zoukankan      html  css  js  c++  java
  • C#设计模式(5)——建造者模式

    出处:https://www.cnblogs.com/wyy1234/

    阅读目录


    1.建造者模式介绍

      在软件开发中,有时我们要创建一个复杂的对象,这个对象由几个子部件按一定的步骤组合而成,这时候我们就可以使用建造者模式了。说到建造者我们首先想到的是盖房子,盖房子简单的说有三个步骤:打地基,砌砖,粉刷。我们就以盖房子为例解释建造者模式的用法。

      建造者模式有三个角色:建造者,具体的建造者,监工。理清这三个角色的作用我们就可以愉快的使用建造者模式了。

      建造者:一般为抽象类或接口,定义了建造者的功能。如盖房子例子的建造者有打地基,砌砖和粉刷的功能。

      具体的建造者:实现了建造者的抽象方法(或接口)。不同的具体建造者生产的组件不同,如一个技术好的建造者打地基深,砌砖整齐,粉刷光滑,而技术差的建造者打地基浅,砌砖错乱,粉刷粗糙。

      监工:制定建造的算法。建造者可以打地基,砌砖,粉刷,但是不知道先粉刷还是先打地基,监工就是给建造者制定盖房子步骤的。

    代码实现如下,

    建造者和具体建造者:

    复制代码
       //建造者抽象类,定义了建造者的能力
        public abstract class Builder
        {
            public abstract void Dadiji();//打地基
            public abstract void QiZhuan();//砌砖
            public abstract void FenShua();//粉刷
        }
    
        /// <summary>
        /// 技术好的建造者
        /// </summary>
        public class GoodBuilder : Builder
        {
            private StringBuilder house = new StringBuilder();
            public override void Dadiji()
            {
                house.Append("深地基-->");
                //这里一般是new一个部件,添加到实例中,如 house.Diji=new Diji("深地基")
                //为了演示方便 用sringBuilder表示一个复杂的房子,string表示房子的部件
            }
    
            public override void FenShua()
            {
                house.Append("粉刷光滑-->");
            }
    
            public override void QiZhuan()
            {
                house.Append("砌砖整齐-->");
            }
            public string GetHouse()
            {
                return house.Append("好质量房子建成了!").ToString();
            }
        }
    
        /// <summary>
        /// 技术差的建造者
        /// </summary>
        public class BadBuilder:Builder
        {
            private StringBuilder house = new StringBuilder();
            public override void Dadiji()
            {
                house.Append("挖浅地基-->");
            }
    
            public override void FenShua()
            {
                house.Append("粉刷粗糙-->");
            }
    
            public override void QiZhuan()
            {
                house.Append("砌砖错乱-->");
            }
            public string GetHouse()
            {
                return house.Append("坏质量房子建成了!").ToString();
            }
        }
    复制代码

    监工:

    复制代码
        //监工类,制定盖房子的步骤
        public class Director
        {
            private Builder builder;
            public Director(Builder builder)
            {
                this.builder = builder;
            }
    
            //制定盖房子的流程,
            public void Construct()
            {
                builder.Dadiji();//先打地基
                builder.QiZhuan();//再砌砖
                builder.FenShua();//最后粉刷
            }
        }
    复制代码

    客户端调用:

    复制代码
        class Program
        {
            static void Main(string[] args)
            {
                //监工1派遣技术好的建造者盖房子
                GoodBuilder goodBuilder = new GoodBuilder();
                Director director1 = new Director(goodBuilder);
                director1.Construct();
                string house1 = goodBuilder.GetHouse();
                Console.WriteLine(house1);
    
                //监工2派遣技术差的建造者盖房子
                GoodBuilder badBuilder = new GoodBuilder();
                Director director2 = new Director(goodBuilder);
                director2.Construct();
                string house2 = goodBuilder.GetHouse();
                Console.WriteLine(house2);
                Console.ReadKey();
            }
        }
    复制代码

    运行结果:

    2.小结

    上边例子的类图

    建造者模式的使用场景:

      主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定,这时适合用建造者模式。StringBuilder和Quartz中的JobBuilder,TriggerBuilder都使用了建造者模式。如果每添加一个部件都返回建造对象的索引,那么我们就可以实现基本的链式构造,如JobBuilder和TriggerBuilder都可以通过Fluent interface形式进行构造。

    建造者模式的优点:

      1.实例的构建具体到组件层次,方便控制细节;

      2.具体的建造者相互独立,易于扩展。

    建造者模式的缺点:

      当组件的组合种类很多时,需要创建很多的具体建造者类。

  • 相关阅读:
    SDN实验2:Mininet 实验——拓扑的命令脚本生成
    2020软工实践第一次作业
    POJ2942-Knights of the Round Table
    POJ1966 ZOJ2182<无向图点连通度 Isap版>
    POJ1523(求割点)
    POJ2391(最大流Isap+Floyd+二分)
    POJ1087 ZOJ1157(最大流Isap+map映射)
    POJ1459(最大流Isap)
    数字的字符串处理 (转)
    POJ2112 最大流(Isap+Floyd+二分)
  • 原文地址:https://www.cnblogs.com/frank0812/p/11241935.html
Copyright © 2011-2022 走看看