一、提出需求

  分析一个关于生产披萨的项目:要便于披萨种类的扩展,要便于维护。

  (1)披萨的种类很多(比如:GreekPizza、CheesePizza 等)

  (2)披萨的制作有 prepare,bake,cut,box

  (3)完成披萨店订购功能。

二、使用传统的方式来完成

  思路分析:可以得到,将披萨做成一个抽象类,里面声明所有披萨都需要的功能,然后根据需要来继承该类,再创建一个订购类,可以根据用户输入的披萨名称来生产不同种类的披萨。

  UML 类图:

  

 

 

 

  Demo:不使用设计模式

  Pizza 相关类

 1 /**
 2  * 将 pizza 类做成抽象类
 3  */
 4 public abstract class Pizza {
 5     //名字
 6     protected String name;
 7 
 8     //准备原材料, 不同的披萨不一样,因此,我们做成抽象方法
 9     public abstract void prepare();
10 
11     //烘焙
12     public void bake() {
13         System.out.println(name + " baking;");
14     }
15 
16     //切割
17     public void cut() {
18         System.out.println(name + " cutting;");
19     }
20 
21     //打包
22     public void box() {
23         System.out.println(name + " boxing;");
24     }
25 
26     public void setName(String name) {
27         this.name = name;
28     }
29 
30 }
31 
32 public class GreekPizza extends Pizza{
33     @Override
34     public void prepare() {
35         System.out.println(" 给希腊披萨 准备原材料 ");
36     }
37 }
38 
39 public class CheesePizza extends Pizza {
40     @Override
41     public void prepare() {
42         System.out.println(" 给制作奶酪披萨 准备原材料 ");
43     }
44 }

 

订购披萨

 1 public class OrderPizza {
 2 
 3     //构造器
 4     public OrderPizza() {
 5         Pizza pizza = null;
 6         String orderType; //订购披萨的类型
 7         do {
 8             orderType = getType();
 9             if (orderType.equals("greek")) {
10                 pizza = new GreekPizza();
11                 pizza.setName("希腊披萨");
12             } else if (orderType.equals("cheese")) {
13                 pizza = new CheesePizza();
14                 pizza.setName("奶酪披萨");
15             } else {
16                 System.out.println("此类披萨还未上架");
17                 break;
18             }
19             //输出披萨制作过程
20             pizza.prepare();
21             pizza.bake();
22             pizza.cut();
23             pizza.box();
24 
25         } while (true);
26     }
27 
28     //声明一个方法,可以获取客户希望订购的披萨种类
29     private String getType() {
30         try {
31             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
32             System.out.println("input pizza 种类:");
33             String str = bufferedReader.readLine();
34             return str;
35         } catch (IOException e) {
36             e.printStackTrace();
37             return "";
38         }
39     }
40 }

 

测试类:

1 public class PizzaStore {
2 
3     public static void main(String[] args) {
4         new OrderPizza();
5     }
6 }

   效果:

          

  

  此时,我们需要另外上架一个新的 PepperPizza 披萨,对代码做出对应的修改。

   创建一个 PepperPizza 类:

1 public class PepperPizza extends Pizza {
2     @Override
3     public void prepare() {
4         // TODO Auto-generated method stub
5         System.out.println(" 给胡椒披萨准备原材料 ");
6     }
7 }

  对订购披萨类进行修改:

 1 public OrderPizza() {
 2         Pizza pizza = null;
 3         String orderType; //订购披萨的类型
 4         do {
 5             orderType = getType();
 6             if (orderType.equals("greek")) {
 7                 pizza = new GreekPizza();
 8                 pizza.setName("希腊披萨");
 9             } else if (orderType.equals("cheese")) {
10                 pizza = new CheesePizza();
11                 pizza.setName("奶酪披萨");
12             } else if (orderType.equals("pepper")) {
13                 pizza = new PepperPizza();
14                 pizza.setName("胡椒披萨");
15             } else {
16                 System.out.println("此类披萨还未上架");
17                 break;
18             }
19             //输出披萨制作过程
20             pizza.prepare();
21             pizza.bake();
22             pizza.cut();
23             pizza.box();
24 
25         } while (true);
26     }

 

   类图:

    

 

 

 

 三、传统的方式的优缺点

  1、优点是比较好理解,简单易操作。

  2、缺点是违反了设计模式的 OCP 原则,即对扩展开发,对修改关闭。即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码。

  3、比如这时要新增一个 Pizza 的种类(Pepper披萨),需要做如下修改:

    ① 增加一个对应的 PepperPizza类;

    ② 凡是订购 Pizza 的代码都需要修改;(可能有一处或者多处都使用)

    

 

 

 

 

  4、改进的思路分析

    分析:修改代码可以接受,但是如果我们在其他的地方也有创建 Pizza的代码,就意味着,也需要修改,而创建 Pizza 的代码,往往有多处。

    思路:把创建 Pizza 对象封装到一个类中,这样我们有新的 Pizza 种类时,只需要修改该类即可。其他有创建到Pizza对象的代码就不需要修改了。

 

posted on 2021-01-03 14:23  格物致知_Tony  阅读(101)  评论(0编辑  收藏  举报