Below you will find pages that utilize the taxonomy term “Architecture”
a few more thoughts on final classes
I said final classes are evil and that post got some attention with interesting comments. Maybe because of the title and the tone I wrote it, a few comments didn't get my real intention and perhaps I should have been more explicit about it. Go ahead and read it. I'll wait. :)
Anyway, I thought I'd expand a little more on that subject, explaining my motivation to write that post and going through the topics I think were raised by my dear readers.
First off, final classes are evil for testing. And that's what it was all about in my previous post.
If you depend on a final class, your code will be harder to test. Unless the final class provides an interface that captures its intent - or you wrap that dependency.
But this affirmation has some implications that were pointed out by a few comments, some of which I agree with - others, not so much. So let's start!
- Immutability
Someone said "Why make a class final ? To make it immutable". This is not entirely true. Only by marking it final you do not ensure immutability. There is no point in doing that if you provide mutators - e.g. setters. - and don't declare your members private and final.
I think it's important to make this clear and understand that the immutability part you achieve by marking a class final is the one of preventing inheritance. Subclasses could possibly contain malicious/careless code and change the internal state of the class.
But there is another way of preventing subclassing without marking the parent final: declare its constructor private and provide a static factory.
- Designing for extensibility
This is hard. It basically means that if you don't mark a class final, you should document it for inheritance.
And this is why inheritance is, in general, a bad OO practice. By documenting the class you basically break encapsulation since you tell the world about your internals.
Therefore, the recommendation is to mark a class final if you're not sure if it's safe to subclass it - or if you just don't wanna bother writing documentation and thinking too much about your "client" subclasses.
- Coding against interfaces
This one is simple but yet often forgotten. Do not code to concrete classes. Always choose interfaces where possible.
It roughly means to do this:
List args = new ArrayList();
instead of this:
ArrayList args = new ArrayList();
By doing so you have the flexibility to not care about the implementation you're working with, as long as it obeys the interface. That way, the implementations can be swapped at any time without breaking any client's code.
- The problem with testing
All items listed here so far are widely regarded as best practices and the bullet I raised about hard testing usually happens when you "violate" some of them.
Specifically, if you decide not to design a class for inheritance and mark it as final, it's wise - in my opinion - to try and capture the class's intent through an interface.
That way you can safely mark your class final and users of your class can easily use the interface to extend it - by favoring composition over inheritance - or by providing it to mocking frameworks for easy testing.
- Conclusion
I don't really think there is a rule of thumb here. Java's standard library shows many examples of both approaches and some of them are now considered bad practices but yet are there for backward compatibility. Nevertheless, these are points to consider when designing your classes.
As pointed out by Josua Bloch in his awesome book Effective Java, "If a concrete class does not implement a standard interface, then you may inconvenience some programmers by prohibiting inheritance".
As usual, comments are more than welcome :)
final classes are evil
Update: Go ahead and read this post in its entirety - including the comments. Then, read my other post where I expand the subject a little more.
--
Every now and then I still do some Java coding. And I actually like it. I spent several years of my career developing primarily in Java and am very keen about the language.
I've been a fierce defender of it these days, specially with the wave of popularity of other languages such as Ruby and Groovy. But I must say that for the 1st time - actually the 2nd - I got pissed off at Java.
The reason? Final classes!
How arrogant of someone to say: "And from now on you shall not subclass my classes!"
Er.... Why?!?! I'm yet to find a good reason in favor of it. But I can share 2 that made me be completely against it. - I never actually liked it but it just didn't bother me that much in the past.
The first one happened while I was adding PostgreSQL XML support to Hibernate. The basic idea is that the XML data type should behave mostly as a string, with the exception of the saving and loading operations.
The thing is, the String data type in Hibernate is declared final. So you cannot share behavior unless you copy and paste it. How smart.
And the second is in the testing area. We all love testing. And we all love mocking external dependencies so we can test our code in isolation and fast. Well, I hope your code doesn't depend on the URL class then.
It is declared final so you just can't mock it. Mocking frameworks like easyMock use subclassing to create your dependencies mock objects and obviously it doesn't work here.
Yeah yeah, of course you can refactor your code so it depends on an interface/class that wraps your URL class and then you can switch implementations. But just how stupid is that? Programming to interfaces makes sense, but not everywhere. Specially not when you're using a low level class like this one.
So please, software developers, architects and the like, design your systems for extensibility and stop being presumptuous.
P.S.: There is a testing framework called jMockit which uses instrumentation (Java 5+) to redefine methods in runtime so you can mock final classes. It works, but should we really be playing that much with the java class loader just so we can "easily" test our code?
spring 25 dependency injection that doesnt hurt
Dependency injection - DIÂ - Â is a great thing. Really. The hability to tweak implementations without touching your code is awesome and the DI frameworks, like spring, saves you a lot of coding. No more service locators stuff.
But, and there is always a but, you're left with a bunch of XML configuration. And I hate it. Not that XML files are bad... the thing is that everything nowadays has its own set of XML configurarion files. And Spring is not different.
scea 5 beta
Hoje fiz a versão beta da nova prova de arquiteto da Sun e eis algumas impressões:
- É longa e cansativa... fato justificável se levar-mos em consideração o fato de ser uma prova em estado beta. Ela possui mais questões que a versão final. São 153 questões no total, em 4h e 30min.
como o spring me ajudou a manter o active record
Nesse primeiro post vou falar um pouco sobre meu novo trabalho. Na verdade, sobre um problema que encontramos lá.
Dentre diversas coisas que estamos fazendo, como migrações por exemplo, estou ajudando na elaboração da arquitetura que irá abrigar as novas aplicações desenvolvidas na empresa.