Best practice to creating Objects in java
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 开发者_C百科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();
}
}
Use constructors until you start to feel the disadvantages Bloch mentions. Then consider whether factories, dependency injection, or some other approach is better.
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.
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.
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.
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.
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.
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.
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();
}
}
精彩评论