Java设计模式:工厂模式学习与分析

1. 为什么需要工厂模式

1.初始化对象经常造成耦合问题,因为当使用“new”时,用的是实现,而不是接口
(设计原则:针对接口编程,不针对实现编程)
2.工厂处理创建对象的环节。

public abstract class PizzaStore {
	
	public Pizza orderPizza(String type) {
		Pizza pizza;
		//creatPizza()方法从工厂对象移回PizzaStore
		pizza = creatPizza(type);
				
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		
		return pizza;
	}	
	//将工厂对象移到这个方法中
	 public abstract Pizza creatPizza(String type);
}

4.将一个orderPizza()方法和一个工厂方法联和起来,就可以成为一个框架。
5.加盟店可以从PizzaStore免费取得所有的功能,只需要继承PizzaStore就可以了。
6.对象组合可以在运行时动态改变行为,这样可以更换不同的实现。

2.正确的做法

1.将实例化具体类的代码从应用中抽离,或者封装起来,是它们不会干扰应用的其他部分。(剥离变化的部分)
2.Pizza pizza = new Pizza();为了让系统有弹性,Pizza应该为一个抽象类或者接口
3.让每个域类型(各个子加盟店)都继承上面这个PizzaStore模板,由各个加盟店决定如何制作Pizza。
4.每个子类都有自己的披萨变体,而仍然适合PizzaStore框架。并使用调试好的orderPizza()方法。
5.由于PizzaStore是抽象的,orderPizza()并不知道哪些实际的具体类参与进来了,这就是解耦
6.将一个orderPizza()方法和一个工厂方法联和起来,就可以成为一个框架。

3.工厂模式

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

将创建对象的代码集中在一个对象或方法中,可以避免代码中的重复,且更方便以后的维护。这样客户实例化对象时,只会依赖于接口,而不是具体类。这可以帮助我们针对接口编程,而不是针对实现编程

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指出具体类。

4. 举例

美国一家Pizza连锁店设计一套系统,为自己的加盟商设计订餐系统。有如下特点:
1.每个连锁店的菜单有区别,比如都输入“Cheese”,每个连锁店的CheesePizza就不一样。
2.每个连锁店的原料有区别,比如都输入“Suger”,每个连锁店Suger做法就不一样。

下面是具体测试的代码,先从这里分析:
在这里插入图片描述

方法执行的链条:
在这里插入图片描述
类的继承和依赖:
在这里插入图片描述

类的依赖分析:
在这里插入图片描述

5.具体代码

代码有点多,就不全贴在这里了。下面只贴部分主要代码:


public class PizzaTestDrive {
	
	public static void main(String args[]) {
		PizzaStore nyStore = new NYPizzaStore();
		//PizzaStore chicagoStore = new ChicagoPizzaStore();
		
		Pizza pizza = nyStore.orderPizza("cheese");
		//orderPizza() -> NYPizzaStore.creatPizza() -> CheesePizza() -》 prepare() -》ingredientFactory.createDough()等
		System.out.println("Ethan ordered a " +pizza.getName() + "\n");
		
//		pizza = chicagoStore.orderPizza("cheese");
//		System.out.println("Forever ordered a " +pizza.getName() + "\n");
		
	}

}

public abstract class PizzaStore {
	
	public Pizza orderPizza(String type) {
		Pizza pizza;
		//creatPizza()方法从工厂对象移回PizzaStore
		pizza = creatPizza(type);
		
		//CheesePizza(ingredientFactory)里面重写了prepare()方法
		/*
		 * 
    	public class CheesePizza extends Pizza{
		PizzaIngredientFactory ingredientFactory;
	
		public CheesePizza(PizzaIngredientFactory ingredientFactory) {
			this.ingredientFactory = ingredientFactory;
		}
	
		protected void prepare() {
			System.out.println("Preparing  " + name);
			dough = ingredientFactory.createDough();
			sauce = ingredientFactory.createSauce();
			cheese = ingredientFactory.createcheese();
			}

		}
		 */
		
		
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		
		return pizza;
	}	
	//将工厂对象移到这个方法中
	 public abstract Pizza creatPizza(String type);
}

package BasePackage;
import java.util.ArrayList;

public abstract class Pizza {
	
	public String name;		    //名称
	//public String dough;        //面团类型
	//public String sauce;	 	//作料
	
	protected Dough dough;
	protected Sauce sauce;
	Veggies veggies[];
	protected Cheese cheese;
	Pepperoni pepperoni;
	Clams clam;
	
	public ArrayList<String> toppings = new ArrayList<String>();
	
	//提供某些默认的基本做法,包括烘焙、切片和装盒
	protected void prepare() {
		System.out.println("Preparing "+name);
		System.out.println("Tossing dough... ");
		System.out.println("Adding sauce...");
		System.out.println("Adding topings:");
		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 pizze into diagonal slices.");
	}
	
	void box() {
		System.out.println("Place pizza in official PizzaStore box.");
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

package PizzaStore;
import BasePackage.Pizza;
import BasePackage.PizzaStore;
import IngredientFactory.CheesePizza;
import IngredientFactory.ClamPizza;
import IngredientFactory.NYPizzaIngredientFactory;
import IngredientFactory.PepperoniPizza;
import IngredientFactory.PizzaIngredientFactory;
import IngredientFactory.VeggiePizza;

public class NYPizzaStore extends PizzaStore{

	
	//这里只有creatPizza()方法, Pizza orderPizza(String type) 方法没列出来
	public Pizza creatPizza(String item) {
		Pizza pizza = null;
		PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
		
		if(item.equals("cheese")) {
			pizza = new CheesePizza(ingredientFactory);
			pizza.setName("New York Style Cheese Pizza!");
			//return new NYStyleCheesePizza();
		}else if(item.equals("veggie")) {
			pizza = new VeggiePizza(ingredientFactory);
			pizza.setName("New York Style Veggie Pizza!");
			//return new NYStyleVeggiePizza();
		}else if(item.equals("clam")) {
			pizza = new ClamPizza(ingredientFactory);
			pizza.setName("New York Style Clam Pizza!");
			//return new NYStyleClamPizza();
		}else if(item.equals("pepperoni")) {
			pizza = new PepperoniPizza(ingredientFactory);
			pizza.setName("New York Style Pepperoni Pizza!");
			//return new NYStylePepperoniPizza();
		}else return null;
		return pizza;
	}

}

运行环境:Eclipse 代码:Java
下载地址
提取码:a1b6

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值