设计模式之工厂模式1-学习笔记

一、定义

工厂方法模式:定义了一个创建对象的借口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

模式组成元素:

创建者(Creator)类:

  1. 创建抽象创建者类,定了一个抽象的工厂方法,让子类实现此方法而制造产品。
  2. 创建者通常会包含依赖于抽象产品的代码,而这些抽象产品由子类创造。创建者不需要真的知道在制造哪种具体产品。

产品类:

  1. 创建抽象产品类,所有产品必须实现公共接口

二、疑惑

 

三、实现

import java.util.ArrayList;;
public abstract class Pizza {
	String name;
	String dough;  //dough 生面团
	String sauce; //sauce 酱油
	ArrayList toppings = new ArrayList(); //topping 糕点上的装饰配料
	void prepare(){
		System.out.println("Preparing "+ name);
		System.out.println("Tossing dough...");
		System.out.println("Adding sauce...");
		System.out.println("Adding toppings:");
		for(int i=0;i<toppings.size();i++){
			System.out.println("   "+toppings.get(i));
		}
	}
	void bake(){
		System.out.println("Bake for 25 minutes at 350");
	}
	
	void cut(){
		System.out.println("Cutting the pizza into diagonal slices");
	}
	
	void box(){
		System.out.println("Place pizza in official PizzaStore box");
	}
	public String getName(){
		return name;
	}
}

public abstract class PizzaStore {
	public Pizza orderPizza(String type){
		Pizza pizza;
		pizza = createPizza(type);
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		return pizza;
	}
	abstract Pizza createPizza(String type); //实现了实际制造产品
}

public class NYPizzaStore extends PizzaStore{
	Pizza createPizza(String item){
		if(item.equals("cheese")){
			return new NYStyleCheesePizza();
		}
		else return null;
	}
}

public class ChicagoPizzaStore  extends PizzaStore{
	Pizza createPizza(String item)
	{
		if(item=="cheese")
			return new ChicagoStyleCheesePizza();
		else
			return null;
	}
}


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

}

public class ChicagoStyleCheesePizza extends Pizza{
	public ChicagoStyleCheesePizza(){
		name = "Chicago Style Deep Dish Cheese Pizza"; //
		dough = "Extra Thick Crust Dougn"; //厚饼
		sauce = "Plum Tomato Sauce";
		
		toppings.add("Shredded Mozzarella Cheese");
	}
	void cut(){ //覆盖cut()方法
		System.out.println("Cutting the pizza into square slices");
	}
}

public class PizzaTestDrive {
	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");
	}
	
}

输出

Preparing NY Style Sauce and Cheese Pizza
Tossing dough…
Adding sauce…
Adding toppings:
Grated Reggiano Cheese
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Ethan ordered a NY Style Sauce and Cheese Pizza

Preparing Chicago Style Deep Dish Cheese Pizza
Tossing dough…
Adding sauce…
Adding toppings:
Shredded Mozzarella Cheese
Bake for 25 minutes at 350
Cutting the pizza into square slices
Place pizza in official PizzaStore box
Joel ordered a Chicago Style Deep Dish Cheese Pizza

四、依赖倒置原则

1、定义

不能让高层组件依赖于底层组件,而且,不关高层或底层组件,两者都应该依赖于抽象

2、设计原则

  • 要依赖于抽象,而不依赖于具体类
  • 变量不可以持有具体类的引用(如果new,就会持有具体类的引用)
  • 不要让类派生子具体类(如果派生自具体类,就会依赖于具体类。要派生自抽象(接口或抽象类))
  • 不要覆盖基类中以实现的方法(如果基类已实现方法,那么基类就不是一个真正适合被继承的抽象。基类中以实现的方法,应该让子类共享)

3、实例分析

高层组件(PizzaStore)和底层组件(即Pizza)都依赖于Pizza抽象。想要遵循依赖倒置原则,工厂方法并非是唯一技巧,但确实最好用的技巧之一。

4、理解

  • 倒置,指别从顶端(工厂)开始思考设计,而是从底层(Pizza)开始。

四、总结