Why factory method not taking parameter in GoF Factory Method - oop

In the Factory Method Design pattern of GoF, I can see that there is no parameter accepted by the FactoryMethod() method. My understanding is that the FactoryMethod should be passed a parameter that will be used in the switch case and then based upon the value in the switch case, different class objects are instantiated and returned back to the caller. My questions in summary are as follows:
1) Should I implement factory method pattern, exactly in the same way defined by GoF. I am also referring to UML diagram given at www.dofactory.com for Factory Method pattern).
2) Why is the factory method pattern of GoF not shown accepting parameter?

1) Should I implement factory method
pattern, exactly in the same way
defined by GoF. I am also referring to
UML diagram given at www.dofactory.com
for Factory Method pattern).
Do whatever makes sense to you. Patterns are just guidelines, not categorical laws of nature.
More than that, the patterns in GoF are not comprehensive. You'll find yourself discovering and implementing patterns which never appear in the book, nor even have a name. And that's a good thing.
2) Why is the factory method pattern
of GoF not shown accepting parameter?
The factory method pattern is simply a special instance of a derived class. In particular, you have an abstract class with an abstract method, and any number of derived classes which implement the method. Usually, this implemented method returns some other type of object -- this is what makes it a creational pattern.
So, using the sample on DoFactory.com, the classes return a canned set of objects. Nothing in principle prevents users from passing in some parameter to the factory method.
My understanding is that the
FactoryMethod should be passed a
parameter that will be used in the
switch case and then based upon the
value in the switch case, different
class objects are instantiated and
returned back to the caller.
You can certainly implement it that way if that makes sense to you.

2) Why is the factory method pattern
of GoF not shown accepting parameter?
In object-oriented programming, your methods should do one clearly-defined thing. Passing in some kind of value to switch on is called "alternate cohesion": instead the method should be into multiple methods, one for each case. For example:
createVeggie(veggieType)
would be split into
createBroccoli()
createCelery()
createCollaredGreens()
This makes your class interface cleaner, promotes easier modification, and improves compile-time checking.
Also, be careful that you are not violating Factory Method's intent: it is actually to avoid having calling code know which object is created. As Juliet says, you may implement something like this, but then it's no longer GoF Factory Method and does not have the same advantages.

Related

What's the difference between Factory Method implementations?

GoF book states that there are two ways to implement Factory Method:
Consider the following issues when applying the Factory Method pattern:
Two major varieties. The two main variations of the Factory Method pattern are the case when the Creator class is an abstract
class and does not provide an implementation for the factory method it
declares, and the case when the Creator is a concrete class and
provides a default implementation for the factory method. It’s also
possible to have an abstract class that defines a default
implementation, but this is less common. The first case requires
subclasses to define an implementation, because there’s no reasonable
default. It gets around the dilemma of having to instantiate
unforeseeable classes. In the second case, the concrete Creator uses
the factory method primarily for flexibility. It’s following a rule
that says, “Create objects in a separate operation so that subclasses
can override the way they’re created.” This rule ensures that
designers of subclasses can change the class of objects their parent
class instantiates if necessary.
Parameterized factory methods. Another variation on the pattern lets the factory method create multiple kinds of products. The factory
method takes a parameter that identifies the kind of object to create.
All objects the factory method creates will share the Product
interface. In the Document example, Application might support
different kinds of Documents. You pass CreateDocument an extra
parameter to specify the kind of document to create.
Design Patterns (Design Patterns: Elements of Reusable Object-Oriented Software)
In what cases should I use one approach instead of another. What the benefits and drawbacks when I prefer one approach instead of another?
Thanks in advance.
Kudos for reading the book. Most people attempt #2 believing that is the Factory Method pattern, when in fact #1 claims to describe the two major varieties.
So we're actually dealing with three slightly different versions of the pattern in the quoted text, though only two of them are numbered. The differences between these versions are based on how much information the Creator has about which Product implementation it wants.
A Creator with an abstract Factory Method knows nothing about the Product implementation and leaves everything up to the ConcreteCreator.
A Creator with a default Factory Method knows what Product implementation it wants most of the time, but not always; so it allows a ConcreteCreator to override the default.
A Creator with a parameterized Factory Method has a menu of Product implementations to choose from and decides which one to ask the ConcreteCreator for.
So in each consecutive version, the Creator has progressively more information about the Product implementations and more logic concerning how the implementation is chosen.
In the Factory Method pattern, a Creator delegates responsibility for creating objects to its child classes because it, "can't anticipate the class of objects it must create." (page 108) Based on the different varieties, we can see how the pattern changes slightly when a Creator can anticipate some information about the class of objects to create.
The version you choose depends on how much you know about the Product implementations at compile time.

Singleton toolbox vs factory method

Apparently, singletons are bad, and a factory method is recommended. I'm wondering if a singleton toolbox is any better than a singleton.
In my opinion, It's really weak to think that singletons are bad,factory methods are good.
Each of them has preferences. As consequence, I'm sure that there is misunderstanding here.
I know that wikipedia is not the best source. But check out the definition of them. The range of situations are not the same for these patterns.
In software engineering, the singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects. The term comes from the mathematical concept of a singleton.
In class-based programming, the factory method pattern is a creational pattern which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor.

Doesn't the Factory pattern, violate the "Tell, Don't Ask" principle?

Procedural code gets information then makes decisions. Object-oriented code tells objects to do things.
Alec Sharp
When we are using the Factory pattern, we make decision, based on a property of a class except than the factory class, so this, doesn't violate Tell, Don't Ask principle?
No, we don't violate.
When we tell the Factory class to create an object instance, all the responsibility is within the Factory class. The caller has no influence what the concrete class will be.
The Factory class itself also doesn't break that rule. It is doing what it has to do: based on the given rules (let it be hard-coded or externally set, or maybe something more complex) decides what kind of object to generate. But every bit of the logic is inside the factory method.

OO principle: c#: design to interface and not concrete classes

I have some questions about the affects of using concrete classes and interfaces.
Say some chunk of code (call it chunkCode) uses concrete class A. Would I have to re-compile chunkCode if:
I add some new public methods to A? If so, isn't that a bit stange? After all I still provide the interface chunkCode relies on. (Or do I have to re-compile because chunkCode may never know otherwise that this is true and I haven't omitted some API)
I add some new private methods to A?
I add a new public field to A?
I add a new private field to A?
Factory Design Pattern:
The main code doesn't care what the concrete type of the object is. It relies only on the API. But what would you do if there are few methods which are relevant to only one concrete type? This type implements the interface but adds some more public methods? Would you use some if (A is type1) statements (or the like) the main code?
Thanks for any clarification
1) Compiling is not an activity in OO. It is a detail of specific OO implementations. If you want an answer for a specific implementation (e.g. Java), then you need to clarify.
In general, some would say that adding to an interface is not considered a breaking change, wheras others say you cannot change an interface once it is published, and you have to create a new interface.
Edit: You specified C#, so check out this question regarding breaking changes in .Net. I don't want to do that answer a disservice, so I won't try to replicate it here.
2) People often hack their designs to do this, but it is a sign that you have a poor design.
Good alternatives:
Create a method in your interface that allows you to invoke the custom behavior, but not be required to know what that behavior is.
Create an additional interface (and a new factory) that supports the new methods. The new interface does not have to inherit the old interface, but it can if it makes sense (if an is-a relationship can be expressed between the interfaces).
If your language supports it, use the Abstract Factory pattern, and take advantage of Covariant Return Types in the concrete factory. If you need a specific derived type, accept a concrete factory instead of an abstract one.
Bad alternatives (anti-patterns):
Adding a method to the interface that does nothing in other derived classed.
Throwing an exception in a method that doesn't make sense for your derived class.
Adding query methods to the interface that tell the user if they can call a certain method.
Unless the method name is generic enough that the user wouldn't expect it to do anything (e.g. DoExtraProcessing), then adding a method that is no-op in most derived classes breaks the contract defined by that interface.
E.g.: Someone invoking bird.Fly() would expect it to actually do something. We know that chickens can't fly. So either a Chicken isn't a Bird, or Birds don't Fly.
Adding query methods is a poor work-around for this. E.g. Adding a boolean CanFly() method or property in your interface. So is throwing an exception. Neither of them get around the fact that the type simply isn't substitutable. Check out the Liskov Substitution Principle (LSP).
For your first question the answer is NO for all your points. If it would be that way then backward compatibility would not make any sense. You have to recompile chunkCode only if you brake the API, that is remove some functionality that chunkCode is using, changing calling conventions, modifying number of parameters, these sort of things == breaking changes.
For the second I usually, but only if I really have to, use dynamic_cast in those situations.
Note my answer is valid in the context of C++;I just saw the question is language agnostic(kind of tired at this hour; I'll remove the answer if it offenses anybody).
Question 1: Depends on what language you are talking about. Its always safer to recompile both languages though. Mostly because chuckCode does not know what actually exists inside A. Recompiling refreshes its memory. But it should work in Java without recompiling.
Question 2: No. The entire point of writing a Factory is to get rid of if(A is type1). These if statements are terrible from maintenance perspective.
Factory is designed to build objects of similar type. If you are having a situation where you are using this statement then that object is either not a similar type to rest of the classes. If you are sure it is of similar type and have similar interfaces. I would write an extra function in all the concrete base classes and implement it only on this one.
Ideally All these concrete classes should have a common abstract base class or a Interface to define what the API is. Nothing other than what is designed in this Interface should be expected to be called anywhere in the code unless you are writing functions that takes this specific class.

When to use the abstract factory pattern?

I'm trying to succinctly describe when to use a factory, for both myself and my team. I ran across the following related questions, which helped somewhat:
When to use factory patterns?
(useful pdf link is broken)
How do you create your Factories?
(more 'how' rather than 'when')
What is your threshold to use factory instead of a constructor to create an object?
(some general answers)
Factory Pattern. When to use factory methods?
(more about factory methods than factory classes)
When to use Factory method pattern?
(again more about factory methods)
Based on these links, and a bunch of other sources (listed at the bottom), I've come up with the following:
When to use the abstract factory pattern:
when you use an interface var or the 'new' operator
e.g. User user = new ConcreteUserImpl();
and the code you are writing should be testable / extensible at some point
Explanation:
interfaces by their very nature imply multiple implementations (good for unit testing)
interface vars imply OCP- and LSP-compliant code (support sub-classing)
use of the 'new' operator breaks OCP/DI, because highly-coupled classes are hard to test or change
"Do I create a factory for every object type? That seems excessive."
no, you can have one (or a few) factories that produce a lot of (usually related) object types
e.g. appFactory.createUser(); appFactory.createCatalog(); etc.
When NOT to use a factory:
the new object is very simple and unlikely to be sub-classed
e.g. List list = new ArrayList();
the new object is not interesting to test
has no dependencies
performs no relevant or long-running work
e.g. Logger log = new SimpleLogger();
References:
http://googletesting.blogspot.com/2008/08/where-have-all-singletons-gone.html
http://misko.hevery.com/2008/07/08/how-to-think-about-the-new-operator/
http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/
http://en.wikipedia.org/wiki/Dependency_Injection
http://en.wikipedia.org/wiki/Open_Closed_Principle
http://en.wikipedia.org/wiki/Liskov_substitution_principle
My question is: is my summary accurate, and does it make sense? Is there anything I've overlooked?
Thanks in advance.
I'd also say don't use a factory when you have a particular implementation that you want. To continue the List example, I know that I want an ArrayList because I'm doing random access. I don't want to rely on a factory getting this right when I can do it myself.
Conversely, when I don't want to know about the concrete subclass then I can use a factory and let it worry about which object to actually instantiate.
I guess I'd suggest that you add a bullet to the "when to use the abstract factory pattern" that says "and you don't really care which concrete subclass you get", and the converse to "when not to use a factory".
EDIT: Be careful to avoid the general-purpose tool-building factory factory factory.
In general, use it when you want to be able to switch of implementation by external configuration.
JDBC and JAXP are excellent examples. For more examples, check this answer.
Abstract Factory pattern provides with a way to encapsulate concrete factories that share some commonality with each other, meaning they implement same interface/abstract class.
You need to use factory pattern whenever you want to control the initialization of your objects, instead of giving the control to the consumer.