C#设计模式学习笔记-建造者模式


本文分为两部分:

  1. 建造者模式(Builder)  
  2. 建造者模式  与 工厂模式的区别

缘起:

顾名思义,builder的意思是建造者或者建筑工人,谈到建造自然会想到楼房。
楼房是千差万别的,楼房的外形、层数、内部房间的数量、房间的装饰等等都不一样
对于建造者来说,抽象出来的建筑流程是确定的,往往建筑一座楼房包括下面的步骤:(1)打桩,建立基础(2)建立框架等。

建造者模式的本质和建造楼房是一致的:即流程不变,但每个流程实现的具体细节则是经常变化的。建造者模式的好处就是保证了流程不会变化,流程即不会增加、也不会遗漏或者产生流程次序错误,
 



动机(Motivation):
    在软件系统中,有时候面临一个"复杂对象"的创建工作,其通常由各个部分的子对象用一定算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合到一起的算法却相对稳定。
    如何应对种变化呢?如何提供一种"封装机制"来隔离出"复杂对象的各个部分"的变化,从而保持系统中的"稳定构建算法"不随需求的改变而改变?
意图(Intent):
    将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
                                              -------《设计模式》GOF


建造者模式包含如下角色:
Builder:抽象建造者
ConcreteBuilder:具体建造者
Director:指挥者
Product:产品角色

建造者模式引入了一个指挥者类Director,该类的作用主要有两个:
一、它隔离客户与生产过程;
二、它负责控制产品的生成过程。指挥者针对抽象建造者编程,客户端只需要知道具体建造者的类型,无须关心产品对象的具体组装过程,即可通过指挥者类调用建造者的相关方法,返回一个完整的产品对象。


实例:

假设创建一个房屋House设施,该房屋的构建由几部分组成,且各个部分富于变化。有两个工人,ChineseBuilder,RomanBuilder,假设他们技术风格相差很大,且相互不知道,一个房子只能由一方一套做下来。不可能出现一个Builder做一半,然后另一个Builder接着做。

带注释的代码:


using System;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main(string[] args)
        {

            Director director = new Director();
            Builder luban = new ChineseBuilder();

            director.Construct(luban);

            House house = luban.GetHouse();
            Console.WriteLine(house.BuilderSign);

            Console.ReadLine();
        }
    }
}

// 房间类, 假设该类只能通过 Builder类的GetHouse方法获得
public class House
{
    // 建造者的签名
    public string BuilderSign;
}

// Builder类:固定的几个流程
public abstract class Builder
{
    public abstract void BuildDoor();
    public abstract void BuildWall();
    public abstract void BuildWindows();
    public abstract void BuildFloor();
    public abstract void BuildHouseCeiling();

    public abstract House GetHouse();
}

//Director类:将固定的几个流程,按一定的方式排列组合到一起
public class Director
{
    public void Construct(Builder builder)
    {
        builder.BuildWall();
        builder.BuildHouseCeiling();
        builder.BuildDoor();
        builder.BuildWindows();
        builder.BuildFloor();
    }
}

// ChineseBuilder类  带各种组件的实现方法,和一个House
public class ChineseBuilder : Builder
{
    private readonly House ChineseHouse = new House();

    public ChineseBuilder()
    {
        ChineseHouse.BuilderSign = "鲁班";
    }
    public override void BuildDoor()
    {
        Console.WriteLine("Door Chinese");
    }

    public override void BuildWall()
    {
        Console.WriteLine("Wall Chinese");
    }

    public override void BuildWindows()
    {
        Console.WriteLine("Windows Chinese");
    }

    public override void BuildFloor()
    {
        Console.WriteLine("Floor Chinese");
    }

    public override void BuildHouseCeiling()
    {
        Console.WriteLine("Ceiling Chinese");
    }

    public override House GetHouse()
    {
        return ChineseHouse;
    }
}

// RomanBuilder类: 带各种组件的实现方法,和一个House
internal class RomanBuilder : Builder
{
    private readonly House RomanHouse = new House();

    public RomanBuilder()
    {
        RomanHouse.BuilderSign = "外国人";
    }
    public override void BuildDoor()
    {
        Console.WriteLine("Door Roman");
    }

    public override void BuildWall()
    {
        Console.WriteLine("Wall Roman");
    }

    public override void BuildWindows()
    {
        Console.WriteLine("Windows Roman");
    }

    public override void BuildFloor()
    {
        Console.WriteLine("Floor Roman");
    }

    public override void BuildHouseCeiling()
    {
        Console.WriteLine("Ceiling Roman");
    }

    public override House GetHouse()
    {
        return RomanHouse;
    }
}





控制台输出结果:

Wall Chinese
Ceiling Chinese
Door Chinese
Windows Chinese
Floor Chinese
鲁班



建造者模式、抽象工厂模式的区别





  • 建造者模式返回一个按一定规则组装的完整产品 ,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族。

  • 建造者模式讨论的主体是Builder,而抽象工厂模式讨论的主体是产品。例如本例中可以这样用抽象工厂模式替代:

<span style="white-space:pre">	</span>ChineseHouse :House<span style="white-space:pre">	</span>

<span style="white-space:pre">	</span>RomanHouse:House
但是这样虽然获得两个不同的房子,但是算法的侧重点不一样了。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值