I am a beginner in Java and the book that I use to learn it seems to have cryptic examples and sentences that completely confuse me.
I understand what interfaces are and how/where to apply the concept in real world. But what are Factory Methods? The term "factory method" is ambiguous (JavaScript has a different meaning for that) so I am providing the snippet that the book has, in order to make my question clear. Here is the code:
interface Service {
void method1();
void method2();
}
interface ServiceFactory {
Service getService();
}
The Service interface is just a normal interface. ServiceFactory interface looks like a normal interface but it is a "Factory Method". What's that? What does it solve and why I should use them?
A factory method is simply a method that encaspulate the creation of an object. Instead of using the new operator as you normally would for creating an instead of a Service, in your example, you're using the factory method on some object.
ServiceFactory sf = new ServiceFactoryImpl();
// factory method
Service s = sf.getService();
To better illustrate the role of the method, it could be called createService instead. Now the method encapsulates the details of the creation of a Service, you can provide many flavors of the methods (by overloading), you can have it return different subclasses depending on the context, or parameters passed to the factory method.
A "factory method" is a method that constructs an object.
More specifically, the term usually refers to a static method that returns an instance of its declaring class (either a direct instance, or an instance of a subclass). In my experience, there are a few cases where that's particularly commonly done:
If you need to have multiple different constructors, using factory methods lets you give them appropriate names (whereas calls to different constructors can only be distinguished by the argument-types, which aren't always obvious at a glance).
If you need to have a few different implementations of a single abstract class that serves as the entry-point, the factory method can instantiate the appropriate subtype.
If you need any sort of caching logic or shared instances, the factory method can handle that, returning an already-existing instance if appropriate.
If you need to do some work with side effects, a factory method can be named in such a way that it's more clear what those side effects are.
So, your example doesn't really involve a "factory method" IMHO, but you can cheat a bit and describe getService() as one. (Rather, I would just describe ServiceFactory as a "factory" at leave it at that.) The benefits of ServiceFactory.getService() are the same as those of a factory method, plus the usual benefits of having an instance instead of a static method.
Related
I'm trying to understand the Factory Method pattern. I've managed to distinguish it from the Simple Factory, but now I don't get why it's actually called a "pattern". Please, look at my example below:
Class Diagram link
Sample java code for Messenger:
public String exchangeMessages(String messageToSend) {
Socket socket = getSocket();
socket.open();
socket.send(messageToSend);
String receivedMessage = socket.receive();
socket.close();
return receivedMessage;
}
And for Client:
public static void main(String[] args) {
Messenger messenger = new TCPMessenger("127.0.0.1", 4321);
String result = messenger.exchangeMessages("Hello!");
System.out.println(result);
}
If I understand correctly, everything makes sense because exchangeMessages method exists. We use the abstract factory method getSocket inside it and thanks to it we:
let subclasses decide which class to instantiate
But isn't it just an ordinary abstract class implementation? We take advantage of the code shared by both TCPMessenger and UDPMessenger - for me, this is not a pattern but a core feature of Object-Oriented Programming that everybody knows from the beggining of OOP language learning!
Moreover, I think that naming this creational is very confusing. We actually care about exchangeMessages method, so Client (part of the code that uses our "pattern") is not even aware of the Socket class which creation we're all about. It's more like a way to implement Messenger functionallity (which can be easily extended etc...) than a way to really create something.
Am I missing the point or is my example invalid? Please guys, let me know what do you thing about it.
Thanks in advance!
for me, this is not a pattern but a core feature of Object-Oriented
Programming
Most of patterns rely on core OOP features : programming by interface, overriding, polymorphism, and so for...
Moreover, I think that naming this creational is very confusing.
We actually care about exchangeMessages method, so Client (part of the
code that uses our "pattern") is not even aware of the Socket class
which creation we're all about. It's more like a way to implement
Messenger functionality (which can be easily extended etc...) than a
way to really create something.
It depends on the point of view you are taking.
For subclasses of the Messenger abstract class such as TcpManager, their parent class defines all but this factory method that they have to implement to specify what Socket getSocket(); should return.
So for subclasses point of view, talking about a creational pattern for Socket getSocket() makes sense.
For client classes of Messenger, things are indeed different.
Clients may even not need to use directly this method.
For these classes, the important thing is indeed having a way to manipulate indifferently any subclass of Messenger.
The Factory Method pattern is a simple pattern, but still a pattern nonetheless.
Your Client and its relationship to the Factory Method
The Gang of Four (GoF) definition of the Factory Method Pattern does not specifically mention a Client as a participant of the pattern itself. In reality the Client is most likely to use the Factory Method indirectly through some other operation.
In your case as the Client does not care about the Socket being used, but just the Messenger itself. However, the Messenger is dependent upon a Socket as it has some behavior that uses a Socket Object.
So whilst the Client itself does not care about the Socket, it does care about the Messenger which has a use dependency with Socket.
As the Socket itself is abstract it gives us a problem, as we don't want to replicate the same logic in exchangeMessages(String) multiple times for the different implementations of Socket (TCPSocket and UDPSocket), especially when we may want to add more Socket classes at a later date.
This is where the Factory Method pattern comes into play, as we can define all the generalized behavior for exchanging messages at an abstract level, but leave the creation of the actual Socket implementation (TCPSocket and UDPSocket) to subclasses of Messenger (TCPMessenger and UDPMessenger).
Discussion of alternatives to the Factory Method Pattern
You could just set the Socket as a field of Messenger, and inject it using a Strategy pattern approach or have a constructor that takes a Socket as a parameter. A drawback of this approach is that we'll have to maintain a reference to this Socket Object as a class field in anticipation of it's use.
However, with the Factory Method Pattern, the Socket will only be created in the method exchangeMessages() when needed and then discarded when the method terminates, which may be of some benefit. This comes at the cost of having to create one of the Socket Objects each time exchangeMessages() is called, which may not be ideal.
You could also pass the required Socket to the exchangeMessages() method to be used, but this may not as convenient for the user of the method in the long term.
If your Messenger subclasses also have some specific behaviors (new methods / overridden implementations) not applicable to all types of Messenger, then Factory Method is certainly the way to go, as we need to subclass Messenger anyway and it allows us to strictly enforce the type of Socket created by the Factory Method getSocket().
Perhaps others could contribute to the pros/cons of the Factory Method (specifically in Java as this the language tag for the question) and I can update this answer in due course.
Validity of your example
About whether your example is invalid or not. I think it helps to first fully understand the pattern and the important classes, operations and relationships in order to conform to the Factory Method pattern (as specified by the GoF).
The Factory Method Pattern allows you to define an Operation (or possibly several operations) in an abstract Creator class (in your case Messenger) which will use some Object (a Product [Socket]) without knowing the specific Product in advance and deferring its creation (hence the term creational pattern) to the Factory Method.
The Factory Method itself (getSocket()) is abstract in the Creator class and will be implemented by Concrete Creators (TCPMessenger, UDPMessenger) so polymorphism is used to achieve Object creation.
The Factory Method will return a Concrete Product (TCPSocket, UDPSocket) and have a return type applicable to all Concrete Product classes (Socket) used by the Operation in the abstract Creator class.
The Operation(s) (exchangeMessages(String)) that use the Factory Method will use the Concrete Product returned by the Factory Method by the interface Product which is applicable to all Concrete Product classes (Socket).
The result is that this pattern allows new Concrete Product classes to be added by implementing / subclassing the Product interface / class (or its subclasses...) and introducing a new Concrete Creator which returns the newly added Concrete Product from its Factory Method, preventing the need to re-write your Operation(s) that use this Product.
This means that we do not need to modify existing code when introducing new Concrete Products (Open/Closed Principle).
Generalized UML for the Factory Method Pattern
Some notes on the UML:
The factoryMethod() can be given a default implementation in Creator (i.e. a default Product to return), in turn allowing Creator to be non-abstract
The factoryMethod() could be public if desired, but this is superficial to the intention of the pattern since the factoryMethod() is primarily intended to be used by operation()
Product does not have to be abstract class, it could be an interface or it could be a concrete class
Validity of your example (continued)
In reference to the UML (and your example), the important parts of the pattern in less wordy terms are as follows:
There must exist
A Product interface (not neccesarily an interface in Java terms, could be a class or abstract class in reality) (in your case Socket)
ConcreteProduct classes that implement the Product interface (TCPSocket, UDPSocket)
An abstract Creator class (Messenger)
A Product factoryMethod() method that is defined in the Creator class (getSocket())
Note: The Creator and factoryMethod() are usually abstract, but the Creator can define a default Product removing this requirement.
operation() methods in the Creator class that use the ConcreteProduct returned by the factoryMethod() (exchangeMessages(String))
At least one ConcreteCreator class (TCPMessenger and UDPMessenger))
Such that
The ConcreteCreator classes implement the Product factoryMethod() to create and return a ConcreteProduct
The abstract Creator class uses the ConcreteProduct (returned by Product factoryMethod()) through the interface for all Product implementations
The last two points reflect that Creator has a use dependency with the Product interface, and the ConcreteCreator classes have a create dependency with its corresponding ConcreteProduct class.
Again, note that the Client class is not part of the pattern itself (as defined by the GoF).
So in conclusion, your example would appear check out as the Factory Method in regards to the requirements listed above if the TCPMessenger and UDPMessenger class implement the getSocket() method correctly (which I assume they actually do).
I am confused with the concept ? Is it just as simple as incorporating a static method to return the object instead of a constructor ? So that client doesn't need to change the code while we update the library or there is something more to it ?
The book Head First Design Patterns will be your definitive guide for Java. That is a great book. If you check out my answer to this Stack Overflow Question, you will be able to see my implementation for an ArbitraryPointFactory class in the Point Example code that uses the Factory Method pattern as well as how it differs from Abstract Factory pattern seen in the Point Factory class. Although this answer is presented with C# code samples, the design pattern language I am using to describe their usage, should warrant you an answer.
What you are thinking of in your question is not a design pattern at all. This static method that returns an object to encapsulate the instantiation, is known as the Simple Factory as seen in the Wiki page. The Factory Method pattern more or less abstracts the type being returned via an interface. This is typically done where the sole job of the factory method class is to control creation of the objects for one concrete class that implements the interface being returned. The Abstract Factory provides encapsulation for a group of related products. In my example I was showing for different types of points, however they could implement different interfaces and all use the same Abstract Factory.
The idea is that you are programming to interfaces, not implementations. True factories pull creation logic to a single location in your application and encapsulate the instantiation via interfaces.
When we use Abstract Factory Pattern, we generally have FactoryMaker class which has a getFactory function in which we pass argument and we have switch or if-else logic in the function on the passed parameter to decide which factory to return. Is creating passed parameter an enum or an object and then having the logic of which factory to return inside those object will be better. For example :
Let us say this us our factory maker which are passed enum CountryCode to decide factory.
public class FacoryMaker {
public final static FacoryMaker fctry= new FacoryMaker();
public static RetailFactory getFactory(CountryCode code){
RetailFactory rt = null;
if(code == CountryCode.UK){
rt = new UKFactory();
}
if(code == CountryCode.US){
rt = new USFactory();
}
return rt;
}
}
Instead of this we will have :
public class FacoryMaker {
public final static FacoryMaker fctry= new FacoryMaker();
public static RetailFactory getFactory(CountryCode code){
return code.getFactory();
}
}
and enum will be modified like this:
public enum CountryCode {
US(){
#Override
public RetailFactory getFactory() {
return new USFactory();
}
},
UK(){
#Override
public RetailFactory getFactory() {
return new UKFactory();
}
};
public abstract RetailFactory getFactory();
}
But I don't see this being followed generally. Why is it so? Why can't we make the passing parameter always an object and have the logic inside the object of which factory to get? Can it fail under any abstract factory design. It looks very generic to me. Also by this it is possible to even remove the factory maker and use the object directly to get the Factory instance.
When designing software, one aspect to consider is Separation of Concerns it doesn't sound very reasonable to me to let a CountryCode create a RetailFactory. Both concepts have a pretty low cohesion towards each other, which should be avoided.
Further, if you already have a country code, why would you need a factory at all, what's preventing you to call the getFactory method directly? It simply makes no sense.
The CountryCode is merely a hint for the FactoryMaker's getFactory method, how to create the factory. It may even completely ignore the country code. What if there is a country without a RetailFactory? Do you return null? a DefaultFactory or the Factory of another country?
Of course it is possible to do it that way, but if you look at your code a half year from now, you may think "Wtf? Why the heck did I create the Factory in the Country Code?!"
Besides, the first example you provided seem to be more of a Factory Method than a Factory because the FactoryMaker is not used at all.
I think that Abstract Factory is a general pattern for all OOP languages. When people describe it, they should show a general implementation which is possible to be applied in all of those languages. Then people follow the pattern, they follow genernal implementation.
And your implementation is using Enum which is specifically supported in Java but not other OOP languages.
Very often in practice, factory methods don't know in advance the implementations. The implementing classes may not exist at the time the factory is created. This is the case for example in service provider frameworks such as the Java Database Connectivity API (JDBC). JDBC defines the interfaces that service providers must implement, but the concrete implementations are not known in advance.
This framework allows adding implementations later, for example for database drivers of new cutting edge databases.
The service provider framework includes a provider registration API to register implementations (ex: DriverManager.registerDriver), and a service access API for clients to obtain an instance of the service (ex: DriverManager.getConnection).
It is common to instantiate the service implementation using reflection (ex: Class.forName("org.blah.Driver")).
Your example is different. You know all the implementation classes you intended.
And you are not considering (yet) the pluggability of other implementations.
Whether you create the instances using a switch or an enum,
it makes little difference.
Both alternatives are fine, equivalent.
Another related alternative is that the various methods in Collections do, for example Collections.emptyList(), Collections.singletonList(...), and so on.
The implementations are not decided by a switch,
but have explicit names by way of using specialized methods.
When you want to make it possible to use implementations of your interfaces not known in advance, and not hard-coded in your factory, look into service provider frameworks such as JDBC.
But I don't see this being followed generally. Why is it so?
Your technique only works because you know all the implementations of RetailFactory in advance.
In frameworks like JDBC, all the implementations of Driver, Connection, and so on, are not known in advance, for all the databases out there, so using such technique with a single enum referencing all implementations is not possible, and not scaleable. So they use a different mechanism, to register and load implementations dynamically at runtime.
Why can't we make the passing parameter always an object and have the logic inside the object of which factory to get?
You can. If you don't need dynamic loading of implementations like JDBC (and most probably don't), your way of using enums has some advantages.
For example, your original implementation does rt = ..., which is not as good as doing return .... Such "mistake" is not possible using your enum solution. On the other hand, if you want dynamic loading, then using an enum will not make much sense.
The bottomline is, there is no big difference between the two alternatives you presented. Both are fine.
My singleton class implements a interface and in future I can expect many concrete implementation to come out .
I am thinking of creating an instance of this class through factory method. factory method may be overloaded .
My question is how good or bad this idea is ?
Based on your updated comment, sure you can do that. A factory method dishes out singleton implementations of your persistence classes based on the overloaded parameters or an enum / integer value in the parameter. There are many frameworks out there that use this pattern, say to give you instances of a client that communicate with a server based on different protocols.
MyFactory.pbClient("host", port);
MyFactory.httpClient("host", port);
It is irrelevant if the instance returned from your factory method is a singleton. That is an implementation choice - do what is correct for your need.
Also, if your method signature is returning an interface, then technically it's an abstract factory method, not a factory method.
I am going through Effective Java and some of my things which I consider as standard are not suggested by the book, for instance creation of object, I was under the impression that constructors are the best way of doing it and books says we should make use of static factory methods, I am not able to few some advantages and so disadvantages and so am asking this question, here are the benefits of using it.
Advantages:
One advantage of static factory methods is that, unlike constructors, they
have names.
A second advantage of static factory methods is that, unlike constructors,
they are not required to create a new object each time they’re invoked.
A third advantage of static factory methods is that, unlike constructors,
they can return an object of any subtype of their return type.
A fourth advantage of static factory methods is that they reduce the verbosity
of creating parameterized type instances.
Disadvantages:
The main disadvantage of providing only static factory methods is that
classes without public or protected constructors cannot be subclassed.
A second disadvantage of static factory methods is that they are not
readily distinguishable from other static methods.
Reference: Effective Java, Joshua Bloch, Edition 2, pg: 5-10
I am not able to understand the fourth advantage and the second disadvantage and would appreciate if someone can explain those points. I would also like to understand how to decide to use whether to go for Constructor or Static Factory Method for Object Creation.
Advantage 4: When using a constructor, you have
Foo<Map<Key, Value>> foo = new Foo<Map<Key, Value>>();
vs
Foo<Map<Key, Value>> foo = Foo.createFoo(); // no need to repeat
this advantage will be gone in Java 7, when the diamond syntax will be introduced
Disadvantage 2. You can't easily tell whether a given static method is used for constructor, or for something else.
As for how to choose - there is no single recipe for that. You can weigh all of the above advantages and disadvantages given a use-case, but most often it will just be a decision driven by experience.
If you know the concrete type of the class you are trying to create, then calling the Constructor is fine.
Static Factory Methods are nice when you're not entirely sure how to construct the object you need.
The Factory Method still calls the Constructor on the concrete type, but the method handles the decision on what kind of concrete class to instantiate. The Factory Method then returns an Interface type (rather than a concrete type) so that the concrete type is hidden from the caller.
Disadvantage 2.
A static method that is used for object creation has the same functional layout and appearance as any other static function.
Just by looking at a static method that creates objects you wouldn't know it does this, and the opposite is the relevant part. When you're writing code that you're unfamiliar with, it can be difficult to identify the correct static method that is used to create objects.
The use of the Static Factory Pattern is well documented and can be very useful, especially in Singleton and Multiton situations. Also useful in the initialisation of complex objects.