先看一个需求
完成一个披萨的项目:要便于披萨种类的扩展,便于维护
- 披萨的种类很多(比如GreekPizz、CheesePizz等)
- 披萨的制作过程有prepare、bake、cut、box
- 完成披萨店的订购功能。
用传统方式实现
创建5个类:Pizza抽象类、CheesePizza实现类、GreekPizza实现类、OrderPizza订购披萨类、PizzaStore输出类
类图如下【蓝色实心箭头代表继承关系、虚线代表依赖关系】:
Pizza抽象类
package com.hupp.factory.simplefactory.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 +" cuting;");
}
public void box(){
System.out.println(name +" boxing;");
}
public void setName(String name){
this.name=name;
}
}
CheesePizza实现类
package com.hupp.factory.simplefactory.pizzastore.pizza;
public class CheesePizza extends Pizza{
@Override
public void prepare() {
System.out.println("奶酪披萨原材料准备中");
}
}
GreekPizza实现类
package com.hupp.factory.simplefactory.pizzastore.pizza;
public class GreekPizza extends Pizza{
@Override
public void prepare() {
System.out.println("准备制作希腊披萨的原材料");
}
}
OrderPizza订购披萨类
package com.hupp.factory.simplefactory.pizzastore.order;
import com.hupp.factory.simplefactory.pizzastore.pizza.CheesePizza;
import com.hupp.factory.simplefactory.pizzastore.pizza.GreekPizza;
import com.hupp.factory.simplefactory.pizzastore.pizza.Pizza;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class OrderPizza{
public OrderPizza() {
Pizza pizza = null;
String orderType;
do {
orderType = getType();
if ("greek".equals(orderType)) {
pizza = new GreekPizza();
pizza.setName("希腊披萨");
} else if ("cheese".equals(orderType)) {
pizza = new CheesePizza();
pizza.setName("奶酪披萨");
} else {
break;
}
//输出pizza制作过程
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.bake();
} while (true);
}
private String getType(){
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza type:");
String str = null;
try {
str = in.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
PizzaStore输出类
package com.hupp.factory.simplefactory.pizzastore.order;
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza();
}
}
总结:代码容易理解,写起来简单。但是,违反了开闭原则,即【对扩展开放,对修改关闭】,如果新增加披萨的类别时需要修改OrderPizza类,不利于扩展。
简单工厂模式
定义了一个创建对象的类,由这个类来封装实例化对象的行为
上述代码改成简单工厂模式:
披萨抽象类(Pizza)和披萨具体实现类(CheesePizza、GreekPizza)不需要变化。
创建个简单工厂类:SimpleFactory
public class SimpleFactory {
public static Pizza createPizza(String orderType){
System.out.println("使用简单工厂模式");
Pizza pizza = null;
if ("greek".equals(orderType)) {
pizza = new GreekPizza();
pizza.setName("希腊披萨");
} else if ("cheese".equals(orderType)) {
pizza = new CheesePizza();
pizza.setName("奶酪披萨");
}
return pizza;
}
}
修改一下订购披萨类(OrderPizza)
public class OrderPizza {
Pizza pizza = null;
String orderType;
public OrderPizza() {
do {
orderType = getType();
pizza = SimpleFactory.createPizza(orderType);
//输出pizza
if (pizza != null) {
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.bake();
} else {
System.out.println("订购披萨失败");
break;
}
}
while (true);
}
private String getType() {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza type:");
String str = null;
try {
str = in.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
总结:简单工厂类将实例化对象的过程封装到了一个工厂类中,使代码更容易维护,使用者也不必关系对象创建的流程。但是依然违法了开闭原则,而且一旦这个工厂不能正常工作,整个系统可能都会收到影响