<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="http://www.developerdotstar.com/community" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
 <title>developer.* Blogs - Open Comments Thread for &amp;quot;Factory Chain: A Design Pattern for Factories with Generics&amp;quot; by Hugo Troche - Comments</title>
 <link>http://www.developerdotstar.com/community/node/138</link>
 <description>Comments for &quot;Open Comments Thread for &quot;Factory Chain: A Design Pattern for Factories with Generics&quot; by Hugo Troche&quot;</description>
 <language>en</language>
<item>
 <title>Ooops</title>
 <link>http://www.developerdotstar.com/community/node/138#comment-289</link>
 <description>&lt;p&gt;Well, you probably wouldn&#039;t put the registration code in the constructor.  And the classloader would still have to go to work before the object was needed.  Not quite perfect then...&lt;/p&gt;
</description>
 <pubDate>Wed, 23 Mar 2005 06:01:02 -0800</pubDate>
 <dc:creator>Steve</dc:creator>
 <guid isPermaLink="false">comment 289 at http://www.developerdotstar.com/community</guid>
</item>
<item>
 <title>Registering with the factory</title>
 <link>http://www.developerdotstar.com/community/node/138#comment-288</link>
 <description>&lt;p&gt;Registering with the factory seems like the way to go.  It seems far more reasonable that a class would know the magic string to pull itself out of a hash, rather than know the next class in a sequence.  And you could easily make the string a constant in the factory so it could be changed without too much work.  Try this:&lt;/p&gt;
&lt;div class=&quot;codeblock&quot;&gt;
&lt;pre&gt;private static HashMap&amp;lt;String, Class&amp;lt;? extends Car&amp;gt;&amp;gt; map = new HashMap&amp;lt;String, Class&amp;lt;? extends Car&amp;gt;&amp;gt;();&lt;br /&gt;public static Car getCar(String carType){&lt;br /&gt;   try{&lt;br /&gt;      Class&amp;lt;? extends Car&amp;gt; carClass = getHash().get(carType);&lt;br /&gt;      return carClass.newInstance();      &lt;br /&gt;   } &lt;br /&gt;   catch(Exception e) {e.printStackTrace();}&lt;br /&gt;   return null;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static HashMap&amp;lt;String, Class&amp;lt;? extends Car&amp;gt;&amp;gt; getHash(){&lt;br /&gt;   return map;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static void add(String type, Class&amp;lt;? extends Car&amp;gt; classObj){&lt;br /&gt;   map.put(type, classObj);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private class Ford implements Car{&lt;br /&gt;   public Ford(){&lt;br /&gt;      CarFactory.add(&amp;quot;Ford&amp;quot;, getClass());&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private class Chevy implements Car{&lt;br /&gt;   public Chevy(){&lt;br /&gt;      CarFactory.add(&amp;quot;Chevy&amp;quot;, getClass());&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;
</description>
 <pubDate>Wed, 23 Mar 2005 05:49:46 -0800</pubDate>
 <dc:creator>Steve</dc:creator>
 <guid isPermaLink="false">comment 288 at http://www.developerdotstar.com/community</guid>
</item>
<item>
 <title>Trade off</title>
 <link>http://www.developerdotstar.com/community/node/138#comment-266</link>
 <description>&lt;p&gt;Tim,&lt;br /&gt;
    You are correct about the tradeoff. If you want compile-time safety, you need to load the classes before they are needed.&lt;/p&gt;
&lt;p&gt;Even if we let the elements register themselves with the factory, you still have to hardcode the class object somewhere. There is no way around having somewhere in the code the class for the element hardcoded. We could make the factory more or less dynamic by allowing the elements to register themselves, and that is an option we should look into it.&lt;/p&gt;
&lt;p&gt;Hugo&lt;/p&gt;
</description>
 <pubDate>Tue, 08 Mar 2005 10:07:30 -0800</pubDate>
 <dc:creator>htroche</dc:creator>
 <guid isPermaLink="false">comment 266 at http://www.developerdotstar.com/community</guid>
</item>
<item>
 <title>getHash() is a different problem</title>
 <link>http://www.developerdotstar.com/community/node/138#comment-265</link>
 <description>&lt;p&gt;Hi, Hugo. Thanks for writing. There are several independent issues floating around. Your article presented a factory that could throw an exception, and you wanted to use generics in order to have the compiler generate code that would never throw an exception. I was trying to demonstrate a simpler way to achieve that. I specifically left getHash(), as in your original factory, even though I don&#039;t particularly like it, because I didn&#039;t need to touch it in order to keep the exception from being thrown.&lt;/p&gt;
&lt;p&gt;The chain of factories is simply a hard-coded linked list. In this code, each class is responsible for identifying the class that comes after it. This is a breach of the single-responsibility principle: Each factory element is responsible for another class in the chain. In other words, while it&#039;s true that to add another class you only have to modify the last class in the chain, first you must determine which class that is! If you need a hard-coded list of hundreds of classes, it&#039;s still more maintainable to have this list in one place, rather than scattered among various unrelated classes.&lt;/p&gt;
&lt;p&gt;Now, if you need to sift through hundreds of classes, it&#039;s better to use a hash (O(log N) time per invocation) than a linked list (O(N) time per invocation), because the hash is faster. I daresay, the hard-coded linked list, in the general case, is not as scalable as you seem to think it is.&lt;/p&gt;
&lt;p&gt;Furthermore, whether it is a hash that references a bunch of Class objects or whether it&#039;s a linked-list that references a bunch of Class objects, the VM will still need to load these classes into memory, yes? As soon as we used the &lt;i&gt;class&lt;/i&gt; static member, we told the VM to load in all these classes.&lt;/p&gt;
&lt;p&gt;There seems to be a tradeoff: If you want compile-time safety, you need to load the classes before they&#039;re needed.&lt;/p&gt;
&lt;p&gt;To decouple the factory from the factory elements we could use an observer pattern. Have each factory element register itself with the factory, which would then add that factory element to the hash. If your application allowed it, you could even load factory elements just before they&#039;re needed, reducing start-up and memory requirements.&lt;/p&gt;
&lt;p&gt;Generic factory also comes into play here. I haven&#039;t worked out the code, but my guess is that you&#039;d want to use generics in your factory-element superclass (as you did in your article) in order to decouple the factory code from the code of the created object.&lt;/p&gt;
&lt;p&gt;-TimK&lt;/p&gt;
</description>
 <pubDate>Tue, 08 Mar 2005 09:34:04 -0800</pubDate>
 <dc:creator>TimK</dc:creator>
 <guid isPermaLink="false">comment 265 at http://www.developerdotstar.com/community</guid>
</item>
<item>
 <title>Just forgot to add to my last</title>
 <link>http://www.developerdotstar.com/community/node/138#comment-233</link>
 <description>&lt;p&gt;Just forgot to add to my last comment. Using a factory chain is good scaling design decision, since you don&#039;t have big collections with all the elements floating around. Remember, you can&#039;t have all the elements of a generic factory defined in a file and then just lookup the file (or database table) when you need a particular element. So, if you are going to put all the element in a collection, you have to do so before the elements are needed.&lt;/p&gt;
&lt;p&gt;Hugo&lt;/p&gt;
</description>
 <pubDate>Tue, 01 Mar 2005 15:07:41 -0800</pubDate>
 <dc:creator>htroche</dc:creator>
 <guid isPermaLink="false">comment 233 at http://www.developerdotstar.com/community</guid>
</item>
<item>
 <title>getHash() is the problem</title>
 <link>http://www.developerdotstar.com/community/node/138#comment-232</link>
 <description>&lt;p&gt;The problem is how to implement getHash(). This example is simple enough so there is no problem adding more elements the hash manually. What if your factory could return a type from hundreds of elements? In that case the method getHash() will be hundreds of lines long. This will also mean having to modify the class CarFactory every time you have a new type of car. Which will also mean having to retest a class that will probably have plenty of dependencies.&lt;/p&gt;
&lt;p&gt;By placing the reference to the next class in the factory into each element and creating a chain you only have to modify one small file: the last element in the factory. Also, the chain gives you the possiblity to reuse parts of the factory more easily.&lt;/p&gt;
&lt;p&gt;Hugo&lt;/p&gt;
</description>
 <pubDate>Tue, 01 Mar 2005 14:52:14 -0800</pubDate>
 <dc:creator>htroche</dc:creator>
 <guid isPermaLink="false">comment 232 at http://www.developerdotstar.com/community</guid>
</item>
<item>
 <title>Not the simplest thing that could possibly work</title>
 <link>http://www.developerdotstar.com/community/node/138#comment-231</link>
 <description>&lt;p&gt;The original factory class as implemented may generate a run-time exception. Consider this code from ClassicFactory.getCar(String):&lt;/p&gt;
&lt;div class=&quot;codeblock&quot;&gt;
&lt;pre&gt;// stuff elided ...&lt;br /&gt;        try{&lt;br /&gt;            String carClass = getHash().get(carType).toString();&lt;br /&gt;            Class clazz = Class.forName(carClass);&lt;br /&gt;            return (Car) clazz.newInstance();&lt;br /&gt;        } catch(Exception e) {e.printStackTrace();}&lt;br /&gt;        return null;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Actually, instead of printing a stack trace, getCar should probably throw an InvalidCarClassException or some such.&lt;/p&gt;
&lt;p&gt;Doing the same cast in Java 5 loses you nothing. Moreover, casting the class returned by forName to a Class&amp;lt;? extends Car&amp;gt; also loses you nothing. It&#039;s just a different way to achieve the same result, only using generics. Big deal.&lt;/p&gt;
&lt;p&gt;But generics can help us shore up our code, and without rewriting the entire factory, too. The key is in a subtle change reflected in the Factory-Chain code:&lt;br /&gt;
super.nextClass = Pan.class;&lt;br /&gt;
This code, taken from the Pot class, shows that in the Factory-Chain implementation, &lt;i&gt;we are no longer using forName&lt;/i&gt;. Instead, we&#039;re referring directly to the class object. We can do this in the classic factory implementation, by using a HashMap containing Class objects, instead of containing String objects. Moreover, doing it this way means we would not have to maintain the Factory-Chain linked list manually, which is a maintainence nightmare waiting to happen.&lt;/p&gt;
&lt;p&gt;But using generics, we should be able to go one better. (I haven&#039;t actually tested the following code. Please try it!)&lt;/p&gt;
&lt;div class=&quot;codeblock&quot;&gt;
&lt;pre&gt;public class CarFactory {&lt;br /&gt;    public static Car getCar(String carType) {&lt;br /&gt;        try{&lt;br /&gt;            Class&amp;lt;Car&amp;gt; carClass = getHash().get(carType);&lt;br /&gt;            return carClass.newInstance();&lt;br /&gt;        } catch(Exception e) {e.printStackTrace();}&lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static HashMap&amp;lt;Class&amp;lt;Car&amp;gt;&amp;gt; getHash() {&lt;br /&gt;        HashMap&amp;lt;Class&amp;lt;Car&amp;gt;&amp;gt; map = new HashMap&amp;lt;Class&amp;lt;Car&amp;gt;&amp;gt;();&lt;br /&gt;        map.put(&amp;quot;Ford&amp;quot;, com.generic.factory.Ford.class);&lt;br /&gt;        map.put(&amp;quot;Chevy&amp;quot;, com.generic.factory.Chevy.class);&lt;br /&gt;        return map;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above code could of course be further streamlined.&lt;/p&gt;
&lt;p&gt;In summary, the Factory-Chain pattern isn&#039;t really the best solution in this case. Using a chain of factories could be useful in other cases, for example, if multiple factories must be dynamically loaded and then behave as though they were components of the same factory.&lt;/p&gt;
&lt;p&gt;-TimK&lt;/p&gt;
</description>
 <pubDate>Tue, 01 Mar 2005 11:51:55 -0800</pubDate>
 <dc:creator>TimK</dc:creator>
 <guid isPermaLink="false">comment 231 at http://www.developerdotstar.com/community</guid>
</item>
<item>
 <title>Open Comments Thread for &quot;Factory Chain: A Design Pattern for Factories with Generics&quot; by Hugo Troche</title>
 <link>http://www.developerdotstar.com/community/node/138</link>
 <description>&lt;p&gt;This an open discussion thread for the &lt;i&gt;developer.* Magazine&lt;/i&gt; article &quot;Factory Chain: A Design Pattern for Factories with Generics&quot; by Hugo Troche. If you haven&#039;t already, you &lt;a href=&quot;/mag/articles/troche_factorychain.html&quot;&gt;can read it here&lt;/a&gt;, then add your comments below.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.developerdotstar.com/community/node/138&quot;&gt;read more&lt;/a&gt;&lt;/p&gt;</description>
 <comments>http://www.developerdotstar.com/community/node/138#comment</comments>
 <category domain="http://www.developerdotstar.com/community/taxonomy/term/34">Software Development Articles</category>
 <pubDate>Thu, 24 Feb 2005 19:31:03 -0800</pubDate>
 <dc:creator>Daniel Read</dc:creator>
 <guid isPermaLink="false">138 at http://www.developerdotstar.com/community</guid>
</item>
</channel>
</rss>
