博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
工厂方法模式(Factory Method Pattern)
阅读量:4969 次
发布时间:2019-06-12

本文共 4141 字,大约阅读时间需要 13 分钟。

工厂方法模式定义:Define an interface for creating an object,but let subclass decide which class to instantiate.Factory Methode lets a class defer instantiate to subclass.工厂方法模式定义了一个创建方法的接口,但由子类决定要初始化的类是哪一个,工厂方法让类把实例化推迟到子类。

两家PizzaStore,NYPizzaStore提供纽约风味的pizza,CHPizzaStore提供芝加哥风味的pizza:

public abstract class PizzaStore {	public abstract Pizza orderPizza(String type);}
public class NYPizzaStore extends PizzaStore {	private NYPizzaFactory factory;		public NYPizzaStore(NYPizzaFactory factory){		this.factory = factory;	}		public Pizza orderPizza(String type) {		Pizza pizza = factory.createPizza(type);				pizza.prepare();		return pizza;	}}
public class CHPizzaStore extends PizzaStore {	private CHPizzaFactory factory;		public CHPizzaStore(CHPizzaFactory factory){		this.factory = factory;	}		public Pizza orderPizza(String type) {		Pizza pizza = factory.createPizza(type);				pizza.prepare();		pizza.cut();		return pizza;	}}
public class NYPizzaFactory{	public Pizza createPizza(String type) {		Pizza pizza = null;		if(type == "cheese"){			pizza = new NYCheessePizza();		}else if(type == "greek"){			pizza = new NYGreekPizza();		}		return pizza;	}}
public class CHPizzaFactory{	public Pizza createPizza(String type) {		Pizza pizza = null;		if(type == "cheese"){			pizza = new CHCheessePizza();		}else if(type == "greek"){			pizza = new CHGreekPizza();		}		return pizza;	}}
public abstract class Pizza {	public abstract void prepare();		public abstract void cut();}
public class CHCheessePizza extends Pizza {	public void prepare() {		System.out.println("CHCheesePizza prepare!");	}	public void cut() {		System.out.println("CHCheesePizza cut!");	}}

其它的pizza是一样的,测试一下:

public class Test {	public static void main(String[] args) {		NYPizzaFactory nyfactory = new NYPizzaFactory();		NYPizzaStore nystore = new NYPizzaStore(nyfactory);		nystore.orderPizza("cheese");				CHPizzaFactory chfactory = new CHPizzaFactory();		CHPizzaStore chstore = new CHPizzaStore(chfactory);		chstore.orderPizza("greek");	}}
NYCheessePizza prepare!CHGreekPizza prepare!CHGreekPizza cut!

PizzaStore是一个抽象的接口,那么继承类通过重写其orderPizza()方法可以自由的实现各自的流程

比如NYPizzaStore的pizza在送出前是不需要cut()的,但是CHPizzaStore的pizza在送出前需要cut(),能不能使NYPizzaStore和CHPizzaStore都保持相同的工作流程,在送出pizza的时候强制要求先进行prepare()然后再进行cut()呢?

由于使用了PizzaStore抽象类,那么使继承类具有相同行为的方式显然是将该行为抽象至他们共同的父类中,并禁止该行为的重写

public abstract class PizzaStore {	public final Pizza orderPizza(String type){		Pizza pizza = ?				pizza.prepare();		pizza.cut();		return pizza;	};}

如此便可保证所有的Pizza在送出前先必须先进行prepare()然后进行cut()

(最初的目的是希望将共同的部分提取出来,以提高代码的复用性,手段是将共同的代码提炼至抽象父类,结果是导致了所有的继承类都必须具有相同的流程,算是有利有弊)

但关键问题是,如何初始化Pizza,在PizzaStore中,根本就不知道将要调用orderPizza方法的是CHPizzaStore类还是NYPizzaStore类,因此没法判断应该提供何种特定类型的pizza(比如:CHCheesePizza)

但是继承类知道自己需要何种类型的Pizza(NYPizzaStore当然知道自己需要NYCheesePizza),那么就让继承类自己创建所需的Pizza好了,这就是工厂方法模式

NYPizzaStore中的createPizza()方法和前面的NYPizzaFactory类的作用是一样的,区别只是将createPizza()放在继承类中,而没有抽象为一个具体的简单工厂类型

工厂方法这个名字很贴切

public abstract class PizzaStore {        public abstract Pizza createPizza(String type);	public final Pizza orderPizza(String type) {		Pizza pizza = this.createPizza(type);		pizza.prepare();		pizza.cut();		return pizza;	}}
public class NYPizzaStore extends PizzaStore{	public Pizza createPizza(String type) {		Pizza pizza = null;		if(type == "cheese"){			pizza = new NYCheessePizza();		}else if(type == "greek"){			pizza = new NYGreekPizza();		}		return pizza;	}}
public class CHPizzaStore extends PizzaStore {	public Pizza createPizza(String type) {		Pizza pizza = null;		if(type == "cheese"){			pizza = new CHCheessePizza();		}else if(type == "greek"){			pizza = new CHGreekPizza();		}		return pizza;	}}

我知道有一个pizza,但并不知道pizza的具体类型,store没有和特定的pizza类型耦合:

public class Test {	public static void main(String[] args) {		PizzaStore store = new NYPizzaStore();		Pizza pizza = store.orderPizza("cheese");		store = new CHPizzaStore();		pizza = store.orderPizza("greek");	}}
NYCheessePizza prepare!NYCheessePizza cut!CHGreekPizza prepare!CHGreekPizza cut!

高层组件PizzaStore和底层组件Pizza实现类都依赖抽象类Pizza,真正的松耦合设计

这样就可以看出工厂方法模式的功能了,既能提供一个框架保证所有的继承类都能按照我的流程来,又没有特定类之间的耦合

转载于:https://www.cnblogs.com/sean-zou/archive/2013/05/30/3710051.html

你可能感兴趣的文章
LeetCode Find K Pairs with Smallest Sums
查看>>
CentOS 6.4下PXE+Kickstart无人值守安装操作系统
查看>>
数据库三范式
查看>>
看完漫画秒懂区块链
查看>>
开发工具,做一个有效率的开发者
查看>>
对Haskell这门语言的基本认识
查看>>
mysql 安装补充
查看>>
大学里如何学习 ?
查看>>
Oracle命令类别
查看>>
js面试题:关于数组去重的四种方法总结
查看>>
Linux内核分析(三)----初识linux内存管理子系统
查看>>
stc12c5a60s2驱动TEA5767收音机模块硬件调试总结
查看>>
vue中提示$index is not defined
查看>>
Java中对List集合内的元素进行顺序、倒序、随机排序的示例代码
查看>>
css选择器
查看>>
看懂下面C++代码才说你理解了C++多态虚函数!
查看>>
ASP.NET上传下载文件
查看>>
Galaxy Nexus 全屏显示-隐藏Navigation Bar
查看>>
Mob-第三方分享 /手机验证码
查看>>
Spring中使用Velocity模板
查看>>