Reputation:
I have created factory class and i wonder which is better way to implement it. option 1
public class Factory {
private IProperty prop;
public IDoc doc;
public Factory(int version) {
switch (version) {
case '1':
prop = new Prop();
doc = new Docu();
...
case '2':
prop = new Prop1();
doc = new Docu1();
...
}
}
public IProperty getProperty() {
return this.prop;
}
public IDoc getDoc() {
return this.doc;
}
}
My question is if to do it like that i.e. define member with the interface type and to to switch on the constructor or for every get method to use switch statement instead on the constructor, so in the constructor i will just get the version and save it on class member and than for instance use like
public IProperty getProperty() {
switch (version) {
case '1':
prop = new Prop();
case '2':
prop = new Prop1();
...
So what is the better way, or any other idea?
Upvotes: 0
Views: 155
Reputation: 213193
First of all, your Factory
should ideally have static references
instead of non-static
one. And it should have a static method
to create / get
the appropriate instance.
Secondly, its better to have two different factories for different types.
createProperty
, rather than
getPropertyObject
, because that method is not returning the already
created instance, rather its creating one.Of course, getPropertyObject('1')
, seems like it is fetching a property
for that version from a persistence storage, which is not what it is doing. It is rather creating an instance based on version.
(NOTE: - Name of static factory methods
are important. They are amongst one of the advantages, they have over constructors
. Since with a name
, you can guess what exactly that factory method
does)
Having said that, I would say, that the 2nd option
would be better with all those changes. Let the createProperty
method decide, how it wants to create the instance
.
So, I would modify your code like this: -
public class PropertyFactory {
private static IProperty prop;
public static createProperty(char version) {
switch (version) {
case '1':
prop = new Prop();
break; // Don't forget a `break` here.
case '2':
prop = new Prop1();
break;
default: // do have a default case
prop = null;
}
return prop;
}
}
Similarly, you can create a DocumentFactory
to create a document object
. Name the method: - createDocument(char version)
Upvotes: 0
Reputation: 18864
The most clean way is to expose what you do as two separate factories giving them a common abstract base or a reusable policy argument if they have anything to share. One factory type should only create one type of particular object (say only plastic tools). Factory public configuration normally only holds properties required to create objects (contacts of suppliers, patents) or static properties of objects being created (type of plastic, let's say), but not type/class of objects.
Also, something that is a storage of long lived objects like in your example #1 should probably be called "context", not "factory".
Code example below.
public interface IFactory {
IDoc createDoc();
IProp createProp();
}
public class Type1Factory implements IFactory {
@Override public IDoc createDoc() { return new Doc1(); }
@Override public IProp createProp() { return new Prop1(); }
}
Upvotes: 5
Reputation: 51030
It depends on your situation.
The first option suggests that your IProperty
and IDoc
have different versions but for each version of one you have a corresponding version of the other.
While the second option suggests that the versions of those could be independent of each other.
Upvotes: 0
Reputation: 13872
The idea of creating a factory is much better in your first version than second one.
Ideally, it shouldn't be the constructor of factory class but a static method.
public class Factory
{
public static IProperty getPropertyObject(char version)
{
switch (version)
{
case '1':
return new Prop();
case '2'
return new Prop1();
}
}
public static IDoc getDocObject(char version)
{
switch (version)
{
case '1':
return new Doc();
case '2'
return new Doc1();
}
}
}
Upvotes: 0
Reputation: 1559
Your second way is always better since every caller of your get*
methods will receive a new instance of the object. If you create the two objects in the constructor, you will have to handle object-sharing issues (even more if you use these objects in different threads).
Upvotes: 0