wood burning stoves 2.0*
The moose likes OO, Patterns, UML and Refactoring and the fly likes Need help with Factory Pattern Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "Need help with Factory Pattern" Watch "Need help with Factory Pattern" New topic
Author

Need help with Factory Pattern

Dmitry Zhuravlev
Ranch Hand

Joined: Apr 14, 2010
Posts: 91
Hello Everyone!

Guys, I have the following structure: parent class TransportType -> child class Car, child class Bike, child class Boat etc. Each of the child classes has its own constructor with a specific number of parameters. For example: Car(color=red, wheels = 3), Boat(Sail = true) etc

The question is: what is the best way to create the class factory? I can see 3 ways:
1) TransportFactory.createCar(String carColor, int carWheels);
2) TransportFactory.createTransport(String transportClass, Object[] transportParams);
3) TransportFactory.createTransport(Object[] allParams);

In item 1 I'll have to create a number of functions, one for each child class. Moreover, I'll have to change my code each time a new child class is added.
In item 2 and 3 I can use the Reflection API to create the object instead of multiple if-then switches. This will decrease the amount of code. But I can use TransportFactory.getDeclaredConstructors() only in case all the child classes are located inside TransportFactory class. This will make my code a bit complicated. Also I have heard from senior developers that I should avoid using Reflection if possible.

So, what is the best way to implement this structure?
Jimmy Clark
Ranch Hand

Joined: Apr 16, 2008
Posts: 2187
In item 1 I'll have to create a number of functions, one for each child class. Moreover, I'll have to change my code each time a new child class is added.


You are going to need to write the new code of the new class as well. Making a related change to the factory class is trivial. This option is the easiest to understand, so it is the "best."

Aside, TransportType should ideally be an interface class, not a concrete class.
Dmitry Zhuravlev
Ranch Hand

Joined: Apr 14, 2010
Posts: 91
Thank you for the reply, Henry!

As for parent class I have made it abstract because I have several functions that are common for all the childs.

Jimmy Clark
Ranch Hand

Joined: Apr 16, 2008
Posts: 2187
Sounds good!





In your factory object then:





Aside, the Reflection API is a powerful tool and is very useful when buliding complex dynamic systems. To use it effectively however, you need a very detailed understanding of what you are doing and how the API works, and how a JRE works.

Using the Reflection API for simple tasks is not good and is commonly screwed up by the novice programmer eager to do something "complex." Hence, it should be avoided.

Dmitry Zhuravlev
Ranch Hand

Joined: Apr 14, 2010
Posts: 91
Henry, I wonder why I cannot place all the common functions into abstract class as abstract methods instead of interface? Why using interface is better? Anyway I have to spend my only inheritance. And whats the sense of making that interface abstract?

As for Reflection, I suppose its not difficult in my case, only one function for running class constructor.
Jimmy Clark
Ranch Hand

Joined: Apr 16, 2008
Posts: 2187
There are typically many different ways to design software. A Java interface class is always abstract. Including the abstract keyword in the interface class declaration is optional.

There are many benefits to thinking and designing in terms of "interfaces" and "interface contracts." A good one that I like to mention is that it enables you to design polymorphism efficiently without being locked down by Java's single concrete implementation restriction. Mulitple inheritance via Java interface classes is a powerful design tool.

If you are just creating a simple application for a homework assignment or a small non-distributed application, then the potential benefits might not seem to valuable. When you get into large scale enterprise systems, the rules change a bit. Designing with an emphasis on "interfaces" helps you separate implementation details from object responsibilities in your head.
Dmitry Zhuravlev
Ranch Hand

Joined: Apr 14, 2010
Posts: 91
OK, this looks easy, but another part of task is to store my Transport Objects in a map. To do this I have written the following:



And I'll have to repeat that code for 6 or 7 times with slight changes.

The thing that really confuses me is whether that style of coding is really better than one Reflection function for all? I thought OOP was invented to reduce the number of copy-pasting..
Jimmy Clark
Ranch Hand

Joined: Apr 16, 2008
Posts: 2187
Write two versions of the code, one version using the Reflection API and one not using it. Choose which ever one that is maintainable, scalable, manageable, and easy to understand. The version that is "better" is the one that you can write efficiently. You probably really don't need to have multiple copies of the same code either. That is a result of how "you" are writing the code. Another programmer may write it differently that "you."
Ran Pleasant
Ranch Hand

Joined: Jan 16, 2003
Posts: 75
Dmitry Msk wrote:Henry, I wonder why I cannot place all the common functions into abstract class as abstract methods instead of interface? Why using interface is better? Anyway I have to spend my only inheritance. And whats the sense of making that interface abstract?


I would strongly suggest following Henry's good advice. It seems that you are using inheritance only for convenience of making use of a few methods rather than looking at whether the entities in question are truely part of a family of entities. It might not seem like an issue when looking at just a car, a bike, and a boat, but it may become a big issue later if you have to add a ship, rocket, train, etc. The use of an interface as Henry suggested makes it a non-issue. A better example is a "customer" interface, clearly a person and a corporation should not inherit from the same from the same super class because they are totally different things but they can both be customers of a store. Programming for the convenience of making use of a few methods may cause you a lot of inconvenience down the road. Take a look at the Interface-Segregation Principle.


Ran
Dmitry Zhuravlev
Ranch Hand

Joined: Apr 14, 2010
Posts: 91
It seems that you are using inheritance only for convenience of making use of a few methods rather than looking at whether the entities in question are truely part of a family of entities.


Ran, you are right. I can easily replace inheritance from my abstract class with the implementation of the TransportType interface. But I'll have to copy-paste several functions and fields. That bothered me because I supposed that copy-pasting is not a good coding style (one of the points is that I was implementing the Visitor pattern in my application and to do this I need to place an accept(visitor) method in each of my Transport classes).

So, I will move towards the Henry's version. Thank you both for assistance!

Jimmy Clark
Ranch Hand

Joined: Apr 16, 2008
Posts: 2187
Dmitry, you seem to be missing something. In my version you still have an abstract class. The only difference is that the abstract class also implements an interface. And client objects are programmed to communicate using the interface type, not the implementation type.

 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Need help with Factory Pattern