<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: Final == Good</title>
	<atom:link href="http://cafe.elharo.com/blogroll/final-good/feed/" rel="self" type="application/rss+xml" />
	<link>http://cafe.elharo.com/blogroll/final-good/</link>
	<description>Longer than a blog; shorter than a book</description>
	<pubDate>Tue, 06 Jan 2009 04:06:46 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
		<item>
		<title>By: OOP is a tool at Fiat Developmentum</title>
		<link>http://cafe.elharo.com/blogroll/final-good/#comment-214454</link>
		<dc:creator>OOP is a tool at Fiat Developmentum</dc:creator>
		<pubDate>Tue, 08 Apr 2008 01:13:50 +0000</pubDate>
		<guid isPermaLink="false">http://cafe.elharo.com/java/final-good/#comment-214454</guid>
		<description>[...] one of the &#8216;communities,&#8217; someone had a sarcastic response to the Final == Good article: To boil the article down: OOP is hard. Let&#8217;s make it as non-object-oriented as [...]</description>
		<content:encoded><![CDATA[<p>[...] one of the &#8216;communities,&#8217; someone had a sarcastic response to the Final == Good article: To boil the article down: OOP is hard. Let&#8217;s make it as non-object-oriented as [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: The Cafes &#187; RatJava</title>
		<link>http://cafe.elharo.com/blogroll/final-good/#comment-29830</link>
		<dc:creator>The Cafes &#187; RatJava</dc:creator>
		<pubDate>Mon, 13 Nov 2006 18:22:57 +0000</pubDate>
		<guid isPermaLink="false">http://cafe.elharo.com/java/final-good/#comment-29830</guid>
		<description>[...] Inheritance is a powerful tool, but it takes extra work. Most estimates are that it takes about three times as much work to design a class for inheritance as one that&#8217;s not extensible. It requires a lot more thought and a lot more documentation as to exactly what subclasses can and cannot change. Given that most programmers don&#8217;t ever think about inheritance when designing classes, extensibility shouldn&#8217;t be the default. [...]</description>
		<content:encoded><![CDATA[<p>[...] Inheritance is a powerful tool, but it takes extra work. Most estimates are that it takes about three times as much work to design a class for inheritance as one that&#8217;s not extensible. It requires a lot more thought and a lot more documentation as to exactly what subclasses can and cannot change. Given that most programmers don&#8217;t ever think about inheritance when designing classes, extensibility shouldn&#8217;t be the default. [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: DougHolton</title>
		<link>http://cafe.elharo.com/blogroll/final-good/#comment-2282</link>
		<dc:creator>DougHolton</dc:creator>
		<pubDate>Sun, 04 Jun 2006 22:18:45 +0000</pubDate>
		<guid isPermaLink="false">http://cafe.elharo.com/java/final-good/#comment-2282</guid>
		<description>I agree though with your followup post that Design by Contract is a good middle ground in a way.  Unfortunately it will be years if ever java or C# get that feature.  Instead you can use of course Eiffel, or use a language that lets you implement DBC functionality yourself, such as ruby, python, or boo.</description>
		<content:encoded><![CDATA[<p>I agree though with your followup post that Design by Contract is a good middle ground in a way.  Unfortunately it will be years if ever java or C# get that feature.  Instead you can use of course Eiffel, or use a language that lets you implement DBC functionality yourself, such as ruby, python, or boo.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: DougHolton</title>
		<link>http://cafe.elharo.com/blogroll/final-good/#comment-2280</link>
		<dc:creator>DougHolton</dc:creator>
		<pubDate>Sun, 04 Jun 2006 22:16:28 +0000</pubDate>
		<guid isPermaLink="false">http://cafe.elharo.com/java/final-good/#comment-2280</guid>
		<description>"One final point: final is the safe, conservative choice. Should you mark a class or method final, and later discover a need to subclass/override it, you can remove the finality without breaking anyoneâ€™s code. You cannot go the other way. O"

Except that it's the exact opposite case for the users of your library.  And who is more important?  Time after time I see in C# people having to change methods from the default final to virtual because they didn't consider some use cases or functionality that the users wanted and could have if it were not for a method being final, or more often having to work around it because the author of the library (including Microsoft) takes forever to change it or will not change it.

Virtual should be the default, as it is in Java.  Instead we are stuck in .NET with Microsoft's decisions due to lack of forethought in the design of a library (such as no common "number" interface or type, making generics useless for numerics) or the lack of any hooks for overriding behavior.</description>
		<content:encoded><![CDATA[<p>&#8220;One final point: final is the safe, conservative choice. Should you mark a class or method final, and later discover a need to subclass/override it, you can remove the finality without breaking anyoneâ€™s code. You cannot go the other way. O&#8221;</p>
<p>Except that it&#8217;s the exact opposite case for the users of your library.  And who is more important?  Time after time I see in C# people having to change methods from the default final to virtual because they didn&#8217;t consider some use cases or functionality that the users wanted and could have if it were not for a method being final, or more often having to work around it because the author of the library (including Microsoft) takes forever to change it or will not change it.</p>
<p>Virtual should be the default, as it is in Java.  Instead we are stuck in .NET with Microsoft&#8217;s decisions due to lack of forethought in the design of a library (such as no common &#8220;number&#8221; interface or type, making generics useless for numerics) or the lack of any hooks for overriding behavior.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: James Abley</title>
		<link>http://cafe.elharo.com/blogroll/final-good/#comment-1494</link>
		<dc:creator>James Abley</dc:creator>
		<pubDate>Fri, 02 Jun 2006 10:01:46 +0000</pubDate>
		<guid isPermaLink="false">http://cafe.elharo.com/java/final-good/#comment-1494</guid>
		<description>I wonder if Elliotte has read Michael Feathers book &lt;cite&gt;&lt;a href="http://www.amazon.com/exec/obidos/ISBN=0131177052/ref=nosim/cafeaulaitA/"&gt;Working Effectively with Legacy Code&lt;/a&gt;&lt;/cite&gt;? Having read that, it seems to me that Elliotte and Michael are approaching this from different poles. Elliotte has the perspective of developer who thinks in terms of exported APIs, and doesn't want people mis-using them. Michael is talking about (I think) making changes to code which wasn't developed using TDD or lacks test coverage. The techniques that Michael talks about definitely aren't as effective / easy to apply if classes are final.</description>
		<content:encoded><![CDATA[<p>I wonder if Elliotte has read Michael Feathers book <cite><a href="http://www.amazon.com/exec/obidos/ISBN=0131177052/ref=nosim/cafeaulaitA/" onclick="javascript:pageTracker._trackPageview('/outbound/comment/www.amazon.com');">Working Effectively with Legacy Code</a></cite>? Having read that, it seems to me that Elliotte and Michael are approaching this from different poles. Elliotte has the perspective of developer who thinks in terms of exported APIs, and doesn&#8217;t want people mis-using them. Michael is talking about (I think) making changes to code which wasn&#8217;t developed using TDD or lacks test coverage. The techniques that Michael talks about definitely aren&#8217;t as effective / easy to apply if classes are final.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michael Feathers</title>
		<link>http://cafe.elharo.com/blogroll/final-good/#comment-1240</link>
		<dc:creator>Michael Feathers</dc:creator>
		<pubDate>Wed, 31 May 2006 15:33:27 +0000</pubDate>
		<guid isPermaLink="false">http://cafe.elharo.com/java/final-good/#comment-1240</guid>
		<description>Elliotte said: " The latest shot from the final-haters is a false claim that finality somehow prevents unit testing. To paraphrase Henry S. Thompson, I hate to move a direct negative, but no! There is nothing in finality that prevents unit testing, and I donâ€™t know why people claim it does. Iâ€™ve had zero trouble testing final classes in my own work. I suppose it makes writing mock classes a little trickier, but Iâ€™m not sure thatâ€™s a bad thing. I much prefer to test the real classes and the real interactions that show what really happens rather than what the mock designer thinks will happen. Bugs arenâ€™t always where you expect them to be. And even if finality did somehow interfere with unit testing, breaking the API to support the tests is a clear case of the tail wagging the dog. The tests exist to serve the code, not the other way around."

And the code exists to serve us.  The code can't serve anyone if it's wrong or it's hard to have confidence in your modifications.  I visit team after team that have trouble testing anything in isolation because of final, sealed, and non-virtual functions in other languages (the C++ folks have it particularly bad and there are no tools in sight for them).  Frankly, development in those code bases is a pain in the ass, but you really only notice this after you've worked in a code base developed using TDD and you can run thousands of unit tests in minutes.</description>
		<content:encoded><![CDATA[<p>Elliotte said: &#8221; The latest shot from the final-haters is a false claim that finality somehow prevents unit testing. To paraphrase Henry S. Thompson, I hate to move a direct negative, but no! There is nothing in finality that prevents unit testing, and I donâ€™t know why people claim it does. Iâ€™ve had zero trouble testing final classes in my own work. I suppose it makes writing mock classes a little trickier, but Iâ€™m not sure thatâ€™s a bad thing. I much prefer to test the real classes and the real interactions that show what really happens rather than what the mock designer thinks will happen. Bugs arenâ€™t always where you expect them to be. And even if finality did somehow interfere with unit testing, breaking the API to support the tests is a clear case of the tail wagging the dog. The tests exist to serve the code, not the other way around.&#8221;</p>
<p>And the code exists to serve us.  The code can&#8217;t serve anyone if it&#8217;s wrong or it&#8217;s hard to have confidence in your modifications.  I visit team after team that have trouble testing anything in isolation because of final, sealed, and non-virtual functions in other languages (the C++ folks have it particularly bad and there are no tools in sight for them).  Frankly, development in those code bases is a pain in the ass, but you really only notice this after you&#8217;ve worked in a code base developed using TDD and you can run thousands of unit tests in minutes.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: The Cafes &#187; Eliminating Final</title>
		<link>http://cafe.elharo.com/blogroll/final-good/#comment-1210</link>
		<dc:creator>The Cafes &#187; Eliminating Final</dc:creator>
		<pubDate>Tue, 30 May 2006 12:51:54 +0000</pubDate>
		<guid isPermaLink="false">http://cafe.elharo.com/java/final-good/#comment-1210</guid>
		<description>[...] All the hoohaw over finality, its goodness or badness, and whether or not it should be the default, suggests it&#8217;s worth exploring the background. Why do I feel so strongly that final should be the default (at least for methods) and what changes could be made to modify this belief? [...]</description>
		<content:encoded><![CDATA[<p>[...] All the hoohaw over finality, its goodness or badness, and whether or not it should be the default, suggests it&#8217;s worth exploring the background. Why do I feel so strongly that final should be the default (at least for methods) and what changes could be made to modify this belief? [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: batch4j</title>
		<link>http://cafe.elharo.com/blogroll/final-good/#comment-1208</link>
		<dc:creator>batch4j</dc:creator>
		<pubDate>Tue, 30 May 2006 11:38:17 +0000</pubDate>
		<guid isPermaLink="false">http://cafe.elharo.com/java/final-good/#comment-1208</guid>
		<description>You could change any field private or not using the reflection API, that is, you could make final or private and you could by pass the protection.

See the code

&lt;pre&gt;public static void hook()throws NoSuchFieldException, IllegalAccessException
    {
    ClassLoader myLoader = new Loader(null);                // Creamos un loader sin padre
    ClassLoader cl2 = ClassLoader.getSystemClassLoader();   // Cogemos el classloader del systema
    loader=cl2;                                             // Cogemos el loader actual
    for(ClassLoader aux=cl2.getParent();aux==null;aux=cl2.getParent())      // Mientras sea distinto de null 
        {
            cl2=aux;
            // No hace nada por que lo que se quiere buscar es el punto donde debe engancharse nuestro cargador de clases   
        }
    
    // cl2 contiene la clase padre
    // Se hackea la clase padre obteniendo su atributo parent, se sustituye el parent por otra
    //

    Class clase2 = cl2.getClass();
    
    for(; !("java.lang.ClassLoader".equals(clase2.getName())); clase2=clase2.getSuperclass())       // Mientras sea distinto de null 
        {
            // No hace nada por que lo que se quiere buscar es el punto donde debe engancharse nuestro cargador de clases   
        }
    
    java.lang.reflect.Field parent= clase2.getDeclaredField("parent");
    parent.setAccessible(true);
    parent.set(cl2, myLoader);      
    }
    &lt;/pre&gt;


See the following post.

&lt;a href="http://weblogs.javahispano.org/page/batch4j?entry=proteccion_de_bytescodes_ii"&gt;http://weblogs.javahispano.org/page/batch4j?entry=proteccion_de_bytescodes_ii&lt;/a&gt;</description>
		<content:encoded><![CDATA[<p>You could change any field private or not using the reflection API, that is, you could make final or private and you could by pass the protection.</p>
<p>See the code</p>
<pre>public static void hook()throws NoSuchFieldException, IllegalAccessException
    {
    ClassLoader myLoader = new Loader(null);                // Creamos un loader sin padre
    ClassLoader cl2 = ClassLoader.getSystemClassLoader();   // Cogemos el classloader del systema
    loader=cl2;                                             // Cogemos el loader actual
    for(ClassLoader aux=cl2.getParent();aux==null;aux=cl2.getParent())      // Mientras sea distinto de null
        {
            cl2=aux;
            // No hace nada por que lo que se quiere buscar es el punto donde debe engancharse nuestro cargador de clases
        }

    // cl2 contiene la clase padre
    // Se hackea la clase padre obteniendo su atributo parent, se sustituye el parent por otra
    //

    Class clase2 = cl2.getClass();

    for(; !("java.lang.ClassLoader".equals(clase2.getName())); clase2=clase2.getSuperclass())       // Mientras sea distinto de null
        {
            // No hace nada por que lo que se quiere buscar es el punto donde debe engancharse nuestro cargador de clases
        }

    java.lang.reflect.Field parent= clase2.getDeclaredField("parent");
    parent.setAccessible(true);
    parent.set(cl2, myLoader);
    }
    </pre>
<p>See the following post.</p>
<p><a href="http://weblogs.javahispano.org/page/batch4j?entry=proteccion_de_bytescodes_ii" onclick="javascript:pageTracker._trackPageview('/outbound/comment/weblogs.javahispano.org');">http://weblogs.javahispano.org/page/batch4j?entry=proteccion_de_bytescodes_ii</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Isaac Gouy</title>
		<link>http://cafe.elharo.com/blogroll/final-good/#comment-1137</link>
		<dc:creator>Isaac Gouy</dc:creator>
		<pubDate>Sat, 27 May 2006 17:36:27 +0000</pubDate>
		<guid isPermaLink="false">http://cafe.elharo.com/java/final-good/#comment-1137</guid>
		<description>Whether final classes are good, bad or indifferent - it seems like JMockit provides a way to create mocks for final classes.

https://jmockit.dev.java.net/</description>
		<content:encoded><![CDATA[<p>Whether final classes are good, bad or indifferent - it seems like JMockit provides a way to create mocks for final classes.</p>
<p><a href="https://jmockit.dev.java.net/" onclick="javascript:pageTracker._trackPageview('/outbound/comment/jmockit.dev.java.net');" rel="nofollow">https://jmockit.dev.java.net/</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Brian Slesinsky</title>
		<link>http://cafe.elharo.com/blogroll/final-good/#comment-1136</link>
		<dc:creator>Brian Slesinsky</dc:creator>
		<pubDate>Sat, 27 May 2006 16:27:30 +0000</pubDate>
		<guid isPermaLink="false">http://cafe.elharo.com/java/final-good/#comment-1136</guid>
		<description>There seems to be an assumption here that you can't talk to the library developer, or if you can, they won't listen or respond in a reasonable amount of time.  That's true of many library developers including Sun, but not of everyone.  If the library developer values communication and responds quickly, they don't need to anticipate every possible customer need.  When someone wants a new way of subclassing, they can write the unit test and release a new version that supports subclassing in a way that's officially supported and won't break in the next release.  (Or alternately, explain a better way to do it.)

It seems to me that the real issue is with library developers who aren't responsive to their customers' needs or are too slow in responding to them.  Maybe that's somewhat idealistic, and learning to listen to your customers isn't easy, but I still think it's a better approach.  And with open source you can always patch the source if upstream isn't responding fast enough.</description>
		<content:encoded><![CDATA[<p>There seems to be an assumption here that you can&#8217;t talk to the library developer, or if you can, they won&#8217;t listen or respond in a reasonable amount of time.  That&#8217;s true of many library developers including Sun, but not of everyone.  If the library developer values communication and responds quickly, they don&#8217;t need to anticipate every possible customer need.  When someone wants a new way of subclassing, they can write the unit test and release a new version that supports subclassing in a way that&#8217;s officially supported and won&#8217;t break in the next release.  (Or alternately, explain a better way to do it.)</p>
<p>It seems to me that the real issue is with library developers who aren&#8217;t responsive to their customers&#8217; needs or are too slow in responding to them.  Maybe that&#8217;s somewhat idealistic, and learning to listen to your customers isn&#8217;t easy, but I still think it&#8217;s a better approach.  And with open source you can always patch the source if upstream isn&#8217;t responding fast enough.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
