zoukankan      html  css  js  c++  java
  • 设计模式笔记——生成器模式(Builder Pattern)

    一、概述
    在软件系统中,把构造对象实例的逻辑移到了类的外部,在这个类的外部定义了类的逻辑。它把一个复杂对象的构造过程从对象的表示中分离出来了,其直接效果是将一个复杂的对象简化为一个比较简单的目标对象。它强调的是产品构造过程。
     
    二、意图
    将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
     
    三、Builder模式的结构
    Builder:为创建Product对象的各个部件指定抽象接口。
    ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。
    Director:构造一个使用Builer接口的对象。
    Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,以及将这些部件装配成最终产品的接口。
     
    四、举例:
    我们用KFC套餐为例,KFC中存在以下对象,各种食物Product,有收银员Director,可配置套餐菜单接口(主食+零食+饮料)Builder,具体套餐搭配ConcreteBuilder。

    1. 首先给定可配置套餐菜单接口(主食+零食+饮料)Builder:

        abstract public class Builder
        {
            // BuildPartA,BuildPartB,BuildPartC具体的套餐方法
            abstract public void BuildPartA();
            abstract public void BuildPartB();
            abstract public void BuildPartC();
            abstract public Product GetResult();
        }

    2.我们需要KFC的产品:

        public class Product
        {
            ArrayList parts = new ArrayList();
            public void Add(string part)
            {
                parts.Add(part);
            }
    
            public void Show()
            {
                Console.WriteLine(" Product Parts -------");
                foreach (string part in parts)
                Console.WriteLine(part);
            }
        }

    3. 然后,我们给出具体套餐搭配ConcreteBuilderA:

     public class ConcreteBuilderA:Builder
        {
            private Product product;
    
            // Methods
            override public void BuildPartA()
            {
                product = new Product();
                product.Add("麦香鸡腿堡");
            }
    
            override public void BuildPartB()
            {
                product.Add("加冰可乐");
            }
            override public void BuildPartC()
            {
                product.Add("大薯条");
            }
            override public Product GetResult()
            {
                return product;
            }
        }

     4. 然后,我们给出具体套餐搭配ConcreteBuilderB:

    public class ConcreteBuilderB:Builder
        {
            private Product product;
    
            // Methods
            override public void BuildPartA()
            {
                product = new Product();
                product.Add("香辣鸡腿堡");
            }
    
            override public void BuildPartB()
            {
                product.Add("可乐不加冰");
            }
            override public void BuildPartC()
            {
                product.Add("小薯条");
            }
    
            public override  Product GetResult()
            {
                return product;
            }
        }


    5. 现在我们需要一个收银员Director:

       public class Director
        {
            public void Construct(Builder builder)
            {
                builder.BuildPartA();
                builder.BuildPartB();
                builder.BuildPartC();
            }
        }

    6. 最后我们完成Client购买KFC套餐:

    class Program
        {
            static void Main(string[] args)
            {
                Director director = new Director();
    
                Builder b1 = new ConcreteBuilderA();
                Builder b2 = new ConcreteBuilderB();
                director.Construct(b1);
                Product p1 = b1.GetResult();
                p1.Show();
    
                director.Construct(b2);
                Product p2 = b2.GetResult();
                p2.Show();
                Console.ReadKey();
            }
        }

     这样Client分别买了两种不同的套餐,Client只需要让收款员知道你需要那种套餐即可,不需要了解具体套餐是如何实现的。

    五、优点:
     1.建造者模式的“加工工艺”是暴露的,这样使得建造者模式更加灵活。
     2.解耦了组装过程和创建具体部件,使得我们不用去关心每个部件是如何组装的。--上面对KFC的分析可以很清楚的看出这点。
     
    六、适用环境:
     1.需要生成的产品对象有复杂的内部结构。
     2.需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序。
     3.在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到。
     
    参考文献:
    《.NET应用架构设计原则、模式与实践》 王洋 著
     
  • 相关阅读:
    安卓:线性布局
    安卓文件的资源访问
    关于安卓的一些初步认识
    haayaGuardV0---3---手机与pc基于p2p通信
    【无中生有】---13---系统发布
    【无中生有】---12---运维与监控
    【无中生有】---11---服务器集群部署
    【无中生有】---7---分布式消息队列
    使用消息队列的 10 个理由
    【无中生有】---10---API接口日志存储设计与实现设计
  • 原文地址:https://www.cnblogs.com/Abel-Zhang/p/BuilderPattern.html
Copyright © 2011-2022 走看看