participate


Patterns & OO Design - Problem understanding Factory Method Pattern
<<   Back to Forum  |   Give us Feedback
7 Duke Stars rewarded for this thread
This topic has 19 replies on 2 pages.    1 | 2 | Next »
minkey
Posts:14
Registered: 1/3/07
Problem understanding Factory Method Pattern   
Jul 1, 2007 5:13 AM

 
Hi All,

I am trying to understand Factory Method pattern from HF- Design pattern.

However i am unable to understand how Subclassing the PizzaStore is better than creating the invidiual region specific PizzaFactories.

The author gives an example of SimpleFactory and then creates region specific NYPizzaFactory and ChicagoPizzaFactory.

PizzaStore class is initialized with the necessary NYPizzaFactory/ChicagoPizzaFactory object and this code is as good as any thing i can think of. If necessary we can create more region specific pizza factories.

The Factory Method pattern makes us define a abstract parent class for which various subclasses provide implementation of factory method.

Honestly i am very much confused about the advantage of factory method pattern over the other approach.

Please help
 
jverd
Posts:51,815
Registered: 3/30/99
Re: Problem understanding Factory Method Pattern   
Jul 1, 2007 10:23 AM (reply 1 of 19)  (In reply to original post )

 
Perhaps you could write code that uses this factory approach, and then write the equivalent code that you think is just as good.
 
Kamal-Mettananda
Posts:35
Registered: 6/15/07
Re: Problem understanding Factory Method Pattern   
Jul 1, 2007 9:40 PM (reply 2 of 19)  (In reply to original post )

 
Honestly i am very much confused about the advantage of factory method pattern over the other approach.

Explain your question with more details.
 
minkey
Posts:14
Registered: 1/3/07
Re: Problem understanding Factory Method Pattern   
Jul 1, 2007 10:26 PM (reply 3 of 19)  (In reply to #2 )

 
Initial Scenario : We have a PizzaStore that creates different types of Pizza, Cheese, Veggie etc.

Since we can have many more varieties of pizzas in future, we can move the code for Pizza creation to Simple Factory class
public class PizzaStore {
           private SimplePizzaFactory factory;
            Public PizzaStore(SimplePizzaFactory factory) {
                  this.factory = factory;
            }
            public Pizza orderpizza(String pizzatype) {
                          Pizza pizza = factory.createpizza(pizzatype);
                          pizza.prepare();
                          pizza.bake();
                          pizza.box();
            }
}     

public class SimplePizzaFactory {
                  public Pizza createpizza(String pizzatype) {
                          Pizza pizza = null;
                          if(pizzatype.equals("veggie")) {
                                       pizza = new VeggiePizza();
                          }
                          else if(pizzatype.equals("cheese")){
                                       pizza = new CheesePizza();
                          }
                          return pizza;
                  }
}

public interface Pizza {
        public void prepare();
        public void bake();
        public void box();
}
 
public class VeggiePizza implements Pizza {
 //dummy code
}
public class CheesePizza implements Pizza {
 //dummy code
}

              public class Client1 {
                    public static void main(String[] args) {
                              SimplePizzaFactory factory  = new NYPizzaFactory();
                              PizzaStore store = new PizzaStore(factory);
                              Pizza pizza = store.orderpizza("veggie");
                    }
              }

Changed Scenario : We need to open regional branches for this PizzaStore, which will sell localized Pizzas, so we will have few more pizzas specific to the region like NYVegPizza, NYCheesePizza, ChicagoVegPizza, ChicagoCheesePizza and so on for various regions

APPROACH 1:- We can create region specific factory classes that will instantiate region specific pizzas, like NYPizzzaFactory creating NYVegPizza, NYCheesePizzas

We can continue to use the SAME PizzaStore class, just that each regional branch will initalize their respective PizzaStore with the region specific Factory

APPROACH 2: Use Factory Method Pattern

1. Create a Pizza Hierarchy : All Pizzas extend Pizza Interface
2. Define a abstract PizzaStore class with a abstract createpizza method
3. Define region subclasses for PIzzaStore that will create region specific code, basically holding the code similar to what NYPizzaFactory will be holding
          public abstract class PizzaStore {
                   public abstract Pizza createpizza(String pizzatype);
 
            public Pizza orderpizza(String pizzatype) {
                          Pizza pizza = createpizza(pizzatype);
                          pizza.prepare();
                          pizza.bake();
                          pizza.box();
            }
 
          }
 
public NYPizzaStore extends PizzaStore {
                 public Pizza createpizza(String pizzatype) {
                          Pizza pizza = null;
 
                         if(pizzatype.equals("veggie")) {
                                       pizza = new NYVegPizza();
                          }
                          else if(pizzatype.equals("cheese")){
                                       pizza = new NYCheesePizza();
                          }
                          return pizza;
                  }
} 
}
 

              public class Client2 {
                    public static void main(String[] args) {
                              PizzaStore store = new NYPizzaStore();
                              Pizza pizza = store.orderpizza("veggie");
                    }
              }
 


DOUBTS: - Both Client1 and Client2 is has to choose either NYPizzaStore / ChicagoPizzaStore and thus becomes tightly coupled to the PizzaStore object that we create here.

Which of the 2 approaches is better, creating region specific factories or subclasses of PizzaStore

What are the advantages and disadvantages of each approach?

I hope things will be more clear to you all now.

Looking forward to having a good discussion to appreciate this pattern
 
Kamal-Mettananda
Posts:35
Registered: 6/15/07
Re: Problem understanding Factory Method Pattern   
Jul 1, 2007 11:27 PM (reply 4 of 19)  (In reply to #3 )

 
Hi Minkey,

Now your question is very clear.

Here's the difference between two approaches.

Approach 1:
Separates the Pizza creation from the user of the pizza object.

Approach 1:
Combine the Pizza creator and the user of the pizza object.

Consider the following scenario. Some clients needs the pizza's ordered using method_1 while some needs method_2.

Order methods
method_1:

pizza.prepare();
pizza.bake();
pizza.box();

method_2:
pizza.prepare();
pizza.bake();
//order procedure changed 
pizza.doSomethingElseToo();
//yes, Pizza interface needs to have this new doSomethingElseToo() method
pizza.box(); 


Now think of how you can achieve this scenario with Approach 2.
One option:
Write two classes like NYPizzaStore and Meth2NYPizzaStore, which would double the number of classes. - not advisable

This order method is not related to any of the countries but depends on what the client requires.

Using Approach 1, you can sub class the PizzaStore easily for method_2.

public class Meth2PizzaStore {
           private SimplePizzaFactory factory;
            Public PizzaStore(SimplePizzaFactory factory) {
                  this.factory = factory;
            }
            public Pizza orderpizza(String pizzatype) {
                          Pizza pizza = factory.createpizza(pizzatype);
                          pizza.prepare();
                          pizza.bake();
                          pizza.doSomethingElseToo();
                          pizza.box();
            }
}  


public class Client3 {
                    public static void main(String[] args) {
                              SimplePizzaFactory factory  = new NYPizzaFactory();
                              PizzaStore store = new Meth2PizzaStore(factory);
                              Pizza pizza = store.orderpizza("veggie");
                    }
              }


So user and creator are decoupled in Approach 1.

HTH.
 
minkey
Posts:14
Registered: 1/3/07
Re: Problem understanding Factory Method Pattern   
Jul 2, 2007 9:28 PM (reply 5 of 19)  (In reply to #4 )

 
Hi Kamal,

Thanks for your reply.

I have taken this example from Head First- Design patterns book.

Assuming the Pizza interface does not change as suggested by you. The only thing that can change is the type of pizza, i.e. new varities of pizza can get added like ChickenPizza, etc.

The question here is which approach is better for instantiating objects, Approach 1 or Approach 2.

Author seems to suggest that Approach 2 is better as it creates a framework sort of a thing.

Please advice

regards
 
Kamal-Mettananda
Posts:35
Registered: 6/15/07
Re: Problem understanding Factory Method Pattern   
Jul 2, 2007 10:10 PM (reply 6 of 19)  (In reply to #5 )

 
Hi Minkey,

(Yes, this was from HFDP Factory chapter). There's no way that we can guarantee this Pizza interface is not going to change in future. So when I design is done, we should assume that these can happen and apply what would help you most in maintaining the code. So as I explained in the previous post, approach 2 is better in terms of decoupling. Why shouldn't we choose the better one?

Even if you think there's no change in the Pizza interface, what if a need arises for changing the way the pizza is ordered.

So I suggest, it's better to think in terms of maintainability of the system.

Kamal
My blog: http://lkamal.blogspot.com
 
minkey
Posts:14
Registered: 1/3/07
Re: Problem understanding Factory Method Pattern   
Jul 2, 2007 11:42 PM (reply 7 of 19)  (In reply to #6 )

 
Hi Kamal,

I am still not able to understand this.

As per my understanding, the example you have provided seems to suggest Approach 1 (used with SimpleFactory) is better

Moreover as the book HF-Design Patterns suggest, the trade-off is for the better approach for creating objects.

Although you point is really valid from the point of view of future changes in order() method.

Many thanks for your help
 
Kamal-Mettananda
Posts:35
Registered: 6/15/07
Re: Problem understanding Factory Method Pattern   
Jul 3, 2007 12:20 AM (reply 8 of 19)  (In reply to #7 )

 
Hi Minkey,

Ok, so you want to think in terms of 'no changes to order operations and only the change would be to create method'.

If that is guaranteed, then there's no need for separating the creator and user. Then you can choose one from the two approaches that they have provided in the book.

But still there's a saying, "favor composition over inheritance". So still Approach 2 wins over 1.

Whole point in Factory Method is to separate the object creation from the user (class or method) so that the changes in the creation would not affect the user. So that's why a SimpleFactory method or a sub class should instantiate.

Why should we integrate and couple features that could be easily separated?

Regards,
Kamal
Blog: http://lkamal.blogspot.com
 
minkey
Posts:14
Registered: 1/3/07
Re: Problem understanding Factory Method Pattern   
Jul 3, 2007 1:01 AM (reply 9 of 19)  (In reply to #8 )

 
Hi Kamal,
Thanks a lot for your patience, help and sparing your precious time.

I think we are getting close to an agreement.

However, as i understand from your 2nd reply,

Approach 1: Create SimpleFactory or region specific factories like NYPizzaFactory, ChicagoPizzaFactory

There will be a single PIzzaStore class. Which will hold reference to the SimpleFactory object.

Approach 1 involves Composition.

Approach 2: Also called Factory Method Pattern. Define a abstract PizzaStore with a abstract create method and implementation of create method will be given by subclasses of the PizzaStore like NYPizzaStore, ChicagoPizzaStore.

Approach 2 involves Inheritance

So as you pointed out "favor composition over inheritance".

That way Approach 1 should be better than Approach 2.

Approach 1 ensures that object creation is encapsulated in a different class.


Moreover, please can you clarify on the point, "
Whole point in Factory Method is to separate the object creation from the user (class or method) so that the changes in the creation would not affect the user. "

In case i move object instantiation to a separate class like SimpleFactory class, i can simply add new object (Pizzas like ChickenPizza etc.) to create() of SimplePizzaFactory.

It should not effect the client?

Please clarify

thanks & regards
 
Kamal-Mettananda
Posts:35
Registered: 6/15/07
Re: Problem understanding Factory Method Pattern      
Jul 3, 2007 2:48 AM (reply 10 of 19)  (In reply to #9 )

 
Hi Minkey,

Extremely sorry, I had made a mistake in last 2 posts by mixing the two words, Apprach 1 and Approach 2.

Let me tell it again.

Approach 1:
This decouples creator from user - composition

Approach 2:
Couples creator and user - inheritance

I was trying to tell that approach 1 is better than 2. (This time correctly said).

The scenario I said previously was also favored approach 1.

If 'no changes to order operations and only the change would be to create method'. - the both match the requirement. But still I would favor approach 1 due to composition.

Your examples:
eg 1. Uses a simple factory to create Pizza but the subclasses of the simple factory decides what to instantiate. So this is also a similar to Factory pattern, but does not have a factory method.

eg 2. Uses a Factory method (PizzaStore) and subclasses decide what to instantiate.

Factory method pattern - delegate the instantiation to sub classes, but knows what to do with the created object
Simple factory - decide and instantiate, has no idea what to do with the created object.

So the 2nd example (Factory method), can be considered as a framework for ordering Pizzas while the first is also used for the same purpose, but in a different manner.

BR,
Kamal
 
minkey
Posts:14
Registered: 1/3/07
Re: Problem understanding Factory Method Pattern   
Jul 4, 2007 1:25 AM (reply 11 of 19)  (In reply to #10 )

 
Hi Kamal,

Thanks for the clarification. Awarding you the points now.

regards
 
Kamal-Mettananda
Posts:35
Registered: 6/15/07
Re: Problem understanding Factory Method Pattern   
Jul 4, 2007 1:31 AM (reply 12 of 19)  (In reply to #11 )

 
Always welcome. Thanks.
 
abhinav21
Posts:54
Registered: 3/1/02
Re: Problem understanding Factory Method Pattern   
Aug 30, 2007 11:37 PM (reply 13 of 19)  (In reply to original post )

 
It also took me a while to grasp it. Here is how I would explain it -
http://techblog.abhinavsrivastava.com/2007/08/factory-pattern.html
 
andy_jammy
Posts:1
Registered: 2/22/07
Re: Problem understanding Factory Method Pattern   
Oct 30, 2007 10:44 AM (reply 14 of 19)  (In reply to #12 )

 
I undersand that this is an old topic, and you have concluded it.

but here is my question:

If we need a call like pizza.doSomething() wouldnt we choose approach 2 as we "doSomething" in NY and not in Chicago?

on the other hand, if we need an entirely new pizza type, like a chicken, then approach 1 would be preferred, since we are choosing composition over inheritance.

Would that be right?

Andy
 
This topic has 19 replies on 2 pages.    1 | 2 | Next »
Back to Forum
 
Read the Developer Forums Code of Conduct

Click to email this message Email this Topic

Edit this Topic
  
 
 
Forums Statistics
    Users Online : 25
  • Guests : 136

About Sun forums
  • Sun Forums is a large collection of user generated discussions. It is here to help you ask questions, find answers, and participate in discussions.

    Check out our guide on Getting started with Sun Forums for a full walkthrough of how to best leverage the benefits of this community.

Powered by Jive Forums