工厂模式
【需求背景】
一个披萨项目:要便于披萨种类的扩展,更便于维护
- 披萨种类可能很多
- 披萨的制作较为固定:prepare,bake,cut,box
- 完成披萨店订购功能
【传统OO类图设计】
-Pizza
:抽象披萨类—抽象prepare方法和各自类拥有的基础操作bake,cut,box
--CheesePizza
:重写prepare()方法
--GreekPizza
:重写prepare()方法
-OrderPizza
:产生对应的Pizza类(用户输入"cheese" 产出CheesePizza类
"Greek"产出GreekPizza类
)
-PizzaStore
:pizza客户端(使用类)
【传统实现–代码实例】
【Pizza抽象类
】
public abstract class Pizza {
protected String name;
//准备原材料,不同的披萨不一样
public abstract void prepare();
//烘焙
public void bake(){
System.out.println(name + "baking;");
}
//裁剪
public void cut(){
System.out.println(name + "cutting;");
}
//打包
public void box(){
System.out.println(name + "boxing;");
}
public void setName(String name) {
this.name = name;
}
}
【CheesePizza
】
public class CheesePizza extends Pizza{
@Override
public void prepare() {
System.out.println("奶酪披萨 准备原材料");
}
}
【GreekPizza
】
public class GreekPizza extends Pizza{
@Override
public void prepare() {
System.out.println("希腊披萨 准备原材料");
}
}
【OrderPizza
】
public class OrderPizza {
public OrderPizza(){
Pizza pizza =null;
String orderType;
do {
String type = getType();
if (type.equals("cheese")){
pizza = new CheesePizza();
pizza.setName("奶酪披萨");
}else if (type.equals("greek")){
pizza = new GreekPizza();
pizza.setName("希腊披萨");
}else {
break;
}
//披萨制作过程
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.bake();
}while (true);
}
//获取用户希望订购的pizza种类
private String getType(){
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza type:");
return bufferedReader.readLine();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
【PizzaStore
】
// pizza订购客户端 负责发起订购
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza();
}
}
【运行结果】
【优缺点】
- 优点:比较好理解,简单易操作。
- 缺点是违反ocp原则,即对扩展开放,对修改关闭。当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码.
- 比如我们这时要新增加一个Pizza的种类(Pepper披萨),创建类order会进行修改 使用到order类方法的使用类也需要进行修改