工厂方法:定义一个创建对象的接口,但由子类决定实例化的类是哪一个,工厂方法让类把实例化推迟到子类。
先画出UML类图来理解定义:
应用场景:某披萨连锁公司想要拓展业务,使得更多的加盟店能够加入进来,但是他们希望,要保留总公司一些基本制作流程,以便能保持品牌效果,同时还要满足地域差异而带来的口味不同。
分析该场景:
根据总公司的要求,加盟店需要保持总公司的基本创建步骤,同时又可以自己创建符合当地口味的pizza,于是我们这么设计:
代码文件:
Pizza接口:
package com.design.factorymethod;
/**
* 披萨接口
* @author Administrator
*
*/
public interface Pizza {
//准备过程的几个步骤方法
public void prepare();
public void bake();
public void cut();
public void box();
}
芝加哥风味的两种Pizza:
package com.design.factorymethod;
/**
* 芝加哥calm披萨
* @author Administrator
*
*/
public class ChicagoClamPizza implements Pizza{
public void prepare() {
System.out.println("prepare ChicagoClamPizza");
}
public void bake() {
System.out.println("bake ChicagoClamPizza");
}
public void cut() {
System.out.println("cut ChicagoClamPizza");
}
public void box() {
System.out.println("box ChicagoClamPizza");
}
}
package com.design.factorymethod;
/**
* 芝加哥cheese披萨
* @author Administrator
*
*/
public class ChicagoCheesePizza implements Pizza{
public void prepare() {
System.out.println("prepare ChicagoCheesePizza");
}
public void bake() {
System.out.println("bake ChicagoCheesePizza");
}
public void cut() {
System.out.println("cut ChicagoCheesePizza");
}
public void box() {
System.out.println("box ChicagoCheesePizza");
}
}
Pizza店的抽象,对工厂方法抽象化,而其他所有方法都可以直接在该类实现。
package com.design.factorymethod;
/**
* 抽象超类(披萨店)
* @author Administrator
*
*/
public abstract class PizzaStore {
/**
* 订阅披萨,客户只需关注这个订阅方法,无需关注如何,创建披萨
* @param type
* @return
*/
public Pizza orderPizza(String type){
Pizza pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
//工厂方法
protected abstract Pizza createPizza(String type);
}
然后我们便能实现芝加哥分店的类:
package com.design.factorymethod;
/**
* 芝加哥披萨
* @author Administrator
*
*/
public class ChicagoPizzaStore extends PizzaStore {
/**
* 实现工厂方法
*/
@Override
protected Pizza createPizza(String type) {
if(type.equals("ChicagoCheesePizza")){
return new ChicagoCheesePizza();
}else if(type.equals("ChicagoCheesePizza")){
return new ChicagoClamPizza();
}
return null;
}
}
我们做下测试:
package com.design.factorymethod;
public class FactoryMehodTest {
public static void main(String[] args) {
ChicagoPizzaStore chicagoPizzaStore = new ChicagoPizzaStore();
chicagoPizzaStore.orderPizza("ChicagoCheesePizza");
}
}
测试结果
这样一来,既可以保留原来总公司的基本制作流程,各地域的分店还能自己灵活的在上面做一个改良,以便满足当地的口味。
欢迎评论交流,有分析不到位之处,欢迎指出。。