zoukankan      html  css  js  c++  java
  • 面向对象设计模式_生成器模式解读(Builder Pattern)

    首先提出一个很容易想到应用场景:

    手机的生产过程:手机有非常多的子件(部件),成千上万,不同品牌的手机的生产过程都是复杂而有所区别的,相同品牌的手机在设计上也因客户需求多样化,大到型号,小到颜色,是否配置附件。假设手机的生产过程(这里用方法来代替)可以是几千个方法的叠加过程,每个方法都面临不同的变化,如果将手机的生产过程中的这些方法全部耦合在一个对象里实现,显然是不明智的。

    教材书上对生成器模式的解释:生成器模式将复杂对象的构建过程和表示(实现)相分离,使得相同的构建过程可以创建不同的表示。如下图

    这里解析一下:"构建过程"(Construct)实则是抽象部分,即稳定的过程框架,它一般不会变化,就像模型中的foreach代码一样,这句代码唯一关联了对象的自身属性(Builders是接口类型IBuilder的集合),仅仅与抽象的接口关联,这完全符合DIP(依赖倒置)原则。手机的生产我们可以抽象成:摄像头生产,电路板生产,......组装手机。这些抽象都是比较稳定的。

    “不同的表示”,可以理解为,将这些抽象的过程具体化,并可以用不同的组合形式,顺序来构建(Construct),比如,我可以先生产A,再生产B,然后组装,也可以先B后A,等等。

    代码示例:生产一个有很多部件的产品

     public class Director
        {
            //产品架构
    
            //先生产10个部件1
            //其次再生产4个部件2
            //组装产品
            public List<IBuilder> Builders { get; set; }//将具体过程按序封装到该集合中
            public Director()
            {
                Builders = new List<IBuilder>();//仅依赖抽象接口
            }
            public void Construct()
            {
                foreach (IBuilder b in Builders)//这句代码是非常稳定的,它唯一依赖唯一的自身属性Builders
                {
                    b.BuildPart();
                }
            }
        }
      //对每个部件生产的抽象(这个接口算是最抽象级的抽象了)
        public interface IBuilder
        {
            void BuildPart();//每个Builder代表一个部件生产
        }
    
    
        //实例化部件的生产过程
        public class Part1Builder : IBuilder
        {
            public void BuildPart()
            {
                Console.WriteLine("完成部件1的生产!");
            }
        }
    
    
    //
    public class Part2Builder : IBuilder { public void BuildPart() { Console.WriteLine("完成部件2的生产!"); } } //对组装过程实例化 public class ProductBuilder : IBuilder { public void BuildPart() { Console.WriteLine("完成产品组装!"); } }


    //测试代码
    class Test
        {
            static void Main(string[] args)
            {
                Director director = new Director();
                for (int i = 0; i <10; i++)
                {
                    director.Builders.Add(new Part1Builder());
                }
                director.Builders.Add(new Part2Builder());
                director.Builders.Add(new ProductBuilder());
                director.Construct();
                Console.ReadKey();
            }
        }

     有些人对生成器模式有另一种解读,如下图所示:

    将抽象的构建过程的实现通过一个实例来实现,接口(IBuilder)中抽象了每一个子过程,每个实现类(ConcreteBuilder)代表一个不同的表示,是一个具体的构建过程。这样当客户需要一种新的形式产品时,就可以具体化一个新的类(ConcreteBuilder)来实现不同的过程(实现抽象化接口),然后在Director的构建方法(Construct)中调用。这实际上比上面一种解读模式稍微提高了些耦合度,同时在统一的接口中的提供很多抽象方法,实际上违背了单一职责原则(职责:变化的原因),扩展修改将变得比较繁重。

    上面的两个类图不同之处在于前者使用类对象实现不同的子过程,后者在统一的接口中抽象每个子过程。后者在Director中方法对每个具体实现有所依赖。前者实际解耦性更高。

  • 相关阅读:
    HDU 2955 Robberies(01背包)
    HDU 2602 Bone Collector(01背包)
    HUST 1352 Repetitions of Substrings(字符串)
    HUST 1358 Uiwurerirexb jeqvad(模拟解密)
    HUST 1404 Hamming Distance(字符串)
    HDU 4520 小Q系列故事――最佳裁判(STL)
    HDU 2058 The sum problem(枚举)
    【破解】修改程序版权、添加弹窗
    HDU 1407 测试你是否和LTC水平一样高(枚举)
    HDU 1050 Moving Tables(贪心)
  • 原文地址:https://www.cnblogs.com/JoeBlogs/p/8595584.html
Copyright © 2011-2022 走看看