• 设计模式学习之建造者模式(Builder,创建型模式)(6)


    假如我们需要建造一个房子,并且我们也不知道如何去建造房子,所以就去找别人帮我们造房子

    第一步:

    新建一个房子类House,里面有房子该有的属性,我们去找房子建造者接口HouseBuilder,我们要建造一栋平房,就去找PingFangHouseBuilder,该类继承自HouseBuilder,里面有具体建造房子的方法各种方法,比如造地板makeFloor,造墙makeWall等

    第二步:

    光有会建造房子的人还不行,我们还需要专门的设计师HouseDirector来调用这个建造房子的方法才行

    第三步:

    客户只知道建造平房,只能 找设计师去调用建造者去建造房子,然后从建造者那里得到房子

    代码如下:

    House.java

    package com.designpattern.builder;
    
    /**
     * 房子类
     * @author yxl
     *
     */
    public class House {
        //地板
        private String floor;
        //
        private String wall;
        //屋顶
        private String housetop;
        public String getFloor() {
            return floor;
        }
        public void setFloor(String floor) {
            this.floor = floor;
        }
        public String getWall() {
            return wall;
        }
        public void setWall(String wall) {
            this.wall = wall;
        }
        public String getHousetop() {
            return housetop;
        }
        public void setHousetop(String housetop) {
            this.housetop = housetop;
        }
    }    

    HouseBuilder.java

    package com.designpattern.builder;
    
    /**
     * 造房子的建造者,是个抽象的
     * @author yxl
     *
     */
    public interface HouseBuilder {
        /**
         * 建造地板
         */
        public void makeFloor();
        /**
         * 建造墙
         */
        public void makeWall();
        /**
         * 建造屋顶
         */
        public void makeHousetop();
        
        public House getHouse();
    }

    PingFangHouseBuilder.java

    package com.designpattern.builder;
    
    public class PingFangHouseBuilder implements HouseBuilder {
    
        private House house = new House();
        
        
        @Override
        public void makeFloor() {
            house.setFloor("平房建造--地板");
        }
    
        @Override
        public void makeWall() {
            house.setWall("平房建造--墙");
        }
    
        @Override
        public void makeHousetop() {
            house.setHousetop("平房建造--屋顶");
        }
        
        public House getHouse(){
            return house;
        }
    
    }

    HouseDirector.java

    package com.designpattern.builder;
    
    /**
     * 设计师类
     * @author yxl
     *
     */
    public class HouseDirector {
        /**
         * 设计师调用建造者的盖房子方法就行
         * @param houseBuilder
         */
        public void makeHouse(HouseBuilder houseBuilder){
            houseBuilder.makeFloor();
            houseBuilder.makeWall();
            houseBuilder.makeHousetop();
            
        }
    }

    MainClass.java

    package com.designpattern.builder;
    
    public class MainClass {
        public static void main(String[] args) {
            //如果是这种实现方式,那么客户必须知道如何建房子才行,必须知道细节,所以客户就去找人HouseBuilder去建造房子
    //        House house = new House();
    //        house.setFloor("建造地板");
    //        house.setWall("建造墙");
    //        house.setHousetop("建造屋顶 ");
    //        System.out.println(house.getFloor());
    //        System.out.println(house.getWall());
    //        System.out.println(house.getHousetop());
            
            
            //这样实现是客户直接找建造者建造房子,客户还必须调用建造者去造房子,这样客户还是必须知道如何造房子才行,
            //所以建造者必须找一个设计师(HouseDirector)来调用建造者的造房子方法
    //        HouseBuilder houseBuilder = new PingFangHouseBuilder();
    //        houseBuilder.makeFloor();
    //        houseBuilder.makeWall();
    //        houseBuilder.makeHousetop();
    //        House house = houseBuilder.getHouse();
    //        System.out.println(house.getFloor());
    //        System.out.println(house.getWall());
    //        System.out.println(house.getHousetop());
            
            //将调用建造者造房子的方法交给设计师去调用,客户只需要找一个设计师就可以了,等房子造好之后就问建造者去要
            HouseBuilder houseBuilder = new PingFangHouseBuilder();
            HouseDirector houseDirector = new HouseDirector();
            houseDirector.makeHouse(houseBuilder);
            House house = houseBuilder.getHouse();
            System.out.println(house.getFloor());
            System.out.println(house.getWall());
            System.out.println(house.getHousetop());
            
            
        }
    }

    一、什么是建造者模式

    Builder模式也叫建造者模式或者生成器模式,是由GoF提出的23种设计模式中的一种。Builder模式是一种对象创建型模式之一,用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象。

    二、建造者模式应用场景

    - 对象的创建:Builder模式是为对象的创建而设计的模式

    - 创建的是一个复合对象:被创建的对象为一个具有复合属性的复合对象

    - 关注对象创建的各部分的创建过程:不同的工厂(这里指builder生成器)对产品属性有不同的创建方法

    三、.NET 中建造者模式的实现

      前面的设计模式在.NET类库中都有相应的实现,那在.NET 类库中,是否也存在建造者模式的实现呢? 然而对于疑问的答案是肯定的,在.NET 类库中,System.Text.StringBuilder(存在mscorlib.dll程序集中)就是一个建造者模式的实现。不过它的实现属于建造者模式的演化,此时的建造者模式没有指挥者角色和抽象建造者角色,StringBuilder类即扮演着具体建造者的角色,也同时扮演了指挥者和抽象建造者的角色,此时建造模式的实现如下:

    复制代码
     /// <summary>
        /// 建造者模式的演变
        /// 省略了指挥者角色和抽象建造者角色
        /// 此时具体建造者角色扮演了指挥者和建造者两个角色
        /// </summary>
        public class Builder
        {
            // 具体建造者角色的代码
            private Product product = new Product();
            public void BuildPartA()
            {
                product.Add("PartA");
            }
            public void BuildPartB()
            {
                product.Add("PartB");
            }
            public Product GetProduct()
            {
                return product;
            }
            // 指挥者角色的代码
            public void Construct()
            {
                BuildPartA();
                BuildPartB();
            }
        }
    
        /// <summary>
        /// 产品类
        /// </summary>
        public class Product
        {
            // 产品组件集合
            private IList<string> parts = new List<string>();
    
            // 把单个组件添加到产品组件集合中
            public void Add(string part)
            {
                parts.Add(part);
            }
    
            public void Show()
            {
                Console.WriteLine("产品开始在组装.......");
                foreach (string part in parts)
                {
                    Console.WriteLine("组件" + part + "已装好");
                }
    
                Console.WriteLine("产品组装完成");
            }
        }
    
        // 此时客户端也要做相应调整
        class Client 
        {
            private static Builder builder;
            static void Main(string[] args)
            {
                builder = new Builder();
                builder.Construct();
                Product product = builder.GetProduct();
                product.Show();
                Console.Read();
            }
        }
    复制代码

      StringBuilder类扮演着建造string对象的具体建造者角色,其中的ToString()方法用来返回具体产品给客户端(相当于上面代码中GetProduct方法)。其中Append方法用来创建产品的组件(相当于上面代码中BuildPartA和BuildPartB方法),因为string对象中每个组件都是字符,所以也就不需要指挥者的角色的代码(指的是Construct方法,用来调用创建每个组件的方法来完成整个产品的组装),因为string字符串对象中每个组件都是一样的,都是字符,所以Append方法也充当了指挥者Construct方法的作用。

  • 相关阅读:
    Javascript校验密码复杂度的正则表达式
    Git合并指定文件到另一个分支
    WebForm SignalR 实时消息推送
    基于SignalR的消息推送与二维码描登录实现
    yarn 错误There appears to be trouble with your network connection. Retrying...
    使用SqlConnectionStringBuilder构造数据库连接字符串
    邮箱核心业务领域建模
    C# NuGet常用命令
    阿里P7架构师是如何解决跨域问题的!你有遇到吗?
    WinForm 之 自定义标题栏的窗体移动
  • 原文地址:https://www.cnblogs.com/yxlblogs/p/3531695.html
Copyright © 2020-2023  润新知