zoukankan      html  css  js  c++  java
  • 建造者模式

    学习建造者模式前,我们来实现一个汉堡的制作流程

    汉堡制作的大致流程:
    首先是加入两个面包片
    加入肉饼
    加入蔬菜
    加热
    打包

    代码:

     1 public class Builder1 {
     2     public static void main(String[] args) {
     3         Hamburger hamburger1 = new Hamburger("巨无霸", "吐司", "莴笋", "牛肉饼");
     4         hamburger1.setBread();
     5         hamburger1.setMeatPie();
     6         hamburger1.setVegetableLeaf();
     7         hamburger1.heating(10);
     8         hamburger1.pack();
     9     }
    10 }
    11 
    12 class Hamburger {
    13     private String name;//汉堡包名字
    14     private String bread;//面包片
    15     private String vegetableLeaf;//菜叶名
    16     private String meatPie;//肉饼名
    17 
    18     Hamburger(String name, String bread, String vegetableLeaf, String meatPie) {
    19         this.name = name;
    20         this.bread = bread;
    21         this.vegetableLeaf = vegetableLeaf;
    22         this.meatPie = meatPie;
    23     }
    24 
    25     void setBread() {
    26         System.out.println("加入面包片:" + this.bread);
    27     }
    28 
    29     void setVegetableLeaf() {
    30         System.out.println("向汉堡加入" + this.vegetableLeaf);
    31     }
    32 
    33     void setMeatPie() {
    34         System.out.println("向汉堡加入" + this.meatPie);
    35     }
    36 
    37 
    38     void heating(int minute) {
    39         System.out.println("汉堡加热时间" + minute + "分钟");
    40     }
    41 
    42     void pack() {
    43         System.out.println(this.name + "汉堡加工完成,打包!");
    44     }
    45 }

    运行的结果:

    功能实现啦,看起来也像一个“面向对象”的程序,把汉堡抽象出来了,同时汉堡中封装他独有的方法和属性。
    但是仔细看看客户端代码,我们在客户端新建了一个汉堡,然后对他进行了一系列的操作,最后完成了汉堡。

    建造者模式就是将一些列操作封装起来的一种模式


    但是出现了最大的问题:代码不可复用,每一次客户端需要汉堡的时候都需要加工一次
    不可复用的结果就可能导致每一次加工出来的汉堡都不一样,不是流水化作业
    比如工序的顺序颠倒了,比如多一个工序或者少一个工序,导致加工出来的汉堡都不是我们想要的汉堡,不是我们想要的对象。

    让我们来看看建造者模式时怎么实现这段代码

     1 public class Builder2 {
     2     public static void main(String[] args) {
     3         Hamburger1 hamburger1 = new KFCHamburger("鸡肉汉堡", "面包", "韭菜", "鸡肉饼");
     4         HamburgerBuilder hamburgerBuilder = new HamburgerBuilder(hamburger1);
     5         hamburgerBuilder.buildHamburger();
     6     }
     7 }
     8 
     9 abstract class Hamburger1 {
    10     String name;
    11     String bread;//面包片
    12     String vegetableLeaf;//菜叶名
    13     String meatPie;//肉饼名
    14     private int heatingTime;//加热时间
    15 
    16     Hamburger1(String name, String bread, String vegetableLeaf, String meatPie) {
    17         this.name = name;
    18         this.bread = bread;
    19         this.vegetableLeaf = vegetableLeaf;
    20         this.meatPie = meatPie;
    21         this.heatingTime = 0;
    22     }
    23 
    24     abstract void setBread();
    25 
    26     abstract void setVegetableLeaf();
    27 
    28     abstract void setMeatPie();
    29 
    30     abstract void heating(int minute);
    31 
    32     abstract void pack();
    33 }
    34 
    35 class KFCHamburger extends Hamburger1 {
    36     public KFCHamburger(String name, String bread, String vegetableLeaf, String meatPie) {
    37         super(name, bread, vegetableLeaf, meatPie);
    38     }
    39 
    40     @Override
    41     void setBread() {
    42         System.out.println("加入面包片:" + this.bread);
    43     }
    44 
    45     @Override
    46     void setVegetableLeaf() {
    47         System.out.println("向汉堡加入" + this.vegetableLeaf);
    48     }
    49 
    50     @Override
    51     void setMeatPie() {
    52         System.out.println("向汉堡加入" + this.meatPie);
    53     }
    54 
    55     @Override
    56     void heating(int minute) {
    57         System.out.println("汉堡加热时间" + minute + "分钟");
    58     }
    59 
    60     @Override
    61     void pack() {
    62         System.out.println(this.name + "汉堡加工完成,打包!");
    63     }
    64 }
    65 
    66 class HamburgerBuilder {
    67     private Hamburger1 hamburger1;
    68 
    69     HamburgerBuilder(Hamburger1 hamburger1) {
    70         this.hamburger1 = hamburger1;
    71     }
    72 
    73     Hamburger1 buildHamburger() {
    74         hamburger1.setBread();
    75         hamburger1.setMeatPie();
    76         hamburger1.setVegetableLeaf();
    77         hamburger1.heating(10);
    78         hamburger1.pack();
    79         return this.hamburger1;
    80     }
    81 }


    看完这段代码是不是觉得建造者模式也很厉害

    UML图

    建造者模式UML

    product:我们需要的产品对象

    Builder:对产品对象的加工方法

    Director:封装生产对象的过程,返回一个加工好的对象。

    (类似于工厂模式,将对象的生产过程封装起来,只返回一个立即可用的对象)

    更正一下:应该把生成对象的方法抽象到建造类中,而不是放在对象之中,所以看起会和建造者UML的图看起来有点点不一样

    我写的HamburgerBuilder其实对应的Director导演的位置,而建造者的方法我全部封装在Product中了。

    有时间会修改我的代码的

    分析下:
    解决了代码不能复用的问题了 (可复用)
    同时如果我们现在要把汉堡的的加热时间修改下,或者把肉片和蔬菜放置的顺序换一下。只需要到建造类中修改时间即可。
    如果我们将代码写在客户端,那么维护起来就是种灾难!(可维护)
    如果我们现在要加入一个巨无霸汉堡,他有三层肉片,2层蔬菜,加热20分钟怎么办呢
    我们只需要到建造类中加入生产巨无霸汉堡的代码即可(可谓可扩展,灵活性高)

     1 public static void main(String[] args) {
     2     Hamburger1 hamburger1 = new KFCHamburger("巨无霸", "面包", "韭菜", "鸡肉饼");
     3     HamburgerBuilder hamburgerBuilder = new HamburgerBuilder(hamburger1);
     4     hamburgerBuilder.buildBigBigBigHamburger();//修改建造的方法即可
     5 }
     6 
     7 Hamburger1 buildBigBigBigHamburger() {
     8     hamburger1.setBread();
     9     hamburger1.setMeatPie();//肉片1
    10     hamburger1.setVegetableLeaf();//蔬菜1
    11     hamburger1.setMeatPie();//肉片2
    12     hamburger1.setVegetableLeaf();//蔬菜2
    13     hamburger1.setMeatPie();//肉片3
    14     hamburger1.heating(20);
    15     hamburger1.pack();
    16     return this.hamburger1;
    17 }

    我们来看看结果吧

    建造者面膜是和工厂模式同属于创建型模式(创建型模式:负责对象的创建


    什么场景下使用建造者模式

    1.产品对象内部具有复杂的结构,产品对象包含多个成员属性,适用建造者模式可以隔离复杂对象的创建和适用,并使得相同的 创建过程可以创建不同的对象;
    2.相同的方法,不同的执行顺序,产生不同的事件结果时;(汉堡的加工顺序)


    简单来说,建造者模式就是一步步创建一个对象,它对用户屏蔽了里面构建的细节(顺序,调用次数...),但却可以精细地控制对象的构造过程。

    代码地址:https://gitee.com/gang_bryant/DesignMode1

  • 相关阅读:
    理解并使用.NET 4.5中的HttpClient
    响应式图片的3种解决方案
    Rest模式get,put,post,delete含义与区别
    Multiple websites on single instance of IIS
    C# 消息队列-MSMQ
    微服务 Micro services
    SQL Server For XML
    Real-time chart using ASP.NET Core and WebSocket
    ASP.NET Core Building chat room using WebSocket
    Ajax 调用的WCF
  • 原文地址:https://www.cnblogs.com/Gang-Bryant/p/10794775.html
Copyright © 2011-2022 走看看