需求说明
一个披萨订购的项目,要便于披萨种类的扩展,要便于维护
- 披萨的种类很多,比如GreekPizza、CheesePizza
- 披萨的制作有prepare、bake、cut、box
- 完成披萨店订购的功能
传统写法
Pizza.java
public abstract class Pizza {
public abstract void prepare();
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
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 class CheesePizza extends Pizza {
@Override
public void prepare() {
System.out.println("给制作奶酪披萨准备原材料");
}
}
希腊披萨
public class GreekPizza extends Pizza {
@Override
public void prepare() {
System.out.println("给制作希腊披萨准备原材料");
}
}
披萨订购
public class OrderPizza {
public OrderPizza() {
Pizza pizza = null;
String orderType;
do {
orderType = getType();
if (orderType.equals("greek")) {
pizza = new GreekPizza();
pizza.setName("希腊披萨");
} else if (orderType.equals("cheese")) {
pizza = new CheesePizza();
pizza.setName("奶酪披萨");
} else {
break;
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} while (true);
}
private String getType() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza type:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
披萨店
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza();
}
}
这样就能根据输入的披萨种类,来制作对应的披萨
输出如下
input pizza type:
cheese
给制作奶酪披萨准备原材料
奶酪披萨 baking
奶酪披萨 cutting
奶酪披萨 boxing
input pizza type:
greek
给制作希腊披萨准备原材料
希腊披萨 baking
希腊披萨 cutting
希腊披萨 boxing
input pizza type:
hello
Process finished with exit code 0
这种写法的优点是比较好理解,简单易操作,但是缺点是违反了设计模式的ocp原则,即对扩展开发,对修改关闭。比如我们要增加一个新的Pizza种类,就需要修改OrderPizza中的代码,如果有好多个
简单工厂模式
针对上面写法的缺点进行改造,把创建Pizza对象封装到一个类中,这样我们有新的Pizza种类时,只需要修改该类即可,其他有创建Pizza对象的代码就不需要修改了 -> 简单工程模式。
简单工厂模式属于创建型模式,是工厂模式的一种,由一个工厂对象决定创建出哪一种产品的实例。它定义了一个创建对象的类,由这个类封装实例化对象的行为。在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会用到工厂模式
工厂类
public class SimpleFactory {
public Pizza createPizza(String type) {
Pizza pizza = null;
System.out.println("使用简单工厂模式");
if (type.equals("greek")) {
pizza = new GreekPizza();
pizza.setName("希腊披萨");
} else if (type.equals("cheese")) {
pizza = new CheesePizza();
pizza.setName("奶酪披萨");
} else if (type.equals("pepper")){
pizza = new PepperPizza();
pizza.setName("胡椒披萨");
} else {
pizza = null;
}
return pizza;
}
}
披萨订购类
public class OrderPizza {
private SimpleFactory factory;
private Pizza pizza;
public OrderPizza(SimpleFactory factory) {
this.factory = factory;
String orderType = "";
do {
orderType = getType();
pizza = this.factory.createPizza(orderType);
if (pizza != null) {
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} else {
System.out.println("订购披萨失败");
break;
}
} while (true);
}
private String getType() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza type:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
披萨店
public class PizzaStore {
public static void main(String[] args) {
// 使用简单工厂模式
new OrderPizza(new SimpleFactory());
System.out.println("退出了程序");
}
}
静态工厂模式
简单工厂模式也叫静态工厂模式,原因是创建对象的方法可以写成一个静态方法。将上面的代码做如下修改
SimpleFactory增加一个方法:
public static Pizza createPizza2(String type) {
Pizza pizza = null;
System.out.println("使用静态工厂模式");
if (type.equals("greek")) {
pizza = new GreekPizza();
pizza.setName("希腊披萨");
} else if (type.equals("cheese")) {
pizza = new CheesePizza();
pizza.setName("奶酪披萨");
} else if (type.equals("pepper")){
pizza = new PepperPizza();
pizza.setName("胡椒披萨");
} else {
pizza = null;
}
return pizza;
}
OrderPizza2
public class OrderPizza2 {
private Pizza pizza;
public OrderPizza2() {
String orderType = "";
do {
orderType = getType();
// 直接使用类名调用
pizza = SimpleFactory.createPizza2(orderType);
if (pizza != null) {
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} else {
System.out.println("订购披萨失败");
break;
}
} while (true);
}
private String getType() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza type:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
披萨店
public class PizzaStore {
public static void main(String[] args) {
// 使用静态工厂模式
new OrderPizza2();
System.out.println("退出了程序");
}
}
效果是一样的
工厂方法模式
假如有了新的需求:
客户在点披萨时,可以点不同的口味,比如北京的奶酪pizza、北京的胡椒pizza或者伦敦的奶酪pizza、伦敦的胡椒pizza
工厂方法模式就是定义一个创建对象的抽象方法,由子类决定要实例化的类,工厂方法模式将对象的实例化推迟到子类
北京奶酪披萨
public class BJCheesePizza extends Pizza {
@Override
public void prepare() {
setName("北京奶酪");
System.out.println("为北京的奶酪披萨准备材料");
}
}
北京胡椒披萨
public class BJPepperPizza extends Pizza {
@Override
public void prepare() {
setName("北京胡椒");
System.out.println("为北京的胡椒披萨准备材料");
}
}
伦敦奶酪披萨
public class LDCheesePizza extends Pizza {
@Override
public void prepare() {
setName("伦敦奶酪");
System.out.println("为伦敦的奶酪披萨准备材料");
}
}
伦敦胡椒披萨
public class LDPepperPizza extends Pizza {
@Override
public void prepare() {
setName("伦敦胡椒");
System.out.println("为伦敦的胡椒披萨准备材料");
}
}
OrderPizza
public abstract class OrderPizza {
public abstract Pizza createPizza(String orderType);
public OrderPizza() {
Pizza pizza = null;
String orderType = "";
do {
orderType = getType();
pizza = createPizza(orderType);
if (pizza != null) {
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} else {
System.out.println("订购披萨失败");
break;
}
} while (true);
}
private String getType() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza type:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
其中createPizza()
这个抽象方法由子类去实现
北京OrderPizza
public class BJOrderPizza extends OrderPizza {
@Override
public Pizza createPizza(String orderType) {
Pizza pizza = null;
if (orderType.equals("cheese")) {
pizza = new BJCheesePizza();
} else if (orderType.equals("pepper")) {
pizza = new BJPepperPizza();
}
return pizza;
}
}
伦敦OrderPizza
public class LDOrderPizza extends OrderPizza {
@Override
public Pizza createPizza(String orderType) {
Pizza pizza = null;
if (orderType.equals("cheese")) {
pizza = new LDCheesePizza();
} else if (orderType.equals("pepper")) {
pizza = new LDPepperPizza();
}
return pizza;
}
}
PizzaStore
public class PizzaStore {
public static void main(String[] args) {
// 工厂方法模式:定一个创建对象的抽象方法,由子类决定要实例化的类,工厂方法模式将对象的实例化推迟到子类
String location = "bj";
if (location.equals("bj")) {
// 创建北京口味的各种披萨
new BJOrderPizza();
System.out.println("退出了程序");
} else if (location.equals("ld")) {
// 创建伦敦口味的各种披萨
new LDOrderPizza();
System.out.println("退出了程序");
}
}
}
抽象工厂模式
抽象工厂模式将工厂抽象成两层,AbsFactory(抽象工厂)和具体实现的工厂子类,程序员可以根据创建对象类型使用对象的工厂子类,这样将单个的简单工厂变成工厂簇,更利于代码的维护和扩展。
抽象工厂
public interface AbsFactory {
Pizza createPizza(String orderType);
}
北京披萨工厂
public class BJFactory implements AbsFactory {
@Override
public Pizza createPizza(String orderType) {
System.out.println("使用的是抽象工厂模式");
Pizza pizza = null;
if (orderType.equals("cheese")) {
pizza = new BJCheesePizza();
} else if (orderType.equals("pepper")) {
pizza = new BJPepperPizza();
}
return pizza;
}
}
伦敦披萨工厂
public class LDFactory implements AbsFactory {
@Override
public Pizza createPizza(String orderType) {
System.out.println("使用的是抽象工厂模式");
Pizza pizza = null;
if (orderType.equals("cheese")) {
pizza = new LDCheesePizza();
} else if (orderType.equals("pepper")) {
pizza = new LDPepperPizza();
}
return pizza;
}
}
OrderPizza
public class OrderPizza {
private AbsFactory factory;
public OrderPizza(AbsFactory factory) {
this.factory = factory;
Pizza pizza = null;
String orderType = "";
do {
orderType = getType();
pizza = this.factory.createPizza(orderType);
if (pizza != null) {
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} else {
System.out.println("订购披萨失败");
break;
}
} while (true);
}
private String getType() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input pizza type:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
PizzaStore
public class PizzaStore {
public static void main(String[] args) {
// 抽象工厂模式:
// 将工厂抽象成两层,抽象工厂和具体实现的工厂子类
new OrderPizza(new BJFactory());
}
}
小结
代码地址:
https://github.com/mundane799699/DesignPattern/tree/master/FactoryDesignPattern
参考:
网友评论