• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Liutauras Vilda
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Saloon Keepers:
  • Scott Selikoff
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
  • Frits Walraven
Bartenders:
  • Stephan van Hulst
  • Carey Brown

If singletons are bad, how does a factory help?

 
Rancher
Posts: 4804
7
Mac OS X VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Many testing folks discourage use of the GoF singleton pattern. For the usual reasons (implicit coupling, hard to test, etc.).

The usual suggestion is to use a factory.

The factory can then return an object, which may or may not be a singleton. So far, so good. And the factory could have a pool of resources, or a single copy, as an implementation detail.

But if the Factory wants to keep either one and only one instance of an object, or pull from a pool, it needs to know that its storage is a static singleton. You would not want there to be two Factory instances, pulling from two pools.

Seems to me we have just moved from having a Singleton object to having a SingletonFactory. This may or not be better. Its not clear to me.

Is this really better?

And when you may have multiple class loaders, and really, really want just one SingletonFactory, how do you do it?

Thanks
 
Ranch Hand
Posts: 376
Scala Monad
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Singleton and Factory Method are different patterns to solve different problems.
Although the "getInstance" method of the singleton can be considered a factory method, they deal with different concerns, and one cannot be replaced by the other.
The problem the pattern solves is:
"How do we ensure that a class has only one instance and that the instance is easily accessible? A global variable makes an object accessible, but it doesn't keep you from instantiating multiple objects."
I think singleton fills its purpose, just need to be used careful... I think the overuse led to the backlash against him
 
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Pat Farrell:
Many testing folks discourage use of the GoF singleton pattern. For the usual reasons (implicit coupling, hard to test, etc.).



And not only testing folks.


The usual suggestion is to use a factory.



Is it? Where do you get that from?

I like this article: http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne
 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The Java implementation of Singleton that you find all over the web tightly couples calling code to a particular class. Testers might object to this because they can't substitute a testing class. The rest of us are uncomfortable because it's harder to substitute another class when the system requirements change, and because "globals" can easily be misused to turn the system into a Big Ball of Mud.

Some even say that using the new() operator to create objects is overly tight coupling because you code a class name. Factory-like creationional helpers (not necessarily exactly the GoF patterns) can help. When you code something like

something = someHelper.getInstance( "ThingThatSovesProblemX" )

you are decoupled from the exact class that will do the job. How often should you do something like this? "Always" is surely not the answer for most of us. It can be hard to spot the places you need this flexibility ahead of time, but some of that is part of experience and skill.
 
Pat Farrell
Rancher
Posts: 4804
7
Mac OS X VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Gabriel Claramunt:
Singleton and Factory Method are different patterns to solve different problems.



Sometimes.

Using a Factory to get an instance makes testing easier.
And the Factory can implement its own "just make one" algorithm.

So far, so good. But it really doesn't change much, because the Factory has to be a singleton, or singleton like, since it has to remember when it has created the one and only Foo object.

Originally posted by Gabriel Claramunt:


The problem the pattern solves is:
"How do we ensure that a class has only one instance and that the instance is easily accessible? A global variable makes an object accessible, but it doesn't keep you from instantiating multiple objects."



I'm not sure it solves it.
It works if there is only one ClassLoader. So you can move the question back a level, and ask how to you get a singleton ClassLoader.

In a container-ful world, the simple answer is you can't be sure you have one class loader, so you can't have a singleton.
 
Gabriel Claramunt
Ranch Hand
Posts: 376
Scala Monad
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you hide the constructor and provide a method to get the only instance, you're applying the Singleton pattern (is the typical implementation!)
The GoF patterns doesn't deal with distributed systems, if you use singleton without care in that kind of environment, you can end with multiple instances (although if I recall correctly, some containers allows you to define singleton components, even in clustered environments).
If you don't have that service, just deploy the singleton in only one class loader... that should work
 
Sheriff
Posts: 7001
6
Eclipse IDE Python C++ Debian Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So far, so good. But it really doesn't change much, because the Factory has to be a singleton, or singleton like, since it has to remember when it has created the one and only Foo object.

I don't think this is true.

All that is required is that code which needs to use the same factory, uses the same factory. The factory can be supplied using any form of "dependency injection" (such as passing in as a constructor parameter, or into a "setter"), or fetched from some sort of context supplied by similar methods.

Such a factory would only need to be "singleton like" if the only allowable way for client code to find it is through a public static ("global") method or variable.

Is there anything actually preventing you from just "passing in" either objects pre-fetched from a factory, a factory, or a context from which the factory may be fetched?
 
Pat Farrell
Rancher
Posts: 4804
7
Mac OS X VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Frank Carver:

The factory can be supplied using any form of "dependency injection" (such as passing in as a constructor parameter, or into a "setter"), or fetched from some sort of context supplied by similar methods.



I've made the leap that having a global parameter hiding in a Context or XML is just syntactic sugar over having a Singleton in the Java code. For my tastes, putting magic values in XML in some config file somewhere is worse than just putting the magic values in Java. If for no other reason than developers have to learn both Java and XML to figure out what is going on.

Originally posted by Frank Carver:

Is there anything actually preventing you from just "passing in" either objects pre-fetched from a factory, a factory, or a context from which the factory may be fetched?



I'm not sold on the so called "dependency injection" as being any better.
If you have one class dependent on the Foo (singleton, made in factory, etc.) then it is fine. But when you have twenty or more classes deep, it adds a lot of ugly parameter passing. You tend to have parameters that are passed in only so they can be feed down to other classes, so their value
in the class at hand is lost.

It seems to me that dependency injection as a cure is as bad as the disease.
Just IMHO, of course, but so far, the solutions aren't impressive.
 
Frank Carver
Sheriff
Posts: 7001
6
Eclipse IDE Python C++ Debian Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I've made the leap that having a global parameter hiding in a Context or XML is just syntactic sugar over having a Singleton in the Java code.

Possibly. I think we may be discussing different meanings of "context", though. In my mind, a "context" is just an object from which other stuff may be fetched. It might be a Map, or a domain object with specific "getters", or a factory of some sort, or whatever. The point is that it is a single object which can provide an environment and is simple to pass around during the execution of some scenario.

{QB]For my tastes, putting magic values in XML in some config file somewhere is worse than just putting the magic values in Java. If for no other reason than developers have to learn both Java and XML to figure out what is going on.[/QB]

Absolutely.

In my experience, though, every Java application has some starting point, be it a "main" method, a servlet, or whatever. This starting point is by definition special, so I usually set up any initial values, factories etc. in this class. That way there is little or no object creation in classes and methods used in the processing of the application, and this in turn allows such classes and methods to be tested independently, with any test-specific setup that is required.

I'm not sold on the so called "dependency injection" as being any better. If you have one class dependent on the Foo (singleton, made in factory, etc.) then it is fine. But when you have twenty or more classes deep, it adds a lot of ugly parameter passing. You tend to have parameters that are passed in only so they can be feed down to other classes, so their value in the class at hand is lost.

That's an interesting viewpoint. I have seen this sort of problem in some applications where setter-based dependency injection has resulted in most classes in the system consisting mostly of methods to support the supply of such collaborators. This seems a common approach for teams which have bought into Spring, and proceeded to use it for everything.

Typically applications which I have designed use a mixture of constructor injection of general configurations, and dependency "pull" from a supplied context of transient state.

It seems to me that dependency injection as a cure is as bad as the disease. Just IMHO, of course, but so far, the solutions aren't impressive.

I guess it depends how bad you see the "disease".

I develop all my code using Test-Driven Development, and view the ability to write unit tests for all behaviour of all code as a vital part of my software. Writing unit tests for software which opaquely manages its own configuration and collaborators can be both difficult and slow, so I find that my style of decoupling makes for faster development of much more robust and correct software.

YMMV, of course.
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In my experience, designing software mostly is a skill of balancing different forces. So certainly dependency injection can be overdone, although personally I have a much stronger dislike for global dependencies.

Also note that using dependency injection doesn't necessarily imply the use of a dependency injection framework. But it certainly means more passing around, and less pulling from known access points in the code. Again, to me that is mostly a good thing.
 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think when it comes to the typical Java implementation, the problem for testing is the way a Singleton is typically accessed: through a static lazy-init access method. It's essentially a public static field except that, in most cases, tests can't even substitute a mock implementation. Using a Factory pattern could discourage calling the method so much, which would possibly lead to injection scenarios which are easier to test.

However, there is a workaround for testing. First, make the field package visible or add a package visible setter. Then, add a class to the package in the harness, i.e. the TEST SOURCE directory, with a public method to set the singleton. This gives tests a foothold for controlling the Singleton without having a public setter in production code.
 
Pat Farrell
Rancher
Posts: 4804
7
Mac OS X VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Ilja Preuss:
In my experience, designing software mostly is a skill of balancing different forces. So certainly dependency injection can be overdone, although personally I have a much stronger dislike for global dependencies.



All of engineering is about balance, trade-offs and optimization.
Sometimes I think all software engineering programs should start off the students with the Civil, Mechanical, and Electrical engineering folks for the first years. They've been making tradeoffs for centuries. Its not a new thing.

What we don't have in software are any hard metrics, so much more judgement is involved than in traditional engineering. But I'm biased, my unfinished PhD dissertation was on software metrics.

Originally posted by Ilja Preuss:

Also note that using dependency injection doesn't necessarily imply the use of a dependency injection framework. But it certainly means more passing around, and less pulling from known access points in the code. Again, to me that is mostly a good thing.



I agree that tons of magic public access points is bad.

I've not seen many frameworks that seem clear winners. Probably because they all get popular in a flash, and then people realize that Brooks was right, there is "no silver bullet" and then they try to invent another framework to solve all known problems.
 
Pat Farrell
Rancher
Posts: 4804
7
Mac OS X VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Frank Carver:
[qb]I've made the leap that having a global parameter hiding in a Context or XML is just syntactic sugar over having a Singleton in the Java code.

Possibly. I think we may be discussing different meanings of "context", though. In my mind, a "context" is just an object from which other stuff may be fetched. It might be a Map, or a domain object with specific "getters", or a factory of some sort, or whatever. The point is that it is a single object which can provide an environment and is simple to pass around during the execution of some scenario.
[/QB]



Well, it is dangerous to use a jargon word like "context" in a field like Java and software engineering, where it has so many common uses, typically in some J2EE container/server.

{QB]
In my experience, though, every Java application has some starting point, be it a "main" method, a servlet, or whatever. This starting point is by definition special, so I usually set up any initial values, factories etc. in this class. That way there is little or no object creation in classes and methods used in the processing of the application, and this in turn allows such classes and methods to be tested independently, with any test-specific setup that is required.
[/QB]



But that aside, I don't see a universal 'single object' that can work without binding it to the outer environment. Be it defined by a J2EE container or shell environment variables, you are still causing external coupling.

Before the days of JUnit, all of my classes had a 'main()' function for testing. While that is no longer my standard model, I really would like to "write once, deploy everywhere"(tm) without having to worry about what external wrapper is in use.


{QB]

That's an interesting viewpoint. I have seen this sort of problem in some applications where setter-based dependency injection has resulted in most classes in the system consisting mostly of methods to support the supply of such collaborators. This seems a common approach for teams which have bought into Spring, and proceeded to use it for everything.
[/QB]



Right, you have identified one of my favorite rant topics.
If you look at the JDK's source code, most of the functions are small, have very few parameters and have no side effects.

Like good smalltalk code.

{QB]
I guess it depends how bad you see the "disease".
[/QB]



I'm sold on testing driven coding, but so far, I'm not seeing a clear winner over the GoF singleton pattern, which has many warts.
 
Stan James
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Re Dependency Injection ... I picked up the idea of an application "assembler" module from Martin Fowler's Dependency Injection paper. In a couple applications I built a class that reads configuration and pushes options and collaborators to numerous other classes. This one class has a nasty bunch of dependencies and can be a busy site of change, but it's only one class that I'm willing to live with. I just leave it out of my dependency metrics reports. Other classes have simple setters, easy to manipulate for testing. BTW: there could be several assemblers, say one per component, but one works so far. And I prefer nearly anything over XML for the configuration part ... properties, databases, etc.

I've thought about a DI framework instead of my hand-made assembler, but haven't found any compelling problem to be solved yet.

I've been changing my Wiki over time to load configuration from Wiki pages. A page change listener updates the component any time the page is saved, and the startup assembler triggers the same code. I'm pretty happy about the way it's working out, especially the automatic update, and the properties files are fading away.

DI via setters does add public methods that are not part of the API that I want others to use, which is a bit ugly. One could separate them from the public API but I haven't felt the need yet.
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Scott Vachalek:

However, there is a workaround for testing. First, make the field package visible or add a package visible setter. Then, add a class to the package in the harness, i.e. the TEST SOURCE directory, with a public method to set the singleton. This gives tests a foothold for controlling the Singleton without having a public setter in production code.



Done that in the past, doesn't work that great for me. The problem is that using this solution, tests suddenly can have side effects on other tests - unless you remember to always reset the Singleton, or even use a fresh JVM (or at least classloader) for each tests. It's simply not worth the hassle, especially when considering the other nasty side effects of having a global access point.
 
Gabriel Claramunt
Ranch Hand
Posts: 376
Scala Monad
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm intrigued now: what should be the recommended solution if one needs to control the number of instances of an object?
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Gabriel Claramunt:
I'm intrigued now: what should be the recommended solution if one needs to control the number of instances of an object?



Depends on what you mean by "control". Basicly my advice would be: if there shouldn't be more than one instance, don't create more than one instance. See http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne
 
Gabriel Claramunt
Ranch Hand
Posts: 376
Scala Monad
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I read Martin's proposal, and I don't see much improvement. Either is a public attribute of the main class and you have the same global access problems that you had with singleton, or you pass the "singleton" object all along the collaboration chain because one class at the end needs it. Worse, all your collaboration classes will depend on the "singleton" even without using it.
As most singletons are from cross-cutting concerns, maybe using AOP could be a solution to avoid using them...
 
Bartender
Posts: 2968
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Gabriel Claramunt:
Worse, all your collaboration classes will depend on the "singleton" even without using it.
As most singletons are from cross-cutting concerns, maybe using AOP could be a solution to avoid using them...



Actually they should depend on the interface(s) that your "JustCreateOne" object implements. Dependency injection only makes sense if the dependent objects implement against interfaces rather than implementations. Dependency injection uses the Dependency Inversion Principle (DIP (pdf)) heavily. Combined with competent use of the Interface Segregation Principle (ISP (pdf)) your interfaces should be pretty stable so that management of those dependencies shouldn't be to onerous. Sometimes containing these dependencies in a context object can help too (everything in moderation though).

AOP sounds good on paper but the auto-magically appearing code at the point cuts can cause its own sets of problems.
See topic: AOP.
 
Pat Farrell
Rancher
Posts: 4804
7
Mac OS X VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Peer Reynders:


Dependency injection only makes sense if the dependent objects implement against interfaces rather than implementations.



I don't see this. interfaces are an important technique to reduce coupling and increasing coherance, but done properly, you can't tell that
you are dealing with an object that extends a base class or one that implements an interface.

Originally posted by Peer Reynders:

AOP sounds good on paper but the auto-magically appearing code at the point cuts can cause its own sets of problems.



I wouldn't even go that far. AOP claims to solve all the same problems that OOP claimed to solve over "structured programming" which solved problems going back Algol, which was an attempt to fix problems in Fortran.

Today, OOP is at least 27 years old, I did a fair amount of development in the mid 90s using Smalltalk 80. Java (which is where this thread started) is a modern mostly OOP. See also "My cat is object-oriented" published by ACM Press in 1989.

So far, I'm not seeing anything that convinces me that we have an answer to the initial Post, how is a Factory better than a Singleton from other than a syntactic sugar viewpoint?
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Gabriel Claramunt:
I read Martin's proposal, and I don't see much improvement. Either is a public attribute of the main class and you have the same global access problems that you had with singleton



That certainly would be just as bad, yes. (Assuming that you are talking about static access here.)


or you pass the "singleton" object all along the collaboration chain because one class at the end needs it. Worse, all your collaboration classes will depend on the "singleton" even without using it.



First, those classes won't depend on a global access point - they are not coupled to a single instance, but can be passed any instance that it's clients want it to use. That's defenitely a significant improvement in my eyes.

Second, there are ways to make those collaboration classes unaware of the Just Create One, if you care to.

But I agree that there doesn't seem to be *the* *ideal* solution - and I suspect there is none, it's always about balancing forces. But in almost all cases I've encountered, there was a better solution than a Singleton. (The only singleton that doesn't trouble me in the one million lines of code I'm working on is the logger.)
 
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

or you pass the "singleton" object all along the collaboration chain because one class at the end needs it. Worse, all your collaboration classes will depend on the "singleton" even without using it.



I'm not sure that is true. e.g is class A collaborates with classes B and C and class C uses a single instance of class D.

If C is passed an instance of D via A. Classes A & C are clearly depenedent on A.
If C accesses D via a global access point such as a singleton. Class C is clearly dependent on D and A is clearly dependent on C. Therefore A is also dependent on D.

The difference is that by passing the instance along the collaborators the dependency is explicit instead of implicit. In general I think this is preferable.

thanks, D.
 
Gabriel Claramunt
Ranch Hand
Posts: 376
Scala Monad
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I understand, but the dependency chain can easily be avoided by using interfaces: A would depend on the interface of C, hence will not depend on D
But now consider a just little more complex scenario: A->B->C->S, S being the singleton. You need to pass the "just one" instance through the chain, and even with interfaces, you have A and B depending directly on S. With a singleton , you'll only have C depending on S.
If S has business meaning, I agree it would be a good idea to have in the interface of B, but if is a orthogonal concept (like logging, or resource pools) there's no place for it on the interface.
Not sure if passing the dependency to an object from it client could be desirable (visions of broken encapsulation comes to my mind ), so the only alternative to singleton pattern is dependency injection of a singleton class. (well, now I'm rediscovering the wheel, not even reinventing it!, but thanks to this thread I understand a little more how DI could help to solve the problem). Anyway, still each approach has is advantages and disadvantages, neither is bad per se, and is a matter of design choices.
Probably the main problem is the prevalent trend on how to design/code: "I'll use a couple of factories, some singletons, and a strategy... what was the system supposed to do?..."
 
a fool thinks himself to be wise, but a wise man knows himself to be a fool - shakespeare. foolish tiny ad:
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic