What is use cases for use (1),(2),(3). What is pro & cons to use it. What is difference between them?
Factory Method pattern
This pattern is very similar to the Factory Pattern, the client also asks the Factory for a specific type of object from a class hierarchy but the Create method of the factory class delegates the creation of the specific object to the derived classes and return the object of the class of the type asked by client. In essence, you have a single point of contact for the creation of several objects of a class hierarchy.
You can think of this as going to a airline ticket counter (controller) and asking for a ticket by giving your preference of the ticket type (first class, executive or economy). The user is not concerned with how the ticket is being generated, even though in an object representation the first class and the economy ticket are both derived from the base ticket class.
When to use
Flexibility is important (low coupling)
Objects can be extended in subclasses
There is a specific reason why one subclass would be chosen over another—this logic forms part of the Factory Method.
A client delegates responsibilities to subclasses in parallel hierarchies.
Factory pattern or Simple Factory Pattern
This pattern is very similar to the Factory method pattern. But unlike a factory method pattern, this pattern is a bit simpler. Instead of delegating the creation to the subclasses, the Create method of the Factory itself creates the instance of the required type and returns it.
Builder Pattern
In the builder pattern, the complex task of creation of objects is encapsulated in a class or method. For example, consider the case of ordering a meal at a fast food counter. The meal would typically consists of a burger, fries and a drink. Each item in the meal has its own creation process. Rather than the customer having to deal with the creation process of each item, this task is handled by the counter where one orders the meal. When the order is placed, the person as the counter takes charge of creating the meal that consists of the three items and returns the items as a single instance of a meal to the customer.
While another customer may ask for a meal that comes with large fries and diet coke. Again, the person at the order counter is responsible for building the order that was different than the first one. From the point of view of the customer, the order is always placed and the counter, which is followed by the meal being returned.
When to use
Construction of the object is not a simple task
Sub parts make up each object
There is a need for more than one kind of (with differencing sub-part in it) end-object is to be demanded by the client. This demand for differing end-objects may happen, if not at the same time, at least at different points of time.
More information
Design Patterns: Abstract Factory vs Factory Method
Questions about the Prototype Pattern
Builder Pattern vs Factory Pattern
Creational Patterns
Creational Design Patterns
Related
I'm currently designing the domain for a reservation system meant for 2 types of reservations.
Both of these types have common properties, such as their date and location. Both also have properties which the other does not, though. Examples here are in one type you can bring along guests, and not with the other; or you can request lunch for one type, and not the other.
Currently I have an abstract Reservation class, with a concrete implementations per type of reservation. I then have a ReservationBuilder which takes an enum (reservation type) as argument in its constructor. This builder would then contain methods for both types of reservations, and using a method for a type of reservation that cannot use the information would either do nothing when built, or throw an error.
Something tells me that this isn't a good use of this pattern, though. Would it be better to abstract the builder too? Or would a factory pattern better suit my use case?
You have identified the need for an abstract superclass, Reservation. You have also identified the need for specialization in child classes, like GroupReservation, RoomServiceReservation.
What is the motivation for using a builder or factory pattern? If the problem is to create a new instance of a class given a string, a few if statements or a case statement would work fine.
if(userSelection.equals("group")) {
return new GroupReservation();
}
If the motivation is for something more complex, a builder or factory class might be useful. The messy details of selecting and instantiating a concrete class can be hidden that way.
Object-oriented programmers can unwittingly wear "pattern goggles". When we wear pattern goggles, we approach every design choice looking for just the right pattern to implement. Sometimes there is a language feature we can use that eliminates the need for a pattern. And sometimes an if statement is good enough.
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.
I have a Product class that contains methods and a complex data structure. I will have 8 types of products that differ only in the contents of the data structure, nothing else. In my application I will then need to create one instance of each of the 8 types of product, once, and the types of products that exist do not change at run-time.
What is the best approach and why?
A) Class Product has 8 sub-classes. Each of these sub-classes defines only the constructor. Inside each constructor the data structure is properly created for that type of product.
B) A Factory class has 8 sub-classes. Each of these sub-classes is a concrete factory for each of the 8 types of products. Class Product has no sub-classes. Each concrete factory creates the specific type of product by creating the appropriate data structure and passing it as an argument to the constructor of class Product.
I have been reviewing the advantages of the Factory design pattern and I can't see, for this specific case, any of those advantages in B over A. Am I missing something?
I would go with a variation of A, plus perhaps a factory class. A factory is meant to create classes with methods defined in an interface class, such that the consumer of the factory-created object doesn't know what type of object they are dealing with, but only the interface. The factory itself knows what type of object to create.
If there is a certain type of logic for what type of Product to create at a given time, implement a factory for 8 Products that implement an IProduct interface, and implement the logic for what type of product to create inside the factory.
I believe in Factory design pattern you can create objects of different subclasses from a single factory. See following example-
According to me using subclass approach with the factory design pattern would be a better option for the mentioned scenario.
You have mentioned - I will have 8 types of products that differ only in the contents of the data structure, nothing else.... That means state and methods are same with different contents. Based on that I feel this is clear indication that these are not subclasses but instances of same class. I think the code will contain only one product class and 8 instances of those. Factory is absolutely not required it will be unnecessary code.
How many abstract function declaration of an Abstract class is too many?
For example, for a membership based payment system :
Multiple payment modes are supported :
Credit Card
Token (a Credit Card payment but using a token)
Redirect (i.e Paypal)
Manual (admin charging manually the user)
I have an abstract class PaymentMode and different modes above extend to this class.
Each mode has its own unique logic of the methods below and i have to declare abstract methods in PaymentMode class for these
// each mode has own way of validating the customer data
validate();
// own logic of cleaning customer data (e.g removing/adding/updating)
preparePaymentData();
// returns a string for saving in database, subclass must implement so developers plan to extend the PaymentMode abstract will be forced to return the correct value
getModeOfPayment();
// each mode has its own logic when determining payment gateways to attempt
getGatewaysToAttempt();
// before sending the payment to gateway, each mode has its own logic when adding specific data
addCustomDataSpecificForGateway();
// check if transaction has failed, different payment modes has different logic of determining a failed transaction
isTransactionFailed()
There 6 unique logic for each mode, I've managed to commonized the common codes already and put it inside the PaymentMode class.
This number may grow as we implement new features that is unique to each mode.
In my mind, im concerned that if any future developer extends my PaymentMode class, he has to implement all the abstract function declarations.
So does a large number of abstract function declarations an indication of a BAD DESIGN? How much is too many?
If its a bad design then, can you recommend any techniques or Design Patterns that will solve this issue
Thanks
It's hard to answer without specifics, but:
Obviously there is no hard limit on abstract methods (methods in interfaces or abstract classes), although less is always clearer and easier to understand.
What is indicating a suboptimal design however is that you need to modify your abstraction of a payment method with each new payment method. That to me indicates a failing abstraction. OOP is not just about pulling common code out, avoiding duplication, it is about abstractions also.
What I would look into is to somehow transfer the control (the real control) to the payment method. Trust the payment method, delegate the task of making the payment to it.
What I mean by that is, you retain control somewhere, where you ask the payment method to do specific parts of its job (with the parts being different for different concrete methods). Steps like validate(), prepare...(). And also, you expect it to give you the "gateway", so now code outside the payment method (even if it's the superclass) must know what that is, or how to handle it.
Instead of doing all that, try to come up with a design, that transfers full control over to the payment method, so it can do it's job without outside code assuming any particular set of steps.
For example:
public interface PaymentMethod {
Receipt payFor(Bill bill);
}
The PaymentMethod here is responsible for doing everything itself. Redirecting the user, saving the receipt in the database, whatever is needed. Once you feel comfortable with this "main" abstraction (it covers all use-cases), you can work to create smaller abstractions that cover details like saving to database, if it is the same for all methods.
In relation to that: don't use abstract parent classes as a way to share code between classes, that is not exactly what inheritance is for. Create proper abstractions for the different "pieces of code", and let them be used by "bigger" abstractions (i.e. composition).
There is no such number of abstract functions declarations that is BAD although the huge number could mean the design has flaws. Just pay attention to Single responsibility principle.
You have already defined that you have 4 modes - so i think you should do 4 interfaces for each mode in your case. After doing this you can see what is the common for all 4 of them and extract the base interface. You may consider to extract 6 unique logics for all of them also as interfaces...
I have the following health club scenario (coded in C++ BTW):
I want to create random Guest and Trainer objects (so both would have names randomly generated, but the guest would also have random health data).
I want to be able to make a lot of different random generators of differing complexities.
So clearly both would need the random forename/surname generator functionality - but I'm not sure how I can keep this code in one place.
I could have an abstract factory with all generation methods (e.g. generateForename()) in it that all the objects that require random generation can use. But should a trainer have access to a factory that can generate health data even though it has nothing to do with them?
I also thought about having an abstract factory for each class - so one for person, one for customer, one for guest and have objects generate their superclasses by passing them the appropriate factory but that sounds over complex for the situation.
I am fairly new to this so forgive me if my design is a bit off.
What do you guys suggest?
I'm not sure an Abstract Factory is what you're looking for. An Abstract Factory works best when you have the same base class but you need to create different concrete instances. Although you have the root base class of Person, you actually need to create derivatives of two, different base classes.
I would endeavour to keep the methods that generate data together with the class that contains that data. This way it can be reused.
Could you create a factory method on Guest and Trainer that would then be able to use the methods in their respective base classes to generate the data? Maybe create test-specific sub-classes to keep test stuff away from real stuff?