zoukankan      html  css  js  c++  java
  • 第一节:不使用设计模式的传统方式

    一、提出需求

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

      (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对象的代码就不需要修改了。

  • 相关阅读:
    java nb
    hdu5293(2015多校1)--Tree chain problem(树状dp)
    点击交互的四种处理
    Java实现二维码技术探讨。
    折腾开源WRT的AC无线路由之路-1
    C语言及程序设计[套餐]课程主页
    09_Android中ContentProvider和Sqllite混合操作,一个项目调用另外一个项目的ContentProvider
    C语言打印字母金字塔(第一行是A 第二行是ABA ……)
    成员函数的const究竟修饰的是谁
    linux pdb调试总结
  • 原文地址:https://www.cnblogs.com/niujifei/p/14225425.html
Copyright © 2011-2022 走看看