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.
Related
My program gets information from an external source (can be a file, a database, or anything else I might decide upon in the future).
I want to define an interface with all my data needs, and classes that implement it (e.g. a class to get the data from a file, another for DB, etc...).
I want the rest of my project to not care where the data comes from, and not need to create any object to get the data, for example to call "DataSource.getSomething();"
For that I need DataSource to contain a variable of the type of the interface and initialize it with one of the concrete implementations, and expose all of its methods (that come from the interface) as static methods.
So, lets say the interface name is K, and the concrete implementations are A,B,C.
The way I do it today is:
public class DataSource {
private static K myVar = new B();
// For **every** method in K I do something like this:
public static String getSomething() {
return myVar.doSomething();
}
...
}
This is very bad since I need to copy all the methods of the interface and make them static just so I can delegate it to myVar, and many other obvious reasons.
What is the correct way to do it? (maybe there is a design pattern for it?)
**Note - since this will be the backbone of many many other projects and I will use these calls from thousands (if not tens of thousands) code lines, I insist on keeping it simple like "DataSource.getSomething();", I do not want anything like "DataSource.getInstance().getSomething();" **
Edit :
I was offered here to use DI framework like Guice, does this mean I will need to add the DI code in every entry point (i.e. "main" method) in all my projects, or there is a way to do it once for all projects?
The classes using your data source should access it via an interface, and the correct instance provided to the class at construction time.
So first of all make DataSource an interface:
public interface DataSource {
String getSomething();
}
Now a concrete implementation:
public class B implements DataSource {
public String getSomething() {
//read a file, call a database whatever..
}
}
And then your calling class looks like this:
public class MyThingThatNeedsData {
private DataSource ds;
public MyThingThatNeedsData(DataSource ds) {
this.ds = ds;
}
public doSomethingRequiringData() {
String something = ds.getSomething();
//do whatever with the data
}
}
Somewhere else in your code you can instantiate this class:
public class Program {
public static void main(String[] args) {
DataSource ds = new B(); //Here we've picked the concrete implementation
MyThingThatNeedsData thing = new MyThingThatNeedsData(ds); //And we pass it in
String result = thing.doSomethingThatRequiresData();
}
}
You can do the last step using a Dependency Injection framework like Spring or Guice if you want to get fancy.
Bonus points: In your unit tests you can provide a mock/stub implementation of DataSource instead and your client class will be none the wiser!
I want to focus in my answer one important aspect in your question; you wrote:
Note - I insist on keeping it simple like "DataSource.getSomething();", I do not want anything like "DataSource.getInstance().getSomething();"
Thing is: simplicity is not measured on number of characters. Simplicity comes out of good design; and good design comes out of following best practices.
In other words: if you think that DataSource.getSomething() is "easier" than something that uses (for example) dependency injection to "magically" provide you with an object that implements a certain interfaces; then: you are mistaken!
It is the other way round: those are separated concerns: one the one hand; you should declare such an interface that describes the functionality that need. On the other hand, you have client code that needs an object of that interface. That is all you should be focusing on. The step of "creating" that object; and making it available to your code might look more complicated than just calling a static method; but I guarantee you: following the answer from Paolo will make your product better.
It is sometimes easy to do the wrong thing!
EDIT: one pattern that I am using:
interface SomeFunc {
void foo();
}
class SomeFuncImpl implements SomeFunc {
...
}
enum SomeFuncProvider implements SomeFunc {
INSTANCE;
private final SomeFunc delegatee = new SomeFuncImpl();
#Override
void foo() { delegatee.foo(); }
This pattern allows you to write client code like
class Client {
private final SomeFunc func;
Client() { this(SomeFuncProvider.INSTANCE); }
Client(SomeFunc func) { this.func = func; }
Meaning:
There is a nice (singleton-correctway) of accessing an object giving you your functionality
The impl class is completely unit-testable
Client code uses dependency injection, and is therefore also fully unit-testable
My program gets information from an external source (can be a file, a database, or anything else I might decide upon in the future).
This is the thought behind patterns such as Data Access Object (short DAO) or the Repository pattern. The difference is blurry. Both are about abstracting away a data source behind a uniform interface. A common approach is having one DAO/Repository class per business- or database entity. It's up to you if you want them all to behave similarly (e.g. CRUD methods) or be specific with special queries and stuff. In Java EE the patterns are most often implemented using the Java Persistence API (short JPA).
For that I need DataSource to contain a variable of the type of the
interface and initialize it with one of the concrete implementations,
For this initialization you don't want to know or define the type in the using classes. This is where Inversion Of Control (short IOC) comes into play. A simple way to archieve this is putting all dependencies into constructor parameters, but this way you only move the problem one stage up. In Java context you'll often hear the term Context and Dependency Injection (short CDI) which is basically an implementation of the IOC idea. Specifically in Java EE there's the CDI package, which enables you to inject instances of classes based on their implemented interfaces. You basically do not call any constructors anymore when using CDI effectively. You only define your class' dependencies using annotations.
and expose all of its methods (that come from the interface)
This is a misconception. You do want it to expose the interface-defined method ONLY. All other public methods on the class are irrelevant and only meant for testing or in rare cases where you want to use specific behavior.
as static methods.
Having stateful classes with static method only is an antipattern. Since your data source classes must contain a reference to the underlying data source, they have a state. That said, the class needs a private field. This makes usage through static methods impossible. Additionally, static classes are very hard to test and do not behave nicely in multi-threaded environments.
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.
I am reading the book EMF: Eclipse Modeling Framework where its stated:
The EMF programming model strongly encourages, but doesn’t require,
the use of factories for creating objects. Instead of simply using the
new operator to create [an object]...
Why is the use of factories encouraged over new?
Your answer does not have to be EMF specific, as long as it has to do with Java.
You can read Effective Java Item 1: Consider static factory methods instead of constructors. It describes advantages of using factory methods in detail:
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 (seems to be outdated since Java 7)
I agree with mostly every answers given here, but those arguments apply generally to every situation in Java, however in this particular case of EMF there is another additional reason: EMF has its own introspection mechanisms, which are used, for instance, for the serialization and deserialization, which doesn't rely in the Java reflection.
For the deserialization, for instance, it reads the XML file, and instantiate the Java objects using the Ecore model information and the respective Factories. Otherwise it would need to use Java reflection.
The answere here is not specific to Java too.
Factory methods have names, it's easier to remember, and less error-prone.
They do not require a new instance to be created each time they are called, you can use preconstructed classes and cache here.
They can return an object of any subtype not only the one called in new
You can parameterize calling "new" object.
The answer to this question is explained in Elegant Objects by Yegor Bugayenko, Chapter 1, Under "1.1 Never use -er names" section.
What the author says is:
A class is a factory of objects.
A class makes objects, though we usually phrase that by saying a class instantiates them:
class Cash {
public Cash(int dollars) {
//...
}
}
Cash five = new Cash(5);
This is different from what we call a Factory Pattern, but only because this "new" operator in Java is not as powerful as it could be. The only thing you can use it for is to make an instance—an object. If we ask class Cash to make a new object, we get a new object. There is no check for whether similar Objects already exist and can be reused, there are no parameters that would modify the behavior of new. etc.
"new" operator is a primitive control for a factory of objects.
Factory Pattern is a more powerful alternative to operator new, but conceptually they are the same. A class is a factory of objects. A class makes objects, keeps track of them, destroys them when necessary, etc.
A Factory Pattern, in Java, works like an extension to the new operator. It makes it more flexible and powerful, by adding an extra logic in front of it.
For example:
class Shapes {
public Shape make(String name) {
if (name.equals("circle")) {
return new Circle();
}
if (name.equals("rectangle")) {
return new Rectangle() ;
}
throw new IllegalArgumentException("not found");
}
}
This is a typical factory in Java that helps us instantiate objects, using textual names of their types. In the end, we still use the new operator. My point is that conceptually, there is not much difference between Factory Pattern and new operator. In a perfect OOP language this functionality would be available in the new operator.
Mainly it is simplicity of creating objects. It's a lot easier to call method from factory than to remember what each parameter in constructor means + it makes changes in code easier
Got design problem, maybe you can help to decide.
My client object can ask for set of objects of class Report. There is defined set of available reports and according to client's permissions different reports can included in returned set. Reports are created per request (every client gets brand new report instances on each request).
Should I use kind of "factory" that will encapsulate reports creation like below:
public class ReportsFactory {
private UserPermissionsChecker permissionsChecker;
public Set<Report> createReports() {
Set<Report> reports = new HashSet<Report>();
if(permissionsChecker.hasAccessTo('report A')) {
reports.add(createReportA());
}
if(permissionsChecker.hasAccessTo('report B')) {
reports.add(createReportB());
}
if(permissionsChecker.hasAccessTo('report C')) {
reports.add(createReportC());
}
return reports;
}
private Report createReportA() {...}
private Report createReportB() {...}
private Report createReportC() {...}
}
Is this right usage of so called simple Factory pattern? Or do you have other suggestions?
** EDIT **
Some comments below say it's not exactly Factory pattern. If not, how could I call that?
I think the design is correct, but this is a wrong usage of the "Factory" word. In the Factory pattern, XxxxFactory creates instances of Xxxx, initializes them if required, but applies no other kind of logic.
This design here seems correct to me, but your class would rather be called ReportsService
And maybe UserPermissionsChecker would be AuthorizationService
Edit: To take into account criticism against the word "Service".
There is currently a quite widespread (I did not say universal) convention in the java world, which consists in having:
A purely descriptive business-model implemented by classes emptied of all logic called (maybe mistakenly) POJOs
All business logic mainly related to an object Xxx implemented in a procedural style in the methods of a class called XxxService.
I personally don't agree with this coding style and I prefer object oriented programming, but whether we like it or not, this convention exists in the Java EE world and has it's coherence.
Judging bye the coding style of the class submitted by the OP, I inferred that he followed this procedural approach. In that situation, it's better to follow the existing convention and call the class that serves as a container for the procedural code which handles Reports a ReportService.
To me this looks a bit of a builder pattern, in a sense you have an object, that you build its data to.
This is in contrast to a factory, where usually returns different concrete types of created objects,
And usually the construction of the data of these objects is done in the CTORs of the concrete classes that objects of them are returned from the factory.
I have a common jar that uses some unmarshaling of a String object. The method should act differently depending on which application it is called from, how can I do that besides from the fact that I can identify the application by trying to load some unique class it has (don't like that). Is there some design pattern that solves this issue?
As I alluded to in my comment, the best thing to do is to break that uber-method up into different methods that encapsulate the specific behaviors, and likely also another method (used by all of the app-specific ones) that deals with the common behaviors.
The most important thing to remember is that behavior matters. If something is behaving differently in different scenarios, a calling application effectively cannot use that method because it doesn't have any control over what happens.
If you still really want to have a single method that all of your applications call that behaves differently in each one, you can do it, using a certain design pattern, in a way that makes sense and is maintainable. The pattern is called "Template Method".
The general idea of it is that the calling application passes in a chunk of logic that the called method wraps around and calls when it needs to. This is very similar to functional programming or programming using closures, where you are passing around chunks of logic as if it were data. While Java proper doesn't support closures, other JVM-based languages like Groovy, Scala, Clojure, JRuby, etc. do support closures.
This same general idea is very powerful in certain circumstances, and may apply in your case, but such a question requires very intimate knowledge of the application domain and architecture and there really isn't enough information in your posted question do dig too much deeper.
Actually, I think a good OO oriented solution is, in the common jar, to have one base class, and several derived classes. The base class would contain the common logic for the method being called, and each derived class would contain specific behavior.
So, in your jar, you might have the following:
public abstact class JarClass {
public method jarMethod() {
//common code here
}
}
public class JarClassVersion1 extends JarClass {
public method jarMethod() {
// initiailzation code specific to JarClassVerion1
super.jarMethod();
// wrapup code specific to JarClassVerion1
}
}
public class JarClassVersion2 extends JarClass {
public method jarMethod() {
// initiailzation code specific to JarClassVerion2
super.jarMethod();
// wrapup code specific to JarClassVerion2
}
}
As to how the caller works, if you are willing to design your code so that the knowledge of which derived class to use resides with the caller, then you obviously just have the caller create the appropriate derived class and call jarMethod.
However, I take it from your question, you want the knowledge of which class to use to reside in the jar. In that case, there are several solutions. But a fairly easy one is to define a factory method inside the jar which creates the appropriate derived class. So, inside the abstract JarClass, you might define the following method:
public static JarClass createJarClass(Class callerClass) {
if (callerClass.equals(CallerClassType1.class)) {
return new JarClassVersion1();
} else if (callerClass.equals(CallerClassType2.class)) {
return new JarClassVersion1();
// etc. for all derived classess
}
And then the caller would simply do the following:
JarClass.createJarClass(this.getClass()).jarMethod();