tag:blogger.com,1999:blog-69622949133984291262009-02-21T02:50:36.381-08:00wickedcoolthoughtsAslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.comBlogger15125tag:blogger.com,1999:blog-6962294913398429126.post-18420538747492427022008-03-26T23:38:00.000-07:002008-03-27T01:35:05.727-07:00.Net Type SafetyWorking with the ternary(conditional) operator in C# I came across an interesting problem. The following piece of code does not compile.<br /><br /><code><br />class Cat{}<br />class Computer{}<br />......<br />Object obj = need_a_cat? new Cat():new Computer();<br />......<br /></code><br /><br />The above code fails with an error that " there is no implicit conversion between <code>Cat</code> and <code>Computer</code>". That is correct ;).However still wondering why is a type checking required in the above case.<br /><br />On the contrary with enums where type checking is expected there is no type checking!<br /><br /><code><br />enum Day_Of_Week { sun, mon, tue ....}<br /><br />String DoSomething(Day_Of_Week day) {<br />.......<br />}<br /><br />....<br /><br />DoSomething(Day_Of_Week.sun+109);<br /><br /></code><br /><br />The above call <code>DoSomething(Day_Of_Week.sun+109);</code> should have failed during compilation. But it doesn't ;)<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6962294913398429126-1842053874749242702?l=wickedcoolthoughts.blogspot.com'/></div>Aslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.com4tag:blogger.com,1999:blog-6962294913398429126.post-9180791291880319452008-02-14T04:05:00.001-08:002008-02-14T04:07:51.522-08:00Refactoring vs Redesign??? or RestructuringIs it refactoring or a redesign?<br />Its a 'big refactoring'.<br />We spent the last two weeks on refactoring.<br />You guys are doing redesign and calling it as refactoring.<br /><br />I am sure that most of us would have come across questions/statements like the above on various occassions. The above statements initially gave me a sense that its the magnitude of the change that differentiates between a refactoring and redesign.<br /><br />Last evening I had a chance to chat with <a href="http://martinfowler.com/">Martin Fowler</a> regarding this and here is Martin's words.<br />"Rather than Refactoring vs Redesign I would like to see it Refactoring vs Restructuring. Refactoring is one of the ways to restructure your code. You can restructure your code by rewriting a class also. Refactoring is my preferred way of restructuring. While each transformation(refactoring) will result in a small change, a sequence of transformations(refactorings) can produce a significant restructuring.".<br /><br />More about refactoring can be found <a href="http://www.refactoring.com/">here</a>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6962294913398429126-918079129188031945?l=wickedcoolthoughts.blogspot.com'/></div>Aslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.com0tag:blogger.com,1999:blog-6962294913398429126.post-25077603099587632452008-01-30T06:13:00.000-08:002008-01-30T06:15:43.095-08:00OR Mappers for .Net, NHibernate vs LLBLGenIn one of our previous projects we had to make a choice between the OR mappers NHibernate(1.x) and LLBLGen(2.5). It was a difficult decision and we ended up discussing various aspects. The decisive factors for the choice were mostly non-technical, like familiarity with the product, the clients willingness to pay/not to pay for a product, support requirements etc. Under such circumstances we may have to make a choice that we may not be quite happy with, as developers.<br /><br />However a little time on the design and practices can help us to overcome some of the limitations. I would like to look at the differences/similarities and explain how some obvious design practices can solve some limitations.<br /><br />1.What is?<br /><br />NHibernate: OR Mapper. Works on plain objects.<br />NHibernate helps you to persist your domain objects.<br /><br />LLBLGen: OR Mapper + Code generator.<br />Works on generated(from a database schema) entity classes.<br />LLBLGen helps you to deal with the data access tier.<br /><br />2. Support: You know it :-). Its between free and paid software.<br /><br />3. Documentation: There is quite a bit of documentation available for both LLBLGen and NHibenate. Also the source code is available for both.<br /><br />4. Supported Databases: Both NHibernate and LLBLGen works for all major databases.<br /><br />5. Mapping of objects to databases: NHibernate uses HBM(xml) files for database mappings while LLBLGen generates code using a visual OR mapping tool. While NHibernate XML mappings are not easily refactored the LLBLGens binary project file which makes it quite difficult to control the versions. This could be a serious limitation with big teams.<br /><br /><br />6. Database First or Domain Objetcs first: Its a matter of taste.<br /><br />One argument is that, with LLBLGen typically the database is created first and the entity classes are generated. After any changes to the database the entity classes need to be generated again. Since the refactoring and IDE supports for the SQL is not as good as programming languages creating the database first may slow you down a bit.<br /><br />Reallistically this problem(if at all) can be solved to some extent by creating a domain layer above the data acess layer and play around with your domain objects first and later think of the persistence.<br /><br />7. Design style: In couple of projects using LLBLGen I have seen the entity classes are being passed between the client and server(across different layers). Using the entity classes as a replacement for your domain objects has some limitations.<br /><br />The LLBLGen entity classes introduces coupling to the data access code and also has limitations to work with some frameworks (if I remember it correctly .. the LLBLGen documentation talks about this somewhere. eg: WCF support).<br /><br />The interface of the generated classes is a little polluted to use them as domain objects.<br /><br />This has nothing to do with LLBLGen, but is all result of using the data access entities as domain objects.<br /><br />8.Productivity: If we use the LLBLGen generated entity classes to replace the domain objects we may save some time and effort. What percentage of the total effort? Does it provide enough value for you? ..need to consider these questions before we make a decision.<br /><br />If we go with a domain layer over the entity classes there is not much productivity gain. Or am I missing something here???<br /><br />Disclaimer: The above is based on some preliminary evaluation of the products.<br /><br />I would like to hear from someone who has used both of these products seriously.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6962294913398429126-2507760309958763245?l=wickedcoolthoughts.blogspot.com'/></div>Aslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.com2tag:blogger.com,1999:blog-6962294913398429126.post-50073142954474198932008-01-17T02:50:00.000-08:002008-01-17T06:00:11.764-08:00Classification of objectsThink no software for this post!<br /><br />1. I have a collection of objects of different classes, some rectangles, some circles, some hexagons and few points. All of the above objects can be drawn and draw is the core/distinguishing behaviour of all the objects above. How can I classify the above objects/classes further? Is it possible to come up with a single common class that can represent all the objects? If so, is that class good enough to convey a concept without ambiquity?<br /><br /><br />2. I have another collection of objects lets say some humans, some robots and some cars. Lets say all the humans party on the weekends ;-), the robots assemble cars and the cars can be driven. Assume that these are core behaviour of the respective classes. Given the requirements above can I classify the objects further? With the above mentioned core/distinguishing behaviours of the objects further meaningful classification is not possible.<br /><br /><br />3. Now let us say there is a radar which needs to track all moving objects.<br /><br />From problem 2 (above) the humans, robots and cars are all objects which can move and we were not interested in the move behaviour until the tracking requirement was introduced. Now we can say humans, robots and cars has ability to move and we are interested in this behaviour.<br /><br />The objects which were otherwise unrelated is now related because of the new behaviour move. And move here is not the distinguishing behaviour of any of the objects/classes.<br /><br /><br />OK, now we can group objects/classes based on their distinguishing behaviours or some other common behaviour. When objects/classes are classified based on their distinguishing behaviour the resulting class is widely accepted and is applicable whereever the objects are used.<br /><br />Eg: Rectangle is a kind of Shape and holds good always.<br /><br />However in the grouping based on a non-distinguishing behaviour the resulting group does not define a class will not be applicable always.<br /><br />Eg: Robot is a kind of Movable (even if we say so) was not applicable till the tracking requirement was introduced.<br /><br />So what is the distinguishing behaviour of the objects? Its up to YOU to decide as needed by the domain.<br /><br />The design of the above in a programming languge is a personal preference and I prefer to maintain the conceptual integrity in the design. Some considerations are covered in the post <a href="http://wickedcoolthoughts.blogspot.com/2008/01/again-abstract-class-vs-interface.html">Abstract Class vs Interface</a>.<br /><br /><a href="http://wickedcoolthoughts.blogspot.com/2008/01/again-abstract-class-vs-interface.html"></a><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6962294913398429126-5007314295447419893?l=wickedcoolthoughts.blogspot.com'/></div>Aslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.com0tag:blogger.com,1999:blog-6962294913398429126.post-6329936721084684012008-01-14T05:51:00.001-08:002008-01-14T07:16:08.301-08:00Abstract class vs interface continued...Hope to clarify some questions/confusions on my previous post on <a href="http://wickedcoolthoughts.blogspot.com/2008/01/again-abstract-class-vs-interface.html">Abstract class Vs Interface</a>. Here I am trying to look at the conceptual difference only.<br /><br /><br /><span style="font-weight: bold; color: rgb(0, 0, 102);">"Of course an interface defines a type": </span>Interesting thought. I would appreciate examples to have a better understanding of the statement.<br /><br />If interface here refers to the java interface (<span style="font-weight: bold; color: rgb(0, 0, 102);">Walkable </span>as in my previous post), the behaviour <span style="font-weight: bold; color: rgb(0, 0, 102);">walk</span> specified by the interface is not sufficient to define a class/type of objects referred by the <span style="font-weight: bold; color: rgb(0, 0, 102);">Walkable </span>interface.<br /><br />If interface is used to refer the messages you can send to an object, I would say the type defines the interface.<br /><br />When modeling a problem say <span style="color: rgb(0, 0, 102); font-weight: bold;">BankAccount</span>,<br /><br />we do not start from <span style="font-weight: bold; color: rgb(0, 0, 102);">deposit(...) , withdraw(...)</span> interfaces to define the type <span style="color: rgb(0, 0, 102); font-weight: bold;">BankAccount</span>. We would rather start from the <span style="font-weight: bold; color: rgb(0, 0, 102);">BankAccount</span>.<br /><br />However when we do classification of objects we do start from the interfaces of the objects to create a class/type.<br /><br /><span style="font-weight: bold; color: rgb(0, 0, 102);">"just wanted to know if we cannot say "walk" as a behavior/type?":</span><br /><br />Perfect to say, <span style="font-weight: bold; color: rgb(0, 0, 102);">walk </span>is a behaviour. However not sufficient to define a class/type of objects referred by the <span style="color: rgb(0, 0, 102); font-weight: bold;">Walkable </span>interface as mentioned above.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6962294913398429126-632993672108468401?l=wickedcoolthoughts.blogspot.com'/></div>Aslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.com5tag:blogger.com,1999:blog-6962294913398429126.post-33408560574781050192008-01-10T07:22:00.000-08:002008-01-10T07:44:15.850-08:00Again Abstract class vs Interface...While pairing with a fellow thoughtworker (<a href="http://thoughtworker.in/">http://thoughtworker.in</a>) we ended up discussing Abstract class vs Interface and he found this explanation useful.<br /><br /><strong>A Class (abstract or not) defines a type while an interface does not.</strong><br /><br />In my domain anything that can be drawn is a shape(including a point) and thus behaviour defines a type.<br /><br /><span style="color:#000066;"><strong>abstract class Shape</strong></span><br /><span style="color:#000066;"><strong>{</strong></span><br /><span style="color:#000066;"><strong> public abstract draw();</strong></span><br /><span style="color:#000066;"><strong>}</strong></span><br /><br />In another domain which includes a Robots, Humans and Pets,<br />If I need to treat all objects that can walk similarly, I would like to have an abstract handle to of all the above and that ends up in a<br /><br /><strong><span style="color:#000066;">interface Walkable{</span></strong><br /><strong><span style="color:#000066;"> </span></strong><br /><strong><span style="color:#000066;">void walk();</span></strong><br /><strong><span style="color:#000066;"></span></strong><br /><strong><span style="color:#000066;">} </span></strong><br /><strong><span style="color:#000066;"></span></strong><br /><strong><span style="color:#000066;">...Robot implements Walkable{...}</span></strong><br /><strong><span style="color:#000066;">...Human implements Walkable{...}</span></strong><br /><strong><span style="color:#000066;">...Pet implements Walkable{...}</span></strong><br /><br />and merely something that can walk does not define a type here. Its a mechanism to tie together otherwise unrelated types Robot, Human and Pet.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6962294913398429126-3340856057478105019?l=wickedcoolthoughts.blogspot.com'/></div>Aslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.com8tag:blogger.com,1999:blog-6962294913398429126.post-54171229322092801672008-01-10T06:27:00.000-08:002008-01-10T06:58:40.337-08:00Test your unit tests + 1 annaThere is no new idea here, however my priliminary search in google did not bring up something similar to what I want to write about.<br /><br />This is just another observation I had with unit tests (applicable to others as well). When the tests were run in the build all of them passed always. However when I ran a single test there were some unexpected failures.<br /><br />A close look into the tests revealed that the tests, the faling test had a dependency on some other test runs. Yes they are bad tests and tests are not supposed to be written that way. But they still exist!<br /><br />Again how can we find them early?<br /><br />Shuffle the test order. Write a RandomTestRunner Decorator?<br /><br />BTW we were discussing the Decorator pattern (hammer) today and everythings seems like a nail ;)<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6962294913398429126-5417122932209280167?l=wickedcoolthoughts.blogspot.com'/></div>Aslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.com0tag:blogger.com,1999:blog-6962294913398429126.post-57399681683749186212008-01-09T04:48:00.001-08:002008-01-10T06:27:20.214-08:00Test your Unit Tests?When I was working on a project in the past I stopped the webserver and database before running the unit tests. To my surprise I found 40+ unit tests started failing. As you would guess the tests did not use the proper test doubles (mocks/stubs..).<br /><br />The next interesting finding was some tests started failing when they were run repeatedly (the same test multiple times in a single build).<br /><br />Both of the above problems are not typical in a fresh development project with people having the right experience with testing/TDD. However these problems could emerge when your team has<br /><br />- less experience in testing or<br />- you are working on a legacy codebase which is not testable.<br /><br />With the legacy codebase, refactoring the codebase is an option to make it testable. However you need tests to refactor with confidence. Its a cyclic dependency problem. So the idea should be to add tests as early as possible. Such tests may be often added at a higher level and may not be proper unit tests. Such tests should be refactored later as the refactoring of the legacy codebase progresses. Due to various reasons some of such tests remain unattended and remain in the codebase. Most of the times the reason why they continue to be in the system is because we do not know that they needs to be addressed.<br /><br />So what can we do about it?<br /><br />1.Automate your build scripts to shutdown all the integrating systems, as a part of your build script, before you run the unit tests. Stop the webserver, database server, disable network connections etc..<br /><br />2.Automate the build script to repeat the tests (the same test multiple times in a single build) occassionally (may be with the nightly build). We can use a decorated TestRunner for this.<br /><br />So we have added two parameters of the unit test quality to our build<br />the 'unitness' and 'repeatability'.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6962294913398429126-5739968168374918621?l=wickedcoolthoughts.blogspot.com'/></div>Aslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.com2tag:blogger.com,1999:blog-6962294913398429126.post-31231593485953642012008-01-04T04:20:00.000-08:002008-01-04T06:07:38.549-08:00Design Patterns : Explosion of strategies"What could too many strategies in your application mean?", was an interesting question while we were discussing the Strategy pattern in ThoughtWorks(Bangalore) patterns study group.<br /><br />The thoughts around this was there is a possibility to combine the strategies to higher level entities and behaviours.<br /><br />Lets look at the example of Bank account and the evolution of the BankAccount object.<br /><br /><pre><code><br /><strong><span style="color:#000066;">class BankAccount {<br /><br /> public Money withdraw(Money amount){<br /><br /> if(account_locked)<br /> throw new AccountLockedException();<br /><br /> else if(transaction_limit_exceeded)<br /> throw new AccountLockedException();<br /><br /> else {<br /> //more logic<br /> balance.subtract(amount);<br /> //more logic<br /> return amount;<br /> }<br /><br /><br /> }<br /><br />}</span></strong><br /></code></pre><br /><br />Looking at the if-else structure the instant answer for this issue was a Strategy pattern. OK Now we have<br /><br /><pre><code><br /><span style="color:#000066;"><strong>abstract class WithdrawalStrategy {<br /><br /> abstract Money withdraw(Money money);<br /><br /> public static final ACCOUNT_LOCKED_WITHDRAWAL = new WithdrawalStrategy(){.......};<br /> public static final LIMIT_EXCEEDED_WITHDRAWAL = new WithdrawalStrategy (){......};<br /> public static final LIMIT_EXCEEDED_WITHDRAWAL = new WithdrawalStrategy (){......};<br /><br />}<br /><br /><br /><br />class BankAccount {<br /><br /> public BankAccount(){<br /><br /> this.withdrawalStrategy = .....;<br /> }<br /><br /> public Money withdraw(Money amount){<br /><br /> return withdrawalStrategy.withdraw(amount);<br /> }<br /><br /><br />}</strong></span><br /></code></pre><br /><br />Soon we we added a deposit operation to the BankAccount object. Again we ended up having strategies. Now we have<br /><br /><pre><code><br /><span style="color:#000066;"><strong>abstract class WithdrawalStrategy {<br /><br /> abstract Money withdraw(Money money);<br /><br /> public static final ACCOUNT_LOCKED_WITHDRAWAL = new WithdrawalStrategy(){.......};<br /> public static final LIMIT_EXCEEDED_WITHDRAWAL = new WithdrawalStrategy (){......};<br /> public static final EVERYTHING_OK_WITHDRAWAL = new WithdrawalStrategy (){......};<br /><br />}<br /><br />abstract class DepositStrategy {<br /><br /> abstract Money deposit(Money money);<br /><br /> public static final ACCOUNT_LOCKED_DEPOSIT = new DepositStrategy(){.......};<br /> public static final LIMIT_EXCEEDED_DEPOSIT = new DepositStrategy (){......};<br /> public static final EVERYTHING_OK_DEPOSIT = new DepositStrategy (){......};<br /><br />}<br /><br /><br /><br />class BankAccount {<br /><br /> public BankAccount(){<br /> ...........<br /> this.withdrawalStrategy = .....;<br /> this.depositStrategy = .....;<br /> }<br /><br /> public Money withdraw(Money amount){<br /><br /> return withdrawalStrategy.withdraw(amount);<br /> }<br /><br /> public Money deposit(Money amount){<br /><br /> return depositStrategy.deposit(amount);<br /> }<br /><br /><br />}</strong></span><br /></code></pre><br /><br />Here both deposit and withdrwal strategies are decided by ACCOUNT_LOCKED,LIMIT_EXCEEDED or EVERYTHING_OK state. So lets try to unify deposit and withdraw.<br /><br /><pre><code><br /><strong><span style="color:#000066;">abstract class WithdrawalStrategy_Plus_DepositStrategy {<br /><br /> abstract Money withdraw(Money money);<br /> abstract Money deposit(Money money);<br /><br /> public static final ACCOUNT_LOCKED = new WithdrawalStrategy_Plus_DepositStrategy(){.......};<br /> public static final LIMIT_EXCEEDED = new WithdrawalStrategy_Plus_DepositStrategy (){......};<br /> public static final EVERYTHING = new WithdrawalStrategy_Plus_DepositStrategy (){......};<br /><br /><br />}</span></strong><br /><br /></code></pre><br /><br />Here WithdrawalStrategy_Plus_DepositStrategy can be renamed as <pre><code><strong><span style="color:#000066;">AccountState</span></strong></code></pre>.<br /><br /><pre><code><br /><br /><strong><span style="color:#000066;">abstract class AccountState {<br /><br /> abstract Money withdraw(Money money);<br /> abstract Money deposit(Money money);<br /><br /> public static final ACCOUNT_LOCKED = new AccountState(){.......};<br /> public static final LIMIT_EXCEEDED = new AccountState (){......};<br /> public static final EVERYTHING_OK = new AccountState (){......};<br /><br /><br />}</span></strong><br /><br /></code></pre><br /><br />The idea here is to explain how the problem of explosion of strategies can be solved by unifying the strategies. ( No I never intend to discuss State vs Strategy here ;))<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6962294913398429126-3123159348595364201?l=wickedcoolthoughts.blogspot.com'/></div>Aslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.com0tag:blogger.com,1999:blog-6962294913398429126.post-69070259499553478822007-12-31T04:40:00.000-08:002007-12-31T04:58:18.295-08:00Object Relations:my friends car can run on my car's tyre....!See how my friends car can run on my car's tyre!<br /><pre><code><span style="color:#000066;"><strong>Car myFerrai = new Car();<br /><br />Car myFriendsFerrari = new Car();<br /><br />Tyre tyre = myFerrari.removeTyre();<br /><br />Tyre flatTyre = myFriendsFerrari.replaceTyre(tyre);<br /><br />myFriendsFerrari.drive();</strong></span><br /><br /></code></pre><br /><br />And with the <strong><span style="color:#000066;">Building</span></strong> and <span style="color:#000066;"><strong>Floor</strong></span>, No you cannot exchange the Floor(s)<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6962294913398429126-6907025949955347882?l=wickedcoolthoughts.blogspot.com'/></div>Aslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.com0tag:blogger.com,1999:blog-6962294913398429126.post-59851569957937243642007-12-18T23:21:00.000-08:002007-12-19T00:06:05.258-08:00The beauty of return this;<span style="font-family:verdana;color:#330099;">As a beginner I was fascinated by the repeated append calls on the StringBuffer (Java) object. Especially because of the saving in the typing and no more string concatenation.</span><br /><pre><code><span style="color:#663300;"><strong>new StringBuffer("start").append("more").append("more")</strong></span></code></pre><code></code><pre><span style="font-family:verdana;color:#330099;">Obviously the return statement of the append method should look like</span><code></code></pre><pre><code><span style="color:#663300;"><strong>return this;</strong></span></code></pre><pre><code></code><br /><span style="font-family:verdana;color:#330099;">Later I came across more interesting examples of this in the mock libraries like below.</span><br /></pre><pre><code><span style="color:#663300;"><strong>Expect.Call(someObj.someMethod()).Return(anotherObject).Repeat().Once();</strong></span></code></pre><pre></pre><br /><span style="font-family:verdana;color:#330099;">This time more than typing benefit what I liked about it is the readability of thecode. This is very close to the natural language translation of the above.<br />"Expect a method call someMethod on someObj. someMethod returns anotherObject. someMethod call is expected only once." Isn't that very close to how the code reads itself?</span><span style="font-family:verdana;color:#330099;"><br /></span><pre><span style="font-family:verdana;color:#330099;">Look at this now.</span></pre><pre><span style="font-family:Verdana;color:#330099;"></span> </pre><pre><span style="font-family:Verdana;color:#330099;">"Create a new bug on build 45576 with description "this is really bugging ....". </span></pre><pre><span style="font-family:Verdana;color:#330099;"></span> </pre><pre><code><span style="color:#663300;"><strong>new Bug("new one").onBuild(45576)</strong></span></code></pre><pre><code><span style="color:#663300;"><strong> .</strong></span></code><code><span style="color:#663300;"><strong>withDescription("this is really bugging")</strong></span></code></pre><pre><code><span style="color:#663300;"><strong> .WithPriority("medium").reportedBy("QA")</strong></span></code></pre><pre><span style="font-family:verdana;color:#330099;">and this</span></pre><pre><code><strong><span style="color:#663300;"> bug = new Bug("new one");</span></strong></code></pre><pre><code><strong><span style="color:#663300;"> bug.setDescription("....");</span></strong></code></pre><pre><code><strong><span style="color:#663300;"> bug.setBuild(45576)......</span></strong></code></pre><pre><code><strong><span style="color:#663300;"></span></strong></code> </pre><pre><code><span style="font-family:verdana;color:#330099;">We can improve the readability by adding 'And', 'With', 'To' etc.</span></code></pre><pre><code><span style="font-family:verdana;color:#330099;">Below I have added a creational method and used 'and' method to </span></code><code><span style="font-family:verdana;color:#330099;">improve the readability a bit more.</span></code></pre><pre><code><span style="color:#330099;"></span></code> </pre><pre><code><strong><span style="color:#663300;"></span></strong></code> </pre><pre><code><strong><span style="color:#663300;">Bug.CreateWithTitle("new one").onBuild(45576)</span></strong></code></pre><pre><code><strong><span style="color:#663300;"> .withDescription("this is really bugging")</span></strong></code></pre><pre><code><strong><span style="color:#663300;"> .WithPriority("medium")</span></strong></code><code><strong><span style="color:#663300;">.reportedBy("QA").and().assignTo("a dev")...</span></strong></code></pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6962294913398429126-5985156995793724364?l=wickedcoolthoughts.blogspot.com'/></div>Aslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.com5tag:blogger.com,1999:blog-6962294913398429126.post-88723608983058149772007-12-14T04:16:00.000-08:002007-12-14T05:18:50.581-08:00Singleton Method Ruby vs Java<strong></strong><br /><strong></strong><br /><strong>I thought this was cool<br /><br /></strong><strong></strong><pre><code><strong>// This was the closest i could get in java.</strong></code></pre><pre><code><strong>// still confused about the terminology 'SingletonMethod'</strong><br /><span style="color:#330099;"><strong>public class SingletonMethodJava {<br /><br /> void theOnlyMethod(){<br /> System.out.println("theOnlyMethod");<br /> }<br /><br /> public static void main(String[] args){<br /><br /> new SingletonMethodJava(){<br /> void addedOneMoreMethod(){<br /> System.out.println("addedOneMoreMethod");<br /> }<br /> }.addedOneMoreMethod();<br /> }<br />}</strong></span></code></pre><br /><br /><strong>But isn't this cooler ?<br /><br /></strong><strong></strong><pre><code><br /><strong><span style="color:#330099;">class SingletonMethodRuby<br /><br /> def theOnlyMethod<br /> puts "theOnlyMethod";<br /> end<br />end<br /><br />singleton_method = SingletonMethodRuby.new<br /><br />def singleton_method.addedOneMoreMethod<br /> puts "addedOneMoreMethod";<br />end<br /><br />singleton_method.addedOneMoreMethod</span><br /></strong></code><strong> </strong></pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6962294913398429126-8872360898305814977?l=wickedcoolthoughts.blogspot.com'/></div>Aslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.com0tag:blogger.com,1999:blog-6962294913398429126.post-30219030012467969052007-12-10T06:57:00.000-08:002007-12-10T07:04:08.541-08:00Redundancy of Language"Couple of boys are riding their bikes!"<br /><br />How many words in the above sentence tell you the presence of more than one person?<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6962294913398429126-3021903001246796905?l=wickedcoolthoughts.blogspot.com'/></div>Aslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.com6tag:blogger.com,1999:blog-6962294913398429126.post-36877165206900672022007-12-07T06:25:00.000-08:002007-12-14T00:43:46.230-08:00Excel POI Wrapper in JRubyDisclaimer:This is one of my very first JRuby/Ruby programs.<br />Dont be surprised if I am writing Java/C# in JRuby.<br /><br /><pre><code><br /><br /><span style="color:#330099;"><strong>require '../../poi-3.0.1-FINAL-20070705.jar'<br />include Java<br /><br />include_class java.io.FileInputStream<br />include_class Java::org.apache.poi.hssf.usermodel.HSSFWorkbook<br />include_class Java::org.apache.poi.hssf.usermodel.HSSFSheet<br />include_class Java::org.apache.poi.hssf.usermodel.HSSFRow<br />include_class Java::org.apache.poi.hssf.usermodel.HSSFCell<br /><br />class ExcelWorkBook<br /> <br /> def initialize(xlsFile)<br /> input = FileInputStream.new(xlsFile)<br /> @hssfworkbook = HSSFWorkbook.new(input)<br /> end<br /> <br /> def worksheet(sheet_position)<br /> ExcelWorkSheet.new(@hssfworkbook.getSheetAt(sheet_position),sheet_position)<br /> end<br /><br /> class ExcelWorkSheet<br /><br /> def initialize(hssfworksheet, sheet_position)<br /> @index = sheet_position<br /> @hssfworksheet = hssfworksheet<br /> end<br /> <br /> def row_at(rownumber)<br /> return Row.new(@hssfworksheet.getRow(rownumber))<br /> end<br /> <br /> def rows<br /> rows = []<br /> for row in @hssfworksheet.rowIterator<br /> rows << Row.new(row)<br /> end<br /> rows<br /> end<br /><br /> class Row<br /> <br /> def initialize(hssfrow)<br /> @hssfrow = hssfrow<br /> end<br /> <br /> def value_at(columnindex)<br /> <br /> cell = @hssfrow.getCell(columnindex)<br /> <br /> if(cell == nil)<br /> ''<br /> elsif(HSSFCell::CELL_TYPE_NUMERIC == cell.getCellType())<br /> cell.getNumericCellValue()<br /> <br /> elsif(HSSFCell::CELL_TYPE_STRING == cell.getCellType()) <br /> cell.getRichStringCellValue()<br /> end<br /> <br /> end<br /> <br /> end<br /><br /> end<br />end<br /><br /><br /></strong></span></code><br /></pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6962294913398429126-3687716520690067202?l=wickedcoolthoughts.blogspot.com'/></div>Aslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.com1tag:blogger.com,1999:blog-6962294913398429126.post-73057549183879303192007-12-05T07:16:00.000-08:002007-12-05T07:53:32.876-08:00Object Relations:CompositionIt took me a while before I could find a convincing real world example of composition. Thanks to civil engineering and Christopher Alexander; I got the enlightenment ;).<br /><br />Yes it’s a <strong>Building</strong> and the <strong>Floor</strong>s. The life time of a <strong>Floor</strong> is totally dependent on the <strong>Building</strong>. The <strong>Floor</strong> is constructed, used and demolished through the <strong>Building</strong>!<br /><br />After finding the right example the next interesting challenge was, how to model the relation? Clearly Building and Floor are the two key objects in the problem and I designed them as separate public classes as follows.<br /><br /><span style="color:#663300;">public class Building {<br />private List<floor> floors;<br />……….<br />}<br /><br />public class Floor {<br />private int level;<br />}<br /></span><br />Functionally this model was fine and I was about to convince myself that the both Composition and Aggregation are same in the design and the difference is conceptual and existed only in the real world. However the lack of conceptual integrity in the model was bugging me for quite sometime before I realized that inner classes is the right way to go.<br /><br />The following code (trivial) demonstrates how the lifetime of the Floor is tied to the building unlike in the previous model. Please excuse my coding conventions.<br /><br /><br /><br /><span style="color:#663333;">public class BuildingTest extends TestCase {<br />private static final int NO_OF_FLOORS = 5;<br /><br />public void testFloorOrder(){<br />Building building = new Building(NO_OF_FLOORS);<br /><br /><strong>Building.Floor</strong> previousFloor = null;<br /><br />for(<strong>Building.Floor</strong> floor : building.Floors()){<br />if(null == previousFloor) {<br />previousFloor = floor;<br />continue;<br />}<br />Assert.assertEquals(true, previousFloor.isAtLowerLevelThan(floor));<br />previousFloor = floor;<br />}<br />}<br />}<br /><br /><br /><strong>public class Building {</strong><br /><br />private List&lt;Floor&gt; floors;<br /><br />public Building(int numFloors) {<br />floors = new ArrayList&lt;Floor&gt;(); </span><br /><span style="color:#663333;"><br />for (int level = 0; level &lt; numFloors; level++)<br /><span style="color:#663333;">floors.add(new Floor(level));</span><br /><span style="color:#663333;"><span style="color:#663333;">} </span><br /><span style="color:#663333;"></span><br /><span style="color:#663333;">public int numberOfFloors() {</span><br /><span style="color:#663333;">return floors.size(); </span><br /><span style="color:#663333;">}</span><br /><span style="color:#663333;"></span><br /><span style="color:#663333;">public List&lt;Floor&gt; Floors() {<br />return floors;<br />}<br /><br /></span><span style="color:#663333;"><strong>public class Floor {<br /></strong>private int level;<br /><br />private Floor(int level) {<br />this.level = level;<br />}<br /><br />public boolean IsAtLowerLevelThan(Floor floor) {<br />return this.level &lt;floor.level;<br />}<br />}<br />}<br /><br /></span><span style="color:#663333;"></span><br /></span></span><span style="color:#663333;"><span style="color:#663333;"></span></span><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6962294913398429126-7305754918387930319?l=wickedcoolthoughts.blogspot.com'/></div>Aslam's Bloghttp://www.blogger.com/profile/07436503144903480817noreply@blogger.com2