I've met whole bunch of java joes out there working in very large
companies, getting badly paid, waiting for their retirement or better
still redundancy. They don't care about OO, or DI, or unit testing (*)
and they love statics and singletons. They don't need to do unit
testing because lots of testing tessies are sitting there ready to
repeat manual system testing over and over again, while *they* wait
for their retirement or redundancy. Its a system that works, very very
slowly, but it works. Eventually.
All the java joes want to see and code is this:
ClassActingAsANamespace.plainOldStaticMethodInGoodOldFashionedProceduralStyle(a,b,c)
Advantages:
Simple and obvious dependencies, without any need to go hunting in no
stinking xml file.
Not an interface in sight. What's an inteface?
No need to use "new SomeObject()" all over the place. Factories? Ewww!
In my experience, this is how alot of "enterprise" java development is
done. Does it matter? I don't think so. Real OO, and DI, etc, etc, is
just more rope to hang yourself with.
Ok, ok so I'm being deliberately provocative and exagerating a
little ;-)
Cheers for the great podcasts.
Just what we need, another religious item to debate over... what will
it be next year, IOC?
/Casper
On Aug 7, 1:08 am, Tim Azzopardi <tim.azzopa...@gmail.com> wrote:
> Steve Yegge said it very well back in 2004. LOL funny.http://steve.yegge.googlepages.com/singleton-considered-stupid
If I have only one instance of something in my running production
code (in today's version of the universe), and client classes to that
singleton have to know that fact, have to know the implementation
class, have to acquire their own references, etc. it makes unit tests
of those client classes much more difficult to set up, and reduces
flexibility in other important ways.
So, even if having a single copy of something is the Right Thing (at
some point in time or in some contexts), I've come to the conclusion
that making the rest of the world know (or worse, depend on) that
fact is often a dubious practice.
-jn-
On Aug 6, 9:35 pm, Casper Bang <c...@brunata.dk> wrote:
> Like so many other things in this world, there are more nuances than
> just black and white...
/Casper
/Casper
On Aug 7, 8:35 pm, Casper Bang <c...@brunata.dk> wrote:
> Right, separating the two is a valuable idea. But if I am dealing with
> something core to my app functionality (say a Proxy), I would usually
> also utilize the provider pattern (java.util.ServiceLoader) such that
> a subtle form of dependency injection is achieved through the
> classpath - which lends itself super well to unit testing in my
> experiences. I still think it can be a fair compromise towards
> simplicity in a design, to assume there will always only be one
> instance. Let's not forget the alternative, the maintainability chaos
> that comes from passing everything around in a parameter list or
> context wrappers.
>
> /Casper
>
> On Aug 7, 7:46 pm, "joel.neely" <joel.ne...@gmail.com> wrote:
>
> > Agreed, but I'd suggest separating the issue of whether there is one
> > instance of something (or an instance pool, etc.) from the issue of
> > whether the clients need to know that fact, especially as the effect
> > on client code increases.
>
> > If I have only one instance of something in my running production
> > code (in today's version of the universe), and client classes to that
> >singletonhave to know that fact, have to know the implementation
But I disagree with ThreadLocal, it seems to be a cludge. ThreadLocal
also implies that the thread doing the work has the correct context in
place. This is something that may not be clear in the contract of the
objects which use it. It also creates issues for name space use,
garbage collection and security.
But again, these are solutions where sometimes there are no clearer
alteratives.
Take, for example, the 'singletons are bad' principle.
singletons aren't bad. But unneccessary tight coupling is very bad,
and singletons almost invariably increase the tight coupling factor.
Saying "tight coupling" is bad is harder to understand, but it is more
insightful. It explains why passing in a huge 'context' container
object is no real improvement (no change in coupling), and also
explains why for example static final variables are no problem
(primitives and java core code is not considered when considering the
dependencies of a chunk of code).
Here's another: public fields are bad. No, thats not the problem.
Unneccessarily restricting future API changes, that's bad. But that
doesn't sound very catchy.
---
For those wondering what 'tight coupling' means: Take a piece of
graphing paper, and pick any java file in your programming project.
Each java file in your project will be a circle on your graphing
paper. Any dependencies between any two java files in your project
will be a line. You can exclude java core. Complete the whole graph.
Exactly how 'interconnected' is your graph? The more of a mess this
graph is, the harder your code will be to debug, to maintain, and to
expand upon or reuse.
Preferably there are lots of little 'islands' in your code - a set of
a few interconnected classes that are connected to the bigger graph
with only 1 simple line someplace. You can safely draw a big box
around this island and call it a 'black box' - in order to understand
your main project you only need to vaguely know what this box does,
you don't need to know the details. Similarly it should be very easy
to 'go into' the black box and understand, test, and modify this box
as if it's a separate app without much need for you to dive into the
main project to fix problems.
- Fully documented
- Written against interfaces
- Tested to a 100% coverage
- Devoured of getters and setters
- Using only immutable classes
- Done with classes talking only to apparent neighbors
- Avoiding inheritance
- Encapsulating instantiation into factories
- Wrapping invocations using the command pattern
- Littered with assertions
- Defensively written with precondition checks
- Not violating DRY
- Localized and internationalized
- Throwing only checked exceptions
- ...blah blah
Personally I have yet to take part of this perfect world and think we
need to improve on our primary expression medium (Java the language),
which we use to manifest our ideas. Whether singletons are considered
evil or not, if it allows me to solve a problem at hand and I do not
expect complications, I will continue to use them in the fashion
described 4 posts ago. When vanilla Java supports IOC I might
reevaluate that stance.
/Casper
If you assume that the singleton pattern is not as theoretically
optimal as a pattern which supplies the same function but has the
option for non-globalness, if required, then you may conclude it's an
anti-pattern. But as Casper sais, there are lots of good design rules
we dodge or omit every day for various reasons (mostly around getting
things done).
I am though all for pushing good design patterns were possible and try
to avoid the anti-anti-pattern argument of "do you want this thing
done propertly or do you want it done at all". I certainly do not
begrudge idealists. We need them to set the "gold standard" even if
we fall short of it. For without them, the standard would be lower
and we would probably be happy to fall well short of that.
As I mentioned earlier, even if you are happy to use your public
static getWorldView() method, be conscious of what you are doing and
be prepaired for a quick refactor if needed (hopefully, if you do it
properly it should be quick).
But, having said that (let me say this). If you were to follow every
gold standard and best practice, a Hello World application would be a
multi-lingual, IOC injected, persistance layer backed, DAO delegated,
factory generated, SOAP and JSF enabled, 200 meg WAR deployment. :) I
think there is a point where the tools and patterns we use to make
something quick or flexible to change might actually make the change
slower or more difficult.
And, yes, I have become more interested in language design (Java or
otherwise) to solve problems, rather than the rules for patterns,
constructs and APIs.