Factory Method

Hyung Jun·2020년 12월 6일
0

Design Pattern

목록 보기
10/10
post-thumbnail

This article is lecture note from "Head First Design Patterns" by Elisabeth Freeman and Kathy Sierra and CS course from Kookmin by Inkyu Kim

Definition

The Factory Method Pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

Structure

The Product declares the interface, which is common to all objects that can be produced by the creator and its subclasses.
Concrete Products are different implementations of the product interface. The Creator class declares the factory method that returns new product objects. It's important that the return type of this method matches the product interface. We can declare the factory method as abstract to force all subclasses to implement their own versions of the method. As an alternative, the base factory method can return some default product type.
Concrete Creators override the base factory method so it returns a different type of product. Note that the factory method doesn't have to create new instances all the time. It can also return existing objects from a cache, an object pool, or another source.

Source Code

<PizzaStore.java>

public abstract class PizzaStore {
 
	abstract Pizza createPizza(String item);
 
	public Pizza orderPizza(String type) {
		Pizza pizza = createPizza(type);
		System.out.println("--- Making a " + pizza.getName() + " ---");
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		return pizza;
	}
}

This is our abstract creator class. It defines an abstract factory method that the subclasses implement to produce products. Often the creator contains code that depends on an abstract product, which is produced by a subclass. The creator never really knows which concrete product was produced.
Let's look at our product.
<Pizza.java>

import java.util.ArrayList;

public abstract class Pizza {
	String name;
	String dough;
	String sauce;
	ArrayList<String> toppings = new ArrayList<String>();
 
	void prepare() {
		System.out.println("Prepare " + name);
		System.out.println("Tossing dough...");
		System.out.println("Adding sauce...");
		System.out.println("Adding toppings: ");
		for (String topping : toppings) {
			System.out.println("   " + topping);
		}
	}
  
	void bake() {
		System.out.println("Bake for 25 minutes at 350");
	}
 
	void cut() {
		System.out.println("Cut the pizza into diagonal slices");
	}
  
	void box() {
		System.out.println("Place pizza in official PizzaStore box");
	}
 
	public String getName() {
		return name;
	}

	public String toString() {
		//code here
		}
		return display.toString();
	}
}

Then here is one of our concrete creator, NewYork style pizza store~
<NYPizzaStore.java>

public class NYPizzaStore extends PizzaStore {

	Pizza createPizza(String item) {
		if (item.equals("cheese")) {
			return new NYStyleCheesePizza();
		} else if (item.equals("veggie")) {
			return new NYStyleVeggiePizza();
		} else if (item.equals("clam")) {
			return new NYStyleClamPizza();
		} else if (item.equals("pepperoni")) {
			return new NYStylePepperoniPizza();
		} else return null;
	}
}

The createPizza() method is our factory method. It produces products.

<NYStyleCheesePizza.java>

public class NYStyleCheesePizza extends Pizza {

	public NYStyleCheesePizza() { 
		name = "NY Style Sauce and Cheese Pizza";
		dough = "Thin Crust Dough";
		sauce = "Marinara Sauce";
 
		toppings.add("Grated Reggiano Cheese");
	}
}

<PizzaTestDrive.java>

 
	public static void main(String[] args) {
		PizzaStore nyStore = new NYPizzaStore();
		PizzaStore chicagoStore = new ChicagoPizzaStore();
 
		Pizza pizza = nyStore.orderPizza("cheese");
		System.out.println("Ethan ordered a " + pizza.getName() + "\n");
 
		pizza = chicagoStore.orderPizza("cheese");
		System.out.println("Joel ordered a " + pizza.getName() + "\n");

		// other codes here
	}
}

Parallel Class Hierarchies

The Product classes and Creator classes both have abstract classes that are extended by concrete creators which know about specific implementation for each concrete products.

Why is it good? 🧐

The Factory Method is useful when you don't know the exact types and dependencies of the objects your code should work with. This pattern separates product construction code from the code that actually usees the product. Therefore it's easier to extend the product construction code independently from the rest of the code.
Secondly, it is used when you want to provide users of your library of framework with a way to extend its internal components. Inheritance is probably the easiest way to extend the default behaviour of a library or framework. But how would the framework recognise that your subclass should be used instead of a standard component?
The Solution is to reduce the code that constructs components across the framework into a single factory method and let anyone override this method in addition to extending the component itself.
For example, imagine that you write an ap using an open source UI framework. Your app should have round buttons, but the framework only provides square ones. You extend the standard Button class with a glorious RoundButton subclass. But now you need to tell the main UIFramework class to use the new button subclass instead of a default one.
To achieve this, you create a subclass UIWithRoundButtons from a base framework class and override its createButton method. While this method returns Button objects in the base class, you make your subclass return RoundButton objects. Now use the UIWithRoundButtons class instead of UIFramework.

By using Factory Method you avoid tight coupling between the creator adn the concrete products. Also, you can achieve Single Responsibility Principle. You can move the product creation code into one place in the program, making the code easier to support. Last, Open Closed Principle. You can introduce new types of products into the program without breaking existing client code.

profile
Keep Learning👨🏻‍💻

1개의 댓글

comment-user-thumbnail
2024년 1월 23일

Découvrez la grandeur de hawa expo 2024, la vitrine ultime du mobilier vietnamien du 6 au 9 mars au Centre des congrès et des expositions de Saigon, à Hô Chi Minh-Ville. Au-delà d'une exposition, c'est une vitrine puissante d'une industrie en plein essor. Avec 700 exposants, ce salon sur le thème du vintage célèbre le dynamisme et la diversité du secteur du meuble vietnamien. Plongez dans l'innovation et le style, marquant un événement incontournable pour les amateurs de meubles et les professionnels de l'industrie.

답글 달기