<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7647784</id><updated>2011-09-01T06:16:17.005-07:00</updated><title type='text'>Pulihora </title><subtitle type='html'>java OO paraphernalia.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7647784.post-114473200203706283</id><published>2006-04-10T22:02:00.000-07:00</published><updated>2006-04-10T22:06:42.050-07:00</updated><title type='text'>Toplink vs hibernate</title><content type='html'>I still remember the excitement I felt when I started working on Toplink. It was early 2000. Before that, I was working mainly in visual c++. Visual c++ community never had this type of tool; I even thought that such a tool is impossible. During that time, I attended toplink training, and was amazed to know that it can store/retrieve practically any object model into a database, with out any sql. It was not just I, every body in the training session was like that. It was like a dream come true to all of us.  Over the period toplink worked very well for us, major productivity gains were there, you know all the regular ORM benefit stuff…&lt;br /&gt;&lt;br /&gt;Though I am a fan of toplink, after looking at Hibernate, looks like Hibernate is a better framework than toplink, and for very good reasons.&lt;br /&gt;Obviously, Hibernate is free (as in free beer?), has better user base, community, articles, resources, books and momentum.&lt;br /&gt;Hibernate API is lot cleaner than Toplink API. Toplink API, naming conventions are unintuitive in many areas (am I picky on this?).&lt;br /&gt;The most problematic feature in toplink is it is practically impossible to get away from its cache. In toplink, cache is a necessary evil, there is no simple way to bypass cache to go to db. Documentation says few options to set on its descriptor, but none of them work well. In Hibernate cache is optional, if we want we can have it, it always goes to database by default.&lt;br /&gt;&lt;br /&gt;We are not going to switch to hibernate anyway.&lt;br /&gt;&lt;br /&gt;orm tricks ..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-114473200203706283?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/114473200203706283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=114473200203706283' title='70 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/114473200203706283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/114473200203706283'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2006/04/toplink-vs-hibernate.html' title='Toplink vs hibernate'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>70</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-114102221348508261</id><published>2006-02-26T22:32:00.000-08:00</published><updated>2006-02-26T22:36:53.503-08:00</updated><title type='text'>Books are in a Library or Library has books or is it both?</title><content type='html'>Is it silly? but for a developer doing object relational mapping this could be interesting.&lt;br /&gt;Suppose we model this relationship as bidirectional, i.e. Book *&lt;----&gt;1 Library, then, when we load/send a book from database, we load book’s library (since book references library), and all the books in that library (since library refers books).&lt;br /&gt;If we model this relation as a unidirectional--Library has Books (Library 1 --&gt;* Book), then, since book doesn’t refer to library, we don’t have the previous problem of loading and serializing all the books. However, our book does not know which library it came from. If we need to load library, we still end up loading all the books in the library.&lt;br /&gt;Suppose we model this relation as Books are in library, i.e. Book *--&gt;1 Library, then, when we load book we get book’s library, but since library does not have books we don’t end up reading all the books; When we load library we load only library. I choose option Books are in library (Book *--&gt;1 Library), it’s me.&lt;br /&gt;Object relationships and OR Mapping are very interesting, if we don’t model them properly, reading/sending a small object may result in reading a whole load of things that we are not intended to read/send. Technique is, model relationships to the right granularity to match our object reading and writing patterns. In many places, I find turning a container into a marker, as we did above, to be very helpful in getting to right object granularity. Then, what about finding books in a library? If need be, we can always find books in a library by query: get all books whose library is x.&lt;br /&gt;How should we model relation between Book and book pages, Pages are in book or Book has pages or both?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-114102221348508261?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/114102221348508261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=114102221348508261' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/114102221348508261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/114102221348508261'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2006/02/books-are-in-library-or-library-has.html' title='Books are in a Library or Library has books or is it both?'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-114066001047614005</id><published>2006-02-22T17:51:00.000-08:00</published><updated>2006-02-22T18:00:10.483-08:00</updated><title type='text'>Great lens</title><content type='html'>&lt;a href="http://photos1.blogger.com/blogger/1440/223/640/IMG_9411.0.jpg"&gt;&lt;img style="CLEAR: all; FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/1440/223/320/IMG_9411.0.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;If you want a cheap and excellent lens for canon rebel, Canon EF 50mm f/1.8 II is the one to buy.&lt;br /&gt;It is very cheap(&lt;$70.00), fast, and pictures are sharp (see six-packistan).&amp;nbsp;&lt;a href='http://picasa.google.com/blogger/' target='ext'&gt;&lt;img src='http://photos1.blogger.com/pbp.gif' alt='Posted by Picasa' style='border: 0px none ; padding: 0px; background: transparent none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;' align='middle' border='0' /&gt;&lt;/a&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-114066001047614005?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.amazon.com/gp/product/B00007E7JU/ref=pd_sim_p_4/002-4648125-8968027?%5Fencoding=UTF8&amp;v=glance&amp;n=502394' title='Great lens'/><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/114066001047614005/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=114066001047614005' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/114066001047614005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/114066001047614005'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2006/02/great-lens.html' title='Great lens'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-114033243624468801</id><published>2006-02-18T22:50:00.000-08:00</published><updated>2006-03-07T20:25:02.723-08:00</updated><title type='text'>Why Thread implements Runnable?</title><content type='html'>&lt;p&gt;I have this questions for many years, why &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Thread.html"&gt;&lt;i&gt;Thread&lt;/i&gt;&lt;/a&gt; implemets &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runnable.html"&gt;&lt;i&gt;Runnable&lt;/i&gt;?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We implement Runnable, if we want our method (task) to be called from a new thread or a special thread. Then we do some thing like below.&lt;span style="font-size:+0;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color:navy;"&gt;public&lt;/span&gt; &lt;span style="color:navy;"&gt;void&lt;/span&gt; doTaskInRunnable() {&lt;br /&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;  Runnable r = &lt;span style="color:navy;"&gt;new&lt;/span&gt; Runnable() {&lt;br /&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;&lt;span style="color:navy;"&gt;    public&lt;/span&gt; &lt;span style="color:navy;"&gt;void&lt;/span&gt; run() {&lt;br /&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;      task();&lt;br /&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;    }&lt;br /&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;  };&lt;br /&gt;&lt;br /&gt;// to make it tarket of a new thread.&lt;br /&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;Thread thread = &lt;span style="color:navy;"&gt;new&lt;/span&gt; Thread(r);&lt;br /&gt;thread.start();&lt;br /&gt;// or to make our task run from a sp thread.&lt;br /&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;SwingUtilities.invokeLater(r);&lt;br /&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;} &lt;p&gt;If we use Thread instead of Runnable above code becomes&lt;/p&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;&lt;span style="color:navy;"&gt;public&lt;/span&gt; void doTaskInRunnable() {&lt;br /&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;  Thread r = &lt;span style="color:navy;"&gt;new&lt;/span&gt; Thread() {&lt;br /&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;&lt;span style="color:navy;"&gt;    public&lt;/span&gt; &lt;span style="color:navy;"&gt;void&lt;/span&gt; run() {&lt;br /&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;      task();&lt;br /&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;    }&lt;br /&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;  };&lt;br /&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;&lt;b&gt;// Reason 1 : to make it tarket of a new thread.&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;Thread thread = &lt;span style="color:navy;"&gt;new&lt;/span&gt; Thread(r); &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;thread.start();&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;// or Reason 2 : to make our task run from a sp thread. &lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;SwingUtilities.invokeLater(r); &lt;/b&gt;&lt;br /&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;} &lt;p&gt;Making a Thread target of another new Thread is plain stupid, why create a new thread and call it from another at all, in the above code at Reason1 we can as well call r.start().&lt;br /&gt;Making a Thread target of a special thread is confusing, why a thread is running in another thread.&lt;br /&gt;Until java 5&lt;i&gt;,&lt;/i&gt; if we use Thread in place of Runnable, we have a memory leak. In the code above thread r is never started--it's run is called from another thread but never started, until java 5 ThreadGroup used to keep track of all un-started threads and r is never released.&lt;br /&gt;&lt;br /&gt;Using Thread in place of Runnable is ugly, then why Thread implements Runnable? Is it because they have same method named &lt;i&gt;run&lt;/i&gt; with same signature?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-114033243624468801?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/114033243624468801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=114033243624468801' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/114033243624468801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/114033243624468801'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2006/02/why-thread-implements-runnable.html' title='Why Thread implements Runnable?'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-113808508639663893</id><published>2006-01-23T21:47:00.000-08:00</published><updated>2006-02-08T00:12:41.080-08:00</updated><title type='text'>Spring, just another hype?</title><content type='html'>A book challenging a platform and developing an open source project to prove its point is unprecedented. That’s how &lt;a href="www.springframework.org"&gt;Spring &lt;/a&gt;is born, from the ideas of (its manifesto) book "J2EE with out ejb". Spring’s alternative to ejb is an aspect oriented and POJO based inversion of control or &lt;a href="http://www.martinfowler.com/articles/injection.html"&gt;dependency injection&lt;/a&gt; (IOC/DI) container, which integrates with other enterprise ingredients--orm tools, transaction services, custom protocols etc--and also provides client interfaces to Spring. While the ingredients, at least orm tools, are not new, integrating them together to build a toolset is different. IOC, DI, POJOs and &lt;span style="font-style: italic;"&gt;hype &lt;/span&gt;make me take a closer look at Spring.&lt;br /&gt;&lt;br /&gt;Dependency injection, that too for POJOs (i.e. without no explicit interfaces) is good--less burden on lazy developers, we don’t need to worry about building objects or learning new APIs. However, objects can have many possible lifecycles, can Spring &lt;span style="font-style: italic;"&gt;really &lt;/span&gt;inject dependencies in all cases?&lt;br /&gt;Spring documents limitations in some cases:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;on lifecycle mismatch it says "There is however a problem when the bean lifecycles are different. Consider a singleton bean A which needs to use a non-singleton (prototype) bean B, perhaps on each method invocation on A." and suggests to forgo POJO ness get it,&lt;/li&gt;&lt;li&gt; warns on prototype lifecycle by saying "Spring cannot manage the complete lifecycle of a non-singleton/prototype bean".&lt;/li&gt;&lt;li&gt;There are many other limitations too: sharing a prototype (state-full) object across multiple objects, composing object graph of non-singletons with circular references among others, temporal objects (objects with time to live) etc are not possible in Spring. Spring barely supports non-singleton objects, and justifies can’t support or missing features as "they are not common", "not needed", or "heavy weight".&lt;/li&gt;&lt;/ul&gt;Non-singletons, state full objects, objects with circular dependencies are not uncommon.&lt;br /&gt;Containers have a smell in them, their lookup services are very plain, e.g. Spring bean-factory looks up objects based on their id. We are used to factories or registries that have meaning full lookups and classifiers, our lookups have methods like get a pricer for a product type and region, or get a data access object for currencies etc. and a lot more magic is possible in our localized factories/lookup utilities.&lt;br /&gt;Whatever elegance gained in dependency injection is lost by lack of rich object composition and vanilla object classifications of spring. Managing singletons is not a big deal, perhaps, dependency injection is just a good &lt;span style="font-style: italic;"&gt;idea &lt;/span&gt;only.&lt;br /&gt;&lt;br /&gt;So can, Spring, "torchbearer of anti ejb", replace ejb?  Yes and no.&lt;br /&gt;Transactional ejbesque services follow a pattern of business service depending on an orm tool and together participating in transactions. In these scenarios rarely state-full services are needed, at the maximum business façade may be a state-full service, they don’t have lifecycle mismatch problems. Spring integrates well with almost all persistence solutions, and its declarative transactions work inside and outside a container.&lt;br /&gt;Declarative transactions are part of the ejb story only; remoting or distribution support is another important feature in ejb. Spring's remoting/distribution is through custom protocols (non rmi-iiop) --hessian, burlap,httpinvoker, these protocols have serialization and user/transaction context propagation limitations.&lt;br /&gt;Even with problems in dependency injection and incomplete remoting, spring framework accomplishes what very few contemporary frameworks are able to do--declarative transactions inside or outside container and of course lot of hype.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-113808508639663893?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/113808508639663893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=113808508639663893' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/113808508639663893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/113808508639663893'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2006/01/spring-just-another-hype.html' title='Spring, just another hype?'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-111311528425109410</id><published>2005-04-09T23:41:00.000-07:00</published><updated>2005-04-09T23:41:24.250-07:00</updated><title type='text'></title><content type='html'>&lt;a href='http://photos1.blogger.com/img/37/5087/640/pavaniwalking.jpg'&gt;&lt;img border='0' style='border:1px solid #000000; margin:2px' src='http://photos1.blogger.com/img/37/5087/320/pavaniwalking.jpg'&gt;&lt;/a&gt;&lt;br /&gt;untitlable image&amp;nbsp;&lt;a href='http://www.hello.com/' target='ext'&gt;&lt;img src='http://photos1.blogger.com/pbh.gif' alt='Posted by Hello' border='0' style='border:0px;padding:0px;background:transparent;' align='absmiddle'&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-111311528425109410?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/111311528425109410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=111311528425109410' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/111311528425109410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/111311528425109410'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2005/04/untitlable-image.html' title=''/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-111311464760202765</id><published>2005-04-09T23:30:00.000-07:00</published><updated>2005-04-09T23:36:10.913-07:00</updated><title type='text'>Turn turn (Rangula ratnam)</title><content type='html'>&lt;a href="http://photos1.blogger.com/img/37/5087/640/ratnam41.jpg"&gt;&lt;img style="border: 1px solid rgb(0, 0, 0); margin: 2px;" src="http://photos1.blogger.com/img/37/5087/320/ratnam41.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt; &lt;a href="http://www.hello.com/" target="ext"&gt;&lt;img src="http://photos1.blogger.com/pbh.gif" alt="Posted by Hello" style="border: 0px none ; padding: 0px; background: transparent none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;" align="middle" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I was playing with shutter speed at a local mall.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-111311464760202765?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/111311464760202765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=111311464760202765' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/111311464760202765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/111311464760202765'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2005/04/turn-turn-rangula-ratnam.html' title='Turn turn (Rangula ratnam)'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-111311404211833198</id><published>2005-04-09T23:20:00.000-07:00</published><updated>2005-04-09T23:20:42.116-07:00</updated><title type='text'></title><content type='html'>turn turn turn&amp;nbsp;&lt;a href='http://www.hello.com/' target='ext'&gt;&lt;img src='http://photos1.blogger.com/pbh.gif' alt='Posted by Hello' border='0' style='border:0px;padding:0px;background:transparent;' align='absmiddle'&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-111311404211833198?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/111311404211833198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=111311404211833198' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/111311404211833198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/111311404211833198'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2005/04/turn-turn-turn.html' title=''/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-110163130611954734</id><published>2005-01-03T00:00:00.000-08:00</published><updated>2006-02-07T15:21:45.306-08:00</updated><title type='text'>why python?</title><content type='html'>I experimented with Python few times. It looked interesting, but turned off by it’s odd indentation, lack of IDEs and my inability to find right area (application) to use. I felt it is a stronger glue scripting language than perl and weeker programming language than java.&lt;br /&gt;&lt;br /&gt;Recently, I loaded Linux on my home desktop and wondered what is the language of choice for gnome applications: to my surprise I found it to be Python. Many gnome UI applets and games are developed in Python.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;its simplicity, which is &lt;span style="font-style: italic;"&gt;not as barbaric as C/C++&lt;/span&gt; , a seasoned programmer can learn in a week.&lt;/li&gt;&lt;li&gt;great interoperability with native gtk libraries, unlike java.&lt;/li&gt;&lt;li&gt;and great glade UI designer, not there in java world.&lt;/li&gt;&lt;/ul&gt;are making python popular on linux. Perhaps, a good IDE(?) and a database independent db access API like ODBC/JDBC, can turn it into a true enterprise application language.&lt;br /&gt;&lt;br /&gt;Check out &lt;a href="http://www.diveintopython.org/"&gt;diveintopython&lt;/a&gt;, &lt;a href="http://www.pygtk.org/"&gt;PyGTK&lt;/a&gt;, &lt;a href="http://www.artima.com/intv/python.html"&gt;Guido van Rossum's interview&lt;/a&gt;, Bruce Eckel's &lt;a href="http://www.artima.com/intv/prodperf.html"&gt;python zen&lt;/a&gt;, and his case for &lt;a href="http://mindview.net/WebLog/log-0025"&gt;strong testing to offset weak typing&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-110163130611954734?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/110163130611954734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=110163130611954734' title='49 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/110163130611954734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/110163130611954734'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2005/01/why-python.html' title='why python?'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>49</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-110283788178445439</id><published>2004-12-11T23:51:00.000-08:00</published><updated>2006-02-05T23:02:23.313-08:00</updated><title type='text'>What is clean code?</title><content type='html'>Coding standards are language and project dependent. Some C/C++ teams strictly think all local variables in a method should be declared at the begining of the method, some think a method should have only one return statement, Some encourage anonymous inner classes and some out right hate them.&lt;br /&gt;So What is clean code? Is it the code that follows coding, documenation and testing standards. Can we apply bookish knowledge--ofcode smells,best practices, and freak out on switch case statements, series of if-elses, instanceofs, lack of test cases etc. Or on the contrary, a nice looking (unsmelly)program that has javadocs, test cases and follows some bookish buzz words is always clean code?&lt;br /&gt;We programmers (perhaps human tendancy) don't accept other's code as clean. More over in a large team with group politics, it is even worse, one group thinks rival group's code is crap, and vice versa. IMO 90% of the cases, calling code bad, horrible, crap is for personal or political reasons.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-110283788178445439?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/110283788178445439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=110283788178445439' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/110283788178445439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/110283788178445439'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/12/what-is-clean-code.html' title='What is clean code?'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-110141349575410806</id><published>2004-11-25T12:11:00.000-08:00</published><updated>2006-02-06T22:24:32.626-08:00</updated><title type='text'>IntelliJ style tabs</title><content type='html'>Swing JTabbedPane's LEFT and RIGHT tab placements are rarely used. They waste screen space by placing tab titles left to right (see below left image).&lt;br /&gt;&lt;br /&gt;I recently came across &lt;a href="http://www.infonode.net/"&gt;infonode's&lt;/a&gt; toolbar library. It has features to have tabbed titles drawn bottomup or topdown along with many other cool features. Using infonode I created a tabbed panel like the one in IntelliJ Idea (see right image).&lt;br /&gt;&lt;br /&gt;&lt;table cellspacing="1" cellpadding="1" width="300"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img alt="JTabbedPane with left tab placement" src="http://home.comcast.net/~pulihora/images/normal.PNG" border="0" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img alt="intellij style" src="http://home.comcast.net/~pulihora/images/intellijtabs.PNG" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Infonode has some cool features but is costly, they should have offered a reasonable site wide licensing price.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-110141349575410806?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/110141349575410806/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=110141349575410806' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/110141349575410806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/110141349575410806'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/11/intellij-style-tabs.html' title='IntelliJ style tabs'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-110126437499317098</id><published>2004-11-23T18:46:00.000-08:00</published><updated>2004-11-23T18:47:03.580-08:00</updated><title type='text'>BloGTK</title><content type='html'>&lt;p&gt;I am posting from BloGTK. &lt;/p&gt;&lt;br /&gt;After looking at it, I am planning to learn python. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-110126437499317098?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/110126437499317098/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=110126437499317098' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/110126437499317098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/110126437499317098'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/11/blogtk.html' title='BloGTK'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-110033112715787324</id><published>2004-11-12T23:30:00.000-08:00</published><updated>2004-11-12T23:32:07.156-08:00</updated><title type='text'>Upgrading to core 3</title><content type='html'>Spent this evening upgrading to core 3 from core 1. I don't have a cdrw. Initially I tried installing using yum. I was getting a weird error saying udev and kernel are conflicting.&lt;br /&gt;Later found a &lt;a href="http://www.linux.ie/pipermail/ilug/2004-June/015747.html"&gt;cool hack&lt;/a&gt; way to install from hard disk downloaded iso image file.&lt;br /&gt;Fedora core 3 has pre installed firefox 1.0, evolution 2.0, gnome 2.8, kernel 2.6 and is much faster than core 1. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-110033112715787324?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/110033112715787324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=110033112715787324' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/110033112715787324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/110033112715787324'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/11/upgrading-to-core-3.html' title='Upgrading to core 3'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-109892401598083643</id><published>2004-10-27T17:38:00.000-07:00</published><updated>2004-10-27T21:29:40.576-07:00</updated><title type='text'>JBoss AOP - 10 out of 10</title><content type='html'>I looked into &lt;a href="http://www.jboss.org/products/aop"&gt;jboss-aop&lt;/a&gt; today and am delighted. It has &lt;ul&gt;&lt;li&gt;Great documentation and tutorials (not unusual any more in jboss projects).&lt;/li&gt;&lt;li&gt;Great examples (with brief explanation) covering all most all jboss-aop features. All the examples work out of the box. We dont need to do any thing special to run them. &lt;/li&gt;&lt;li&gt;Excellent &lt;a href="http://www.jboss.org/products/jbosside"&gt;eclipse ide plugin&lt;/a&gt;. This one rocks. &lt;/li&gt;&lt;li&gt;Works with jdk1.4 &amp;amp; jdk1.5 .&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Over all I am able to get started in half an hour. JBoss team is living upto their "professional opensource" slogan.&lt;/p&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-109892401598083643?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.jboss.org/products/aop' title='JBoss AOP - 10 out of 10'/><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/109892401598083643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=109892401598083643' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109892401598083643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109892401598083643'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/10/jboss-aop-10-out-of-10.html' title='JBoss AOP - 10 out of 10'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-109747765541511232</id><published>2004-10-23T23:53:00.000-07:00</published><updated>2004-10-24T22:28:52.106-07:00</updated><title type='text'>Cool Runnables</title><content type='html'>A frequent reason to implement Runnable is, a class already extends other class we want it's objects to be active objects.&lt;br /&gt;&lt;br /&gt;Another important reason is runnable can be used as a generic call back.&lt;br /&gt;We can have a method like below doCallback where it calls back run on given runnable. &lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;doCallback(Runnable r){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;r.run();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This idiom is used in SwingUtilities.invokeLater(Runnable r), and SwingUtilitie.invokeAndWait(r). In these runnable is posted to a event queue and AWTEvent thread reads it and calls run from event thread. This makes given runnable called execute in a particular thread.&lt;br /&gt;&lt;br /&gt;Recently I have been using this idiom in our persistence framework, we do normal operations on our business objects and post persistence tasks to a set of database aware threads. These db aware threads call our runnable task and do pre/post processing(transaction, connection management etc). Isn't it cool?&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-109747765541511232?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/109747765541511232/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=109747765541511232' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109747765541511232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109747765541511232'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/10/cool-runnables.html' title='Cool Runnables'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-109756076154197013</id><published>2004-10-11T21:58:00.000-07:00</published><updated>2004-10-12T19:30:03.323-07:00</updated><title type='text'>Why not JOnAS?</title><content type='html'>I am wondering why &lt;a href="http://jonas.objectweb.org/"&gt;JOnAS&lt;/a&gt; is not as popular and as hip as &lt;a href="http://www.jboss.org/"&gt;JBoss&lt;/a&gt;?&lt;br /&gt;&lt;br /&gt;JOnAS is also an open source (LGPL) project. It is J2EE certified for a while. Lot of developer/user documentation is freely available (Unusual for a open source project). According to &lt;a href="http://www.cs.rice.edu/CS/Systems/DynaServer/perf_scalability_ejb.pdf"&gt;study conducted by rice university&lt;/a&gt; JOnAS scales better than JBoss. Redhat officially supports JOnAS as part of &lt;a href="http://www.redhat.com/software/rha/appserver/"&gt;redhat application server&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Is it because JOnAS doesn't have evangelists, entusiasts JBoss has? Is marketing/hype important for a free and open source project also?&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-109756076154197013?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/109756076154197013/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=109756076154197013' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109756076154197013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109756076154197013'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/10/why-not-jonas.html' title='Why not JOnAS?'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-109746775712754571</id><published>2004-10-10T20:28:00.000-07:00</published><updated>2004-11-25T12:32:09.776-08:00</updated><title type='text'>Linux desktop</title><content type='html'>I tried using a Linux desktop four years ago, it was a disaster. My dell PC had a winmodem and Linux didn't recognize it. It made me switch back to windows.&lt;br /&gt;&lt;br /&gt;I tried again six months back. This time Linux recognized cable connection :). Over this period gnome/kde improved a lot. In many ways gnome looks and feels better than ms windows. All my favorite IDEs, tools are available on Linux also. In fact eclipse looks better on Linux. I am able to use samba file server, use &lt;a href="http://www.realvnc.com"&gt;vnc &lt;/a&gt;to control windows PC from Linux and vice versa. I feel p2p clients are perceivably faster on Linux. Open office is nice also. Open office can convert from open office format to PDF. Mail client evolution is great.  Most importantly there is &lt;b&gt;no worry of spyware&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;On the -ve side multimedia tools are still lagging. XMMS doesn't have nice play list editor. Not many video players available and available ones are not that friendly.&lt;br /&gt;&lt;br /&gt;Only big complaint this time is Firefox on Linux is not able to recognize telugu fonts. After some trouble I am able to install &lt;a href="http://www.eenadu.net"&gt;eenadu&lt;/a&gt; font and read it. I am not able to set up rest of the telugu news paper fonts.&lt;br /&gt;&lt;br /&gt;I found tamil, bengali and hindi linux builds. I could not find telugu linux. Is it out there?&lt;br /&gt;&lt;br /&gt;Overall this time I am very happy with Linux desktop.&lt;br /&gt;&lt;br /&gt;I will post some screen shots soon :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-109746775712754571?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/109746775712754571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=109746775712754571' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109746775712754571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109746775712754571'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/10/linux-desktop.html' title='Linux desktop'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-109738131747735183</id><published>2004-10-09T21:08:00.000-07:00</published><updated>2004-10-10T00:40:32.053-07:00</updated><title type='text'>Visitor thoughts</title><content type='html'>Riley white gives an excellent &lt;a href="http://rileywhite.com/software/visitorpattern.html"&gt;visitor&lt;/a&gt; example and explanation. &lt;br /&gt;&lt;br /&gt;My 2 cents are &lt;ul&gt; &lt;li&gt;I prefer foreign method to visitor pattern. Foreign method can traverse Subject's hierarchy with out accept method in subject. In reily white's example I would have some thing like&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class CheckoutImpl extends Checkout{&lt;br /&gt;&amp;nbsp;&amp;nbsp;  void checkout(ShoppintCart cart) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    Collection items = cart.getItems();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    // traverse and add all items.&lt;br /&gt;&amp;nbsp;&amp;nbsp;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Only advantage of &lt;stong&gt;Visitor&lt;/strong&gt; is it's accept method can encapsulate traversing items in a Subject. In Most cases it tends to be very simple traversal.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Use visitor only when there is a need to do special traversal&lt;/strong&gt;.  For example when traversing a closet an employee need to sort only items under $3.00 or need to remove expired items. Then Subject's accept method becomes&lt;br /&gt;&lt;code&gt;&lt;br /&gt;void accept(Visitor v, Condition c){&lt;br /&gt;&amp;nbsp;&amp;nbsp; Collection = getItemsSatisfyingCondition(c);&lt;br /&gt;&amp;nbsp;&amp;nbsp; doNormalAccept...&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt; &lt;br /&gt;&lt;li&gt;Java (my language choice) determines overloaded resolution at compile time, visitor need to have explicit visit methods for each sub type of Subject and an instance of checking method to resolve and call explicitly typed methods. Resolving these conditional type checks is some sort of ugly code. &lt;br /&gt;Changes in Subject hierarchy causes changing all visitor implementations. &lt;br /&gt;&lt;br /&gt;Beware of these problems and &lt;strong&gt; (as advised by GoF) use visitor only when subject hierarchy is stable(rarely/never changes).&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-109738131747735183?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://rileywhite.com/software/visitorpattern.html' title='Visitor thoughts'/><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/109738131747735183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=109738131747735183' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109738131747735183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109738131747735183'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/10/visitor-thoughts.html' title='Visitor thoughts'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-109494807856647198</id><published>2004-09-11T17:10:00.000-07:00</published><updated>2004-09-11T23:23:48.656-07:00</updated><title type='text'>Assigning Responsibilities Duh!</title><content type='html'>In object design a big dilemma is where to assign responsibilities, thumb rule is to keep behavior with data i.e. to define methods in the class that has the data. This rule has is always not correct even when data is in the class. Look at this simple example, An application need to store Order object(s) containing set of Order Items, Customer who ordered it. These objects need to be saved to a database. Order, OrderLineItem and Customer classes and relation ship among them are identified. Dilemma is where should save responsibility(methods) live and why it need to be there. To be specific, Is there a need to have a new class like DataStore, or have save method be part of Order object (it is the object that has data).&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public class Order&lt;br /&gt;{&lt;br /&gt;void save();&lt;br /&gt;}&lt;br /&gt;// or&lt;br /&gt;class DataStore&lt;br /&gt;{&lt;br /&gt;void save(Order anOrder);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;If it is a method in order, then&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Order object needs knowledge of api like JDBC. It is not a real part of Order object. &lt;li&gt;Similarly save method should be in each domain object. &lt;li&gt;If need be, How to handle bulk saves(saving a collections of Orders) in a single transaction?&lt;/li&gt;&lt;/ul&gt;All the above are valid objections even in a medium level complex application. So (If they are) it is better make other datastore abstraction to handle these db related operations.&lt;br /&gt;&lt;br /&gt;In this application Order need to be priced also. Price of an Order is sum of it’s OrderLineItem’s price. Where does price responsibility belong?&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public class Order&lt;br /&gt;{&lt;br /&gt;double price();&lt;br /&gt;}&lt;br /&gt;// or&lt;br /&gt;class Pricer&lt;br /&gt;{&lt;br /&gt;double price(Order anOrder);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Here Order's price does not depend on any external data, keeping price calculation in Order makes more sense. (there may be a method in OrderLineItem also to calculate its individual price). What if price of a order is dependent on current interest rates (external data), and need to price set of orders with same set of interest rates, then clearly in other Pricer class.&lt;br /&gt;&lt;br /&gt;When adding a responsibility to a class, ask why not move it to it's new (or other) class. Questions like&lt;br /&gt;&lt;ul&gt;&lt;li&gt;can the same responsibility/behavior be applied to collection of objects in single operation? (transaction, data set etc). &lt;li&gt;is same/similar responsibility need to be there in classes? &lt;li&gt;is needed data (to fulfill responsibility) noisy?&lt;/li&gt;&lt;li&gt;Is needed data (to fulfill responsibility) external?&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;can help in idenitifying the responsibility's location. If all things equal, add it to class with data - its the norm.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Duh!.&lt;/strong&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-109494807856647198?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/109494807856647198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=109494807856647198' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109494807856647198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109494807856647198'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/09/assigning-responsibilities-duh.html' title='Assigning Responsibilities Duh!'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-109469124410549088</id><published>2004-09-08T17:39:00.000-07:00</published><updated>2004-09-08T18:14:13.790-07:00</updated><title type='text'>Facade Notes</title><content type='html'>&lt;strong&gt;Generally façades are implemented as concrete classes or as singletons or as helper static methods&lt;/strong&gt;. Even design patterns workbook says &lt;em&gt;“A facade provides an interface, but it does not use a Java interface. Rather, a facade is a class with methods that make it easy to use the classes in a subsystem”&lt;/em&gt;. Implementing facades as concrete classes should not be a qualification, in fact &lt;strong&gt;interface based facade implementations are better&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Concrete façade/singleton classes make testing client code difficult, e.g., client using a concrete facade that hides remote calls. We can’t test client code unless remote services needed by façade are running. &lt;li&gt;If implemented as interfaces, we can easily change implementations (even intent change to a bridge).&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;Are helper utility classes facades?&lt;/strong&gt; Helpers and utilities simplify complex API usage by wrapping commonly used code. If helpers can abstract complete client needs to facaded API, then helpers are façades.&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Do we need facades to standard APIs? &lt;/strong&gt;Standard APIs are well documented, well understood and well designed. By standard APIs I mean subsystems like swing, jms etc. Wrapping rich APIs for your needs is difficult. Our facades tend to hide well needed APIs richness. Why do we need facades to well known standard APIs? Except for temporary advantage of hiding some of the (noisy) classes from client they are not really helpful. In the long run our facades to such apis tend to be maintenance headaches. So letting user deal with the standard apis is better. If needed we can have some helper classes to simplify some parts of it.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Does it mean data access objects, Object Relational Mapping tools, aren’t needed, aren’t they facades to standard APIs?&lt;/strong&gt; Data access objects are not treated JDBC facades, they are helper classes to abstract a client modules persistence needs. ORM tools are defining new set of APIs with intent of providing persistence features for objects, their primary intent is not to hide JDBC layers.&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Core J2EE's Session Façade, Fowler's Gateway, Business Service, Remote Façade are they facades?&lt;/strong&gt; They certainly are, their specialized (overloaded) intent is to hide low level (remote/ session handling/ integration) abstractions by providing a high level user/application friendly interface. They hide noise (convert application requests to low level requests, convert low level exceptions to business exceptions etc.)&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;In the end Facade’s intent is to provide a consolidated complete unified cool API to a complex/noisy abstractions. &lt;/em&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-109469124410549088?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/109469124410549088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=109469124410549088' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109469124410549088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109469124410549088'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/09/facade-notes.html' title='Facade Notes'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-109434631427730904</id><published>2004-09-04T18:05:00.000-07:00</published><updated>2006-02-05T23:08:11.610-08:00</updated><title type='text'>cool pictures</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.refactoring.be/thumbnails/ec-strategy.gif"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px;" src="http://www.refactoring.be/thumbnails/ec-strategy.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.refactoring.be/thumbnails.html"&gt;A thumbnail is worth thousand words&lt;/a&gt;. especially evolution charts, are n't they.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-109434631427730904?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.refactoring.be/thumbnails.html' title='cool pictures'/><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/109434631427730904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=109434631427730904' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109434631427730904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109434631427730904'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/09/cool-pictures.html' title='cool pictures'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-109409882911597216</id><published>2004-09-01T19:09:00.000-07:00</published><updated>2004-09-02T19:55:47.406-07:00</updated><title type='text'>Quotable “Design Patterns" Quotes</title><content type='html'>&lt;em&gt;“A solution to a problem in a context.” &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;ChristopherAlexander&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;“Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.”&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;ChristopherAlexander&lt;br /&gt;&lt;br /&gt;&lt;em&gt;“A pattern is a way of doing something, a way of pursuing an intent. ” &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Rebecca Wirfs-Brock&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-109409882911597216?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/109409882911597216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=109409882911597216' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109409882911597216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109409882911597216'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/09/quotable-design-patterns-quotes.html' title='Quotable “Design Patterns&quot; Quotes'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-109383033862535613</id><published>2004-08-30T18:31:00.000-07:00</published><updated>2004-08-30T21:04:03.573-07:00</updated><title type='text'>Parallel Inheritance</title><content type='html'>&lt;a href="http://www.c2.com/cgi/wiki?ParallelInheritanceHierarchies"&gt;There are two(+) associated classes A, B, and every sub type of A is associated with a (different?) sub type of B&lt;/a&gt;. e.g ProductEditor provides UI for a Product. Curtains and Books are different type of Products. CurtainEditor provides UI for Curtain. BookEditor provides UI for Book. And so on. &lt;strong&gt;Is this a CodeSmell?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;If there is duplicate parallel relationship child classes, managing the duplicate relationship can be a problem.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class Product&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Book extends Product&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class ProductEditor&lt;br /&gt;{&lt;br /&gt; &amp;nbsp; private Product product;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public void setProduct(Product prd)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.product = prd;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class BookEditor extends ProductEditor&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;// need to be careful?&lt;br /&gt;&amp;nbsp;&amp;nbsp;private Book book;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public void setProduct(Book book)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.product = prd; // need to call super also&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;BookEditor bookEditor = ...;&lt;br /&gt;Product product = new Book(...);&lt;br /&gt;bookEditor.setProduct(product); // calls base class method.&lt;br /&gt;Book book = new Book(...);&lt;br /&gt;bookEditor.setProduct(product); // calls chile class methods.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Adding duplicate relationship for convenience is bad&lt;/strong&gt;. Apart for code duplication, if not done correctly, there could be dangling/spurious references.&lt;br /&gt;How ever I don't think this is a code smell (due to its -ve meaning).In fact relation ships among parallel inheritance hiearchies is common in many frameworks (&lt;strong&gt;is a good smell?&lt;/strong&gt;). Are not these relations cornerstone for template methods?When such relation ships exist,&lt;ul&gt;&lt;li&gt; Document them and advise against duplicate relations.&lt;li&gt;If needed provide a controlled relation ship managers for setting relations among the participant Objects (do we need a DIP for this?)&lt;/ul&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-109383033862535613?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/109383033862535613/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=109383033862535613' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109383033862535613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109383033862535613'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/08/parallel-inheritance.html' title='Parallel Inheritance'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-109349091129538599</id><published>2004-08-25T20:28:00.000-07:00</published><updated>2004-08-25T21:11:24.763-07:00</updated><title type='text'>What should methods return arrays or Collections? </title><content type='html'>To prolong &lt;a href="http://jroller.com/page/PaulRivers/20040727"&gt;Paul River's Weblog&lt;/a&gt;: By returning arrays we have a temporary advantage of typed objects(untill we java 5). There are many other advantages if a method returns Collections, We can decorate collections as needed.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;We can implement lazy loading returned objects very easily (with arrays also it may be possible by proxies etc in a long way). &lt;/li&gt;&lt;li&gt;We can easily return (private) inner data (unmodifiable), instead of returning new cloned array each time.&lt;/li&gt;&lt;li&gt;We can share data between multiple threads.&lt;/li&gt;&lt;li&gt;Collection is as simple to use as an array type.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In summary returned collection can be changed to any sub type collection (which is very very useful from implementors perspective) with minimal client changes. &lt;/p&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-109349091129538599?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://jroller.com/page/PaulRivers/20040727' title='What should methods return arrays or Collections? '/><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/109349091129538599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=109349091129538599' title='78 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109349091129538599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109349091129538599'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/08/what-should-methods-return-arrays-or.html' title='What should methods return arrays or Collections? '/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>78</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-109305493343846614</id><published>2004-08-20T18:45:00.000-07:00</published><updated>2004-08-25T19:39:40.060-07:00</updated><title type='text'>Method Overloading</title><content type='html'>&lt;p&gt;There is a &lt;strong&gt;chance of surprise/confusion&lt;/strong&gt; in using methods overloaded with subtype arguments (Effective java #26). e.g.&lt;/p&gt;&lt;span style="font-family:lucida grande;font-size:85%;"&gt;void foo(String s);&lt;br /&gt;void foo(Long l);&lt;br /&gt;void foo(Object o);&lt;br /&gt;...&lt;br /&gt;// in client code&lt;br /&gt;Object x = "Some String";&lt;br /&gt;foo(x); // call actually goes to foo(object).&lt;br /&gt;&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Differenent method names instead of overloading is more elegant . &lt;/strong&gt;e.g see below Bladestore interfaces to delete blades first one with overloaded and second one with different methods.&lt;span style="font-family:lucida grande;font-size:85%;"&gt;&lt;br /&gt;boolean delete(Blade blade);&lt;br /&gt;boolean delete(long bladeID);&lt;br /&gt;boolean delete(Blade[] blades);&lt;br /&gt;boolean delete(String bladeName); &lt;/p&gt;&lt;/span&gt;&lt;span style="font-family:lucida grande;font-size:85%;"&gt;&lt;/span&gt;&lt;p&gt;&lt;span style="font-family:lucida grande;font-size:85%;"&gt;boolean delete(Blade blade);&lt;br /&gt;boolean deleteById(long id);&lt;br /&gt;boolean deleteByName(String name);&lt;br /&gt;boolean deleteAll(Blade[] blades);&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;&lt;p&gt;interface with different method names is better, It make intent absolutely clear.&lt;/p&gt;&lt;p&gt;Adding methods like is excess (overaction).&lt;/p&gt;&lt;span style="font-family:lucida grande;font-size:85%;"&gt;&lt;p&gt;boolean deleteByName(char[] name);&lt;br /&gt;boolean deleteById(Long l);&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;&lt;p&gt;to second interface is an unnecessary(smelly) overloading. We are not adding any extra benefit.&lt;/p&gt;&lt;p&gt;Moral of the story : Overload only when method intent is absolutely same, method is useful and there is no possibility of confusion.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-109305493343846614?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/109305493343846614/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=109305493343846614' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109305493343846614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109305493343846614'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/08/method-overloading.html' title='Method Overloading'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-109289040074378867</id><published>2004-08-18T21:28:00.000-07:00</published><updated>2004-08-25T19:52:29.096-07:00</updated><title type='text'>Methods with too many parameters</title><content type='html'>Method with too many parameters (esp in exported api) is a &lt;a href="http://www.c2.com/cgi/wiki?CodeStench"&gt;Codestench&lt;/a&gt; (?). It makes an API usage a pain. IMO 4-5 parameters should be the practical maximum.&lt;br /&gt;&lt;br /&gt;I have seen them evolve in two (anti) patterns. One is a &lt;strong&gt;desire to create a feature rich API. &lt;/strong&gt;And in doing so adding new enhancements very intrusively, e.g by adding a parameter for each parallel feature in existing methods. In turn producing a polluted feature creepy (&lt;a href="http://c2.com/cgi/wiki?YouArentGonnaNeedIt"&gt;YAGNI&lt;/a&gt;) API, making it very difficult for normal situations.&lt;br /&gt;&lt;br /&gt;e.g.&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// Normal API to find a blade in database by a its id a long type.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Blade blade = bladeFinder.getBladeById(id); &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Developer modified above finder to search by multiple id types (by name, key, by group etc addin one param) , from multiple data sources(adding three params), and multiple service types (ejb/jms/corba servers) in total adding five more parameters.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// Ugly&lt;br /&gt;List blades = (List) bladeFinder.getBlades(idType, id, userid, password, datasourceName, servertype);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;In next version developer added a new feature to get data in different formats XML, formatted HTML, Blade object etc (adding one more param for dataformat). As part of this new version a new parameter object is created with all the parameters from old previous finder method + one more to support dataformats. A Response object is also added to wrap return data, exceptions, some more methods. Usage pattren changes to&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;strong&gt;// The ugly&lt;/strong&gt;&lt;br /&gt;BladeRequest request = bladeRequestFactory.createReadBladeRequest(idType, id, dataFormat, userid, password, datasourceName, usingJMS, ...);&lt;br /&gt;&lt;br /&gt;BladeResponse response = bladeRequestProcessor.processRequest(request);&lt;br /&gt;&lt;br /&gt;If (response.getAttribute(somecode).equals(successcode))&lt;br /&gt;Blade blade = (Blade) response.getObjectType(OBJ_FORMAT); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;else&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;String failMessage = (String) response.getFailureObject();&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Other pattern is a&lt;strong&gt; need/plan to develop very loosely coupled modules&lt;/strong&gt;. These modules agree only on a minimal set of interfaces and see world very differently.&lt;br /&gt;e.g. proverbial OR mismatch. One layer looks a BladeObject and other looks it as a Map.&lt;br /&gt;&lt;br /&gt;Possible refactorings ?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Make one or more parameter objects with all the parameters. We are moving problem from one place to other place. &lt;/li&gt;&lt;li&gt;Setters instead of constructor for Parameter object, with possible defaults for some. (confusing some times, difficult to document etc)&lt;/li&gt;&lt;li&gt;A &lt;a href="http://c2.com/cgi/wiki?MagicContainer"&gt;magic container&lt;/a&gt; like properties(map), that server assumes a default for missing properties. (confusing some times, difficult to document etc)&lt;/li&gt;&lt;li&gt;Write &lt;a href="http://www.c2.com/cgi/wiki?FacadePattern"&gt;Facade&lt;/a&gt;s to hide ugly code(If we can't change any interfaces or if it is a result of a loose coupling design).&lt;/li&gt;&lt;li&gt;Remove unused features/parameters, computable parameters if any. &lt;/li&gt;&lt;li&gt;If a parameter is an enumeration provide different methods for each type.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The above example can be refactored by removing unneeded features data source (user and password too) parameter. And adding new Criteria a parameter objects and new methods for each data format.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// Refactoring to below&lt;br /&gt;Criteria criteria = ...; // to make a search expression&lt;br /&gt;List /*&lt;blade&gt;*/blades = bladeFinder.findBlades(criteria);&lt;br /&gt;//or xml as String&lt;br /&gt;List /*&lt;string&gt;*/ blades = bladeFinder.findXmlBlades(criteria); &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-109289040074378867?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/109289040074378867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=109289040074378867' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109289040074378867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109289040074378867'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/08/methods-with-too-many-parameters.html' title='Methods with too many parameters'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-109185898239804693</id><published>2004-08-06T22:59:00.000-07:00</published><updated>2005-01-05T18:22:27.453-08:00</updated><title type='text'>is synchronization not enough?</title><content type='html'>java5 has a class called &lt;strong&gt;Lock&lt;/strong&gt;, with methods lock() and unlock(). They can be used to lock in one block and unlock in another block (even in different methods, but needs to be explicitly unlocked unlike &lt;em&gt;synchronized&lt;/em&gt;).  Lock is termed as an enhancement to synchronization&lt;br /&gt;&lt;br /&gt;Now we can write code like&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Lock a = ...; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Lock b = ...; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{ &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   a.lock(); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;...;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;b.lock(); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;...; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;a.unlock(); // reversing the order. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{ &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   b.unlock(); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Where to use these,  I am waiting for a execuse :)&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-109185898239804693?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/109185898239804693/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=109185898239804693' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109185898239804693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109185898239804693'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/08/is-synchronization-not-enough.html' title='is synchronization not enough?'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-109176761643815126</id><published>2004-08-05T21:15:00.000-07:00</published><updated>2004-09-04T20:53:31.990-07:00</updated><title type='text'>Six Simple Rules</title><content type='html'>&lt;ol&gt;&lt;li&gt;&lt;em&gt;Clarity and simplicity are of paramount importance.&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Modules should be as small as possible but no smaller.&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Code should be reused rather than copied.&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;The dependencies between modules should be kept to a minimum.&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Errors should be detected as soon as possible after they are made, ideally at compile time.&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;You should not slavishly follow these rules, but you should violate them only occasionally and with good reason. &lt;/em&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p align="right"&gt;Jashua Bloch in Effective java.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-109176761643815126?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/109176761643815126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=109176761643815126' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109176761643815126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/109176761643815126'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/08/six-simple-rules.html' title='Six Simple Rules'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7647784.post-108995212567844194</id><published>2004-07-15T20:36:00.000-07:00</published><updated>2004-07-31T22:47:51.880-07:00</updated><title type='text'>Java UI - 'some thing is better than nothing'</title><content type='html'>&lt;span style="font-size:85%;"&gt;Java normal GUI application performance is bad enough. Who needs looking glass and Java3d. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;JDNC big deal. Every other language/tool has form building, data/db binding framework for the last 10+ years. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;JDIC file explorer, is another example pathetic integration.&lt;/span&gt;&lt;br /&gt;&lt;p&gt; &lt;/p&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7647784-108995212567844194?l=pulihora.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pulihora.blogspot.com/feeds/108995212567844194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7647784&amp;postID=108995212567844194' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/108995212567844194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7647784/posts/default/108995212567844194'/><link rel='alternate' type='text/html' href='http://pulihora.blogspot.com/2004/07/java-ui-some-thing-is-better-than.html' title='Java UI - &apos;some thing is better than nothing&apos;'/><author><name>pulihora</name><uri>http://www.blogger.com/profile/09141278584031304867</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
