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中方法对每个具体实现有所依赖。前者实际解耦性更高。

  • 相关阅读:
    mvc+dwz第七天
    mvc+dwz第六天
    mvc+dwz第五天
    mvc+dwz第四天
    笔记-基础配置与应用
    Entity Framework (EF) Core学习笔记 1
    EFCore学习记录--数据访问技术人门2
    EFCore学习记录--数据访问技术人门
    net core启动报错Unable to configure HTTPS endpoint. No server certificate was specified
    c#中const与readonly区别
  • 原文地址:https://www.cnblogs.com/JoeBlogs/p/8595584.html
Copyright © 2011-2022 走看看