2

I'm reading the Effective Java book by Joshua Bloch. In the first chapter, he says to use factories instead of constructors and lists the advantages and disadvantages of this approach. As far as I see disadvantages are not closely related to to object construction.

Moreover, Bloch says that Java Bean style of construction has disadvantages as well. Source: http://www.javapractices.com/topic/TopicAction.do?Id=84

OK, so using constructors is not great, Java beans are not great, factories are nice, so you can do some cache lookups and avoid creating extra objects (depends on the situation, sometimes you dont want caching).

How am I supposed to create an object if I try to avoid constructors and java beans?

Am I missing a point? What is the best practice?

EDIT:

class Foo{
   private Foo(){}

   public Foo Create(){
      return new Foo();
   }

}
Cajunluke
  • 3,103
  • 28
  • 28
DarthVader
  • 52,984
  • 76
  • 209
  • 300
  • 2
    The 'best practice' is what's best for you given a giant collection of considerations that cannot be boiled down to the simple 'best practice'. – bmargulies Oct 14 '11 at 18:10
  • 2
    Understand that factories use constructors as that is the only way to create an instance of an object. So even if you are using a factory, there is still a constructor in use. – John B Oct 14 '11 at 18:11
  • ok, can i use a private constructor and a factory within the same class? see my edit. – DarthVader Oct 14 '11 at 18:13
  • This isn't a question with a single true answer (or even multiple true answers), sadly. Voting to migrate to Programmers.SE. – Tom Anderson Oct 14 '11 at 18:13
  • There can be a site devoted entirely to discussions on Bloch's recommendations.. – Bhaskar Oct 14 '11 at 18:21
  • Specific Bloch topic was addressed here: http://stackoverflow.com/questions/4617311/creation-of-objects-constructors-or-static-factory-methods – David J. Liszewski Oct 14 '11 at 19:10

8 Answers8

7

Use constructors until you start to feel the disadvantages Bloch mentions. Then consider whether factories, dependency injection, or some other approach is better.

Eric Wilson
  • 57,719
  • 77
  • 200
  • 270
2

Use constructors for simple objects with small number of arguments. If the number of arguments grow , then start thinking about either builder or factory as suggested by bloch.

Most of the simple cases, constructors does the job neatly.

My experiences is that, if the number of attributes to define a object grows a lot, I would go back and review the design and find out if I have to group the attributes in a better way. Like DININGTABLE can be broken into the n legs + 1 top wooden part.

If you use factory pattern for all your object constructions, it does not look nice.

  • also NEVER USE java bean like setters in your classes unless there is a good reason * You will thank me for saying this because that will make the maintenance of the code a nightmare --- you never know who and how the setters are called to change the state of the object. Objects should be constructed with as much details as possible thru a constructor , make them as much as possible as immutable, if not make them only few ways to update the state of the object via one or two methods only.
java_mouse
  • 2,069
  • 4
  • 21
  • 30
1

It depends on the scenario. As you mentioned, if there is caching involved, then static factories are the preferable way. If there are lots of state variables, then use a Builder pattern.

Basanth Roy
  • 6,272
  • 5
  • 25
  • 25
1

You might be interested in getting familiar with the Dependency Injection pattern, with Google Guice being one of the most popular frameworks to implement it.

Nano Taboada
  • 4,148
  • 11
  • 61
  • 89
  • @rationalSpring: I've stated is _one of the_ most popular, not _the_ most popular, either way such opinion is subjective to its commenter (in this case myself) -- in any case _your_ remark is not constructive at all and, given your username, I'd even interpret it as marketing or self-promotion. – Nano Taboada Oct 14 '11 at 18:24
  • I am not affiliated with VMWare in any shape or form. – Basanth Roy Oct 14 '11 at 18:39
  • @rationalSpring: I've never implied that, but the URL in your profile / username, either way I'm finishing this argument here as it's rather pointless. – Nano Taboada Oct 14 '11 at 19:01
1

Well I think what the guy is reffering to there is Inversion of Control pattern:

http://en.wikipedia.org/wiki/Inversion_of_control

Not to make a dissertation here, I'll just say that inversion of control in this narrow context of object instanciation reffers to the fact (and benefits) of having a separate service deal with object instanciation, and not having to instanciate those objects manually. One way to achieve this is the Factory Pattern which, from what you say, the guy is describing. Another one would be to use a framework that does IOC for you, like Spring:

http://static.springsource.org/spring/docs/2.0.x/reference/beans.html

(which is really not that far from the Factory Pattern)

A third option is to make your own IOC Mechanism that deals with object instanciation in some way so you don't have to do it explicitly every time.

The idea here is not to stop using the constructor to create instances, you always use that to get your instances, the idea here is WHEN and HOW you call that constructor:

  • do you call it directlly in the class that needs the instance
  • do you have a separate mechanism (like Factory) that deals with getting that instance (dependency) when needed, such that you never explicitly do it yourself

There are advantages to both ways. More often than not is better to deal with instanciation separatelly and not do it manually as it leads to cleaner, less coupled and more testable code.

Shivan Dragon
  • 15,004
  • 9
  • 62
  • 103
1

If you came across a program that was doing maths to work out what day of the week it was all over the place, what would you think? You'd probably think "that maths to work out what day of the week it is should be in a method of its own, so it can be expressed once and only once, with the method being called wherever the code needs to know what day of the week it is".

Constructing an object is no different to working out what day of the week it is, really. Do it in one place, make that a method, and call that method from wherever you need a new object.

Now, in some cases, that method can itself be the constructor (a constructor is really just a funny kind of method, right?). In others, the method will call the constructor, which will not be used anywhere else. It depends on how much work there is to do to create the object, and how much you want to hide the class of the object being created (imagine a createDaysOfTheWeek factory method - it could return a Collection<DayOfTheWeek>, and hide the fact that it's an ArrayList or LinkedHashSet or EnumSet or whatever). Wrapping the construction in a factory method gives you more encapsulation, but less transparency. Both of those qualities are needed to make good code, but like beer and pies, you need to have a balance of them.

Tom Anderson
  • 46,189
  • 17
  • 92
  • 133
0

Always judge a recommendation in the context. Constructors are the standard way to create an object , but they are not entirely free from disadvantages.

For example , he talks about a Service provider framework - this is made possible only on factory methods of constructing objects. But the point is you dont design Service Provider Framework all the time.

Again , he quotes examples from Collection framework which use instance-controlled classes. This is not possible if you limit object creation to simple constructor style. But again , everyday code need not adopt the instance-controlled classes.

There are other cases he makes in support of the factory method - all under some context of use. In other contexts , constructors may well suffice.

Bhaskar
  • 7,443
  • 5
  • 39
  • 51
0

You can create object using Cinstructor like using new as follows example:

Foo f=new Foo();

There is a concept called singleton.In that case you can use this type as you shown above but make the create function static else how the user will call the function create as follows:

class Foo{
   private Foo(){}

   public static Foo Create(){
      return new Foo();
   }

}
Android Killer
  • 18,174
  • 13
  • 67
  • 90
  • 1
    The purpose of a singleton is to allow one-and-only-one instance of a class. In this case you are creating a new instance with every call to Create() so it's not a singleton. – Chris Nava Oct 14 '11 at 18:49