Factory Pattern - Is having multiple factories a good idea? - oop

I am designing a system that lets a user assign a specific task to be performed when a button is pressed. The task to be performed can be assigned to all sorts of things. So I have an abstract base class called "ButtonTask", and all other tasks inherit from this base to implement the task to be performed along with the associated data it needs to know. This way I can use polymorphism to abstract away all the specifics, I just call "PerformTask" without having to care about what type it actually is. So far so good.
The actual task itself can be set in may different ways, the user may change the task with a UI menu, the task may be read from a file, and also the task may be set remotely via a network message.
At the moment I have a factory function that will create the correct derived type based on the network message, and return a pointer to the base type. The problem is that the UI menu and the file reading feel like they need their own factory method for object creation, as they are inherently different from one another. Is it generally a good idea to have multiple factories for this kind of problem? I can't really think of another way around this problem but perhaps there's something neater I can do.

The only good reason I see to implement multiple factory methods is if you want to be able to create the objects with different sets of initial attributes, for instance by allowing the caller to specify some attributes and setting default values for others - the equivalent of having multiple public constructors.
If the idea is that the tasks are independent of the way they were initiated (GUI, network, etc), then I don't see a need for separate factory methods. Instead, I would say that one of the duties of the factory is to achieve this very abstraction. In other words, calling the same factory from three different parts of the code is absolutely fine. It is probably a good idea to make the factory method static or to make the factory a singleton object, though.
If on the other hand you have a situation where certain tasks can only ever be initiated from the network and others from the GUI, and only a few can be initiated in all three ways, then it might be worthwhile to rethink the design a bit. You should then consider adding another level of abstract Task classes, eg CommonTask, GuiTask, NetworkTask, FileTask, and have factories for them instead of ButtonTask. This is obviously more complex and whether or not it's worth it depends on the number of task classes and the structure of your code.
What you want to avoid is a situation where users of the factory are aware of which specific subclasses of ButtonTask they can receive from the factory. That's a "false base class" situation, ie one where the base class is not a true abstraction of the whole set of its subclasses, and you get out of it by adding the extra subclass layer as outlined above.
Other than that, you might also want to consider renaming ButtonTask; it sounds like a GUI-only task just from the name.

Related

Should I store common functions in a Parent/Base class

I have common functions, such as syntactic sugar for calling the database, logging or site-wide information such as a look-up tables.
If I put these in a site-wide base class I will have access to them, however it just seems intuitively wrong to use a parent class this way. It would make more sense to use the base class as a 'has a' relationship rather than an 'is a'.
Or perhaps this is good design? Is there any problem doing this?
Parent classes should instantiate some base functionality and a child should instantiate the differentiating code.
IMNSHO, what you are describing is a bastardization of that process.
Ideally you would only want to serializable POCO classes, because they only contain properties and no methods.
Having a baseclass for common functionality might be a good idea, if you place code it in, that will be same in every childpage and if there is no other good place.
For instance you could place Helper-methods inside a baseclass, but that breaks OOP in my opinion.
In my opinion, having a class that derives from System.Web.UI.Page and replaces some logic in the OnInit event or other events is a very good strategy. I've used this approach in various projects, but I limited the code in the baseblass to globalization and logic for memberpages (like redirects to non public pages).
I believe that what you are doing is wrong.
First of all, object should be dedicated to one task. Having db connection handling, logging or look-up tables in the same class seems very ugly, regardless of whether these funcitonalities are inherited or not.
Moreover, the functionalities you described seem like fitting the exact idea of an object, just as described above. So, to answer your question: yes, has-a relationship seems like a much better solution.
In general, I tend to try to put program-wide accessible functions in separate classes. If possible, I try to use static methods. Behind these sometimes are singletons, sometimes there is some kind of queue, and sometimes something entirely different. Still, having one single point of origin for such functionalities the code is very flexible. If static methods are not applicable, especially when there is a need to store some information in such helper class, only then do I instantiate an object for each instance of other class. Even then factory/pool single point of origin static methods are often a good idea.

Creating objects with the same arguments across the system

I have an object that performs a very specific task. To be created, this object needs some parameters. I create a new instance in some parts of my system. But there is the problem. What if a parameter or argument must be changed in the future? I will need to change it everywhere. Then I thought: "Well, maybe I can encapsulate its creation in a class, if some argument changes, I will need to change it just in a single place!".
It does make perfect sense to me. The real question is, is this "wrapper" object a factory? Its responsibility would be "Create a new object with specific parameters and return it". Consumers would just use this object ...
You a refactoring code to avoid duplication, that is itself likely to improve your overall maintainability.
If this piece of refactored code is creating objects then, yes, it is a factory. It really doesn't matter what you call it - is your code better structured now you have it? Then do it!
However, given that it is a factory study the classic design patterns concerning factories and understand what leads people to use more sophisticate forms of this pattern. Decide whether you have any of the forces that lead them to use "clever" factories.
The problem you describe is that all clients of your class have to change when the constructor parameters of that class change. Introducing a factory could help prevent recompilation of the clients. But does this really solve the problem? If you modify the class to be constructed with another parameter that parameter has to be determined somewhere, probably in the context of the clients that initiate the construction. How should the factory class know? Would the clients have to pass any context information to the factory?
What parameters are needed to construct the object? Do the clients provide them or could the objects be created beforehand and then injected into the clients as you would inject the factory (as I understand your question the latter seems to be the case)? Consider using a DI framework. This oftentimes makes factories obsolete.
Why are you afraid that your class is likely to be changed? Could it be that your class just does too much? Mind the Single Responsibility Principle. In your case also the Open/Closed Principle is an interesting study.
As I understand a factory does not necessarily address the problem you describe. Factories take the responsibility of creating objects away from clients so the client doesn't have to know the concrete type of the object. Just preventing that signatures remain stable can also be done by wrapping parameters in a single object. This is also a well known refactoring pattern. But it also doesn't solve the question where the new parameters come from.

Which design pattern can I use to solve this situation?

First of all, I'm using Objective-C, but this doesn't matter at all.
My situation is:
I have two different scenarios. I distinguish them by a preprocessor macro like:
#ifdef USER
do some stuff for scenario 1
#else
do some stuff for scenario 2
Both scenarios works with a list of items all across the application, but the difference is the way of getting those items.
In the first one I get the items by sending a request to a server.
In the second one, I get them from the local device storage.
What I have now is the second scenario implemented. I have a singleton class that returns to me the list of items by getting them from the local storage. (like a traditional database singleton)
I want to add the other scenario. Since the items can be get from any point across the app, I want this to be a singleton too.
Does it make sense to have a singleton superclass, and then two subclasses that implement the different ways of getting the items? Singleton hierarchies sound quite strange to me.
That's not exactly hierarchy. The superclass you're mentioning is actually an interface for your 2 concrete classes, which can be singletons if you want. The interface is an abstract entity thus any instance-related term is irrelevant to it.
You're statically defining your program behavior by using preprocessor to do the scenario choice. If you stick to this approach and it fits your requirements, you don't need any design patterns. In your code just use the interface I mentioned above, which is a port to your statically instantiated data. If you want to have more flexibility (this sounds likely), you can do your scenario choice at runtime. In this case you may find the Strategy pattern useful for applying scenarios and Factory pattern for instancing.
Factory combined with Strategy.
Factory as the pattern of using another class to make your instance rather than using just a constructor. You are already doing that with your Singleton most likely.
Strategy for the ability to configure which kind of object is actually created by the factory at rutime.

Is it considered bad practice to use a static method as a factory?

I see most projects creating separate factory classes, so for example, they'll have a User class, and a UserFactory class. This makes sense if your factory needs more methods than just a CreateUser method, but most of these factories only have a constructor and a CreateUser method (or equivalent for whatever the factory creates). So, are there other reasons why you would create a separate factory class over just adding a static User.create() method to classes?
In my experience, separate factory classes are mainly used if you often want to change the implementation, especially for test cases. For example, if User has methods that hit a database and are "too slow" for a Unit Test, you might want to have a MockUser that doesn't use the database. Then you can have a RealUserFactory for the actual app, and a MockUserFactory for the unit tests.
But there may be real world examples where you want to change, say from a SecurityClearedUser in your military spec app to a AnyOldUser in another. So a config file would declare the class of the factory, e.g. a MilitaryUserFactory or an AnyOldFactory.
Of course, User.create() could read the actual class to create from a config file. So, in practice, I'm not sure if there's that much of a difference. Depends on how things are setup.
Another thing to consider is 'separation of concerns'. In the case of User.Create, the user class will be doing more than it should, hence the need of a class that does precisely that, creating a User.
By using User.Create, you would have coupled the creation of an object to the class itself and in other instances, you will be confronted by scenarios were the user creation consists of various steps, and if that is the case, the User.Create method becomes inappropriate.
So to be brief, keep the user object responsible for being a user, and outsource the creation of the user to an external concern, Factory.
and from a readability perspective, User.Create vs UserFactory.Create... think of it as 'a car cannot create a car', but a factory can.

Unused Interface Parameters

I have an interface that is implemented by thirty concrete classes. The concrete implementers are subdivided into two groups, with each group inheriting from a common abstract class. The abstract classes define the constructors for the concrete implementers, including passing in a database connection object for each "side" of the two sides (they have different databases, among other differences).
All the current interface methods each have several parameters needed for the concrete classes to "get the job done", but not all are used in every implementer.
When I went to add a new method to the interface this morning, I realized that the database connection is going to be needed for only one of the concrete implementers, but the rest will not need it. So, that gets me wondering, should I pass it in as a parameter? It is needed to "get the job done", but for only one of the concrete classes, and that class has the database connection already. If I passed the database connection in as an interface parameter, then the other 29 classes will not use it.
What is a good line to draw for what is an acceptable interface parameter? Any reading/content on the subject I will thankfully devour as well.
All the current interface methods each have several parameters needed
for the concrete classes to "get the job done", but not all are used
in every implementer.
That sounds to me a lot like the interface is slowly turning into a bit of a "god interface". Check whether this is the case by asking yourself a couple of questions:
Does the interface represent a single behavioural concept in your model, or has it become a bit of a convenient dumping ground for method signatures from several concepts? Could it be called something like e.g. Serializable, or would it more accurately be called SerializableAndSomethingElse.
Could you carve the interface up into several more cohesive interfaces, and have the 30 different objects implement just the ones they need?
When I went to add a new method to the interface this morning, I
realized that the database connection is going to be needed for only
one of the concrete implementers, but the rest will not need it. So,
that gets me wondering, should I pass it in as a parameter?
No. In fact, if the database connection is only needed by one of the implementers then it doesn't sound like it belongs in the interface at all. The interface should represent the abstract API, where as it sounds as though the database connection is a part of the implementation of that API.
If it's not part of the abstraction -- then it shouldn't be in the interface. And if it's only used by 1 of 30 implementing classes, then it's definitely not part of the abstraction.
I did a quick google search for 'api design' and the first hit was:
slides of a presentation by Joshua Bloch.
His points that are relevant to your question:
"When in doubt leave it out"
'Don't let implementation details “leak” into API'
"API design is tough", but also, "API design is a noble and rewarding craft"
"Expect to make mistakes"
It sounds like you have a tough problem to solve -- but good luck!
It sounds like you are following implementation driven design as opposed to use case driven one. You'll be able to answer some of these questions yourself by considering the perspective of the caller. I've got more details in this blog post:
http://theamiableapi.com/2011/08/29/considering-the-perspective-of-the-caller/
Cheers,
Ferenc
The constructor arguments to your various classes should be collaborators (or configuration values) used in processing. This is the how. These can vary for the 30 different implementations. If the database connection is required for some and not others, then only supply it as a constructor argument to one.
The interface then forms a basis for the processing should be done. This is the what.
You should strive for an interface where the API name, arguments and methods are at the same conceptual level. Constructor arguments are likely to be at a lower conceptual level.