设计模式读书笔记(四)——生成器模式

一、Builder模式的缘起(也就是需求)

       1、假设创建游戏中的一个房屋House设施,该房屋的构建由几个部分组成,且各个部分要富于变化。

       2、如果使用最直观的设计方法,每一个房屋部分的变化,都将导致房屋构建的重新修正......

二、动机

        在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成,由于需要的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

       如何应对这种变化,如何提供一种“封装机制”来隔离出“复杂对象各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需要的变化而变化。

三、类图

四、代码

        1、Build.cs

namespace Builder
{
    public abstract class House
    {
 
    }

    public abstract class Door
    {

    }

    public abstract class Wall
    {

    }

    public abstract class Windows
    {

    }

    public abstract class Floor
    {

    }

    public abstract class HouseCelling
    {

    }
   
    public abstract class Builder
    {
        public abstract void BuildDoor();
        public abstract void BuildWall();
        public abstract void BuildWindows();
        public abstract void BuildFloor();
        public abstract void BuildHouseCelling();

        public abstract House GetHouse();
    }  
}

     2、RomaHouse.cs

namespace Builder
{
    public class RomaHouse:House
    {
        public RomaHouse()
        {
            Console.WriteLine("/n建设罗马式房屋");
        }
    }
    public class RomaDoor : Door
    {
        public RomaDoor()
        {
            Console.WriteLine("/n建设罗马式门");
        }
    }
    public class RomaWall : Wall
    {
        public RomaWall()
        {
            Console.WriteLine("/n建设罗马式墙");
        }
    }
    public class RomaWindows : Windows
    {
        public RomaWindows()
        {
            Console.WriteLine("/n建设罗马式窗");
        }
    }
    public class RomaFloor : Floor
    {
        public RomaFloor()
        {
            Console.WriteLine("/n建设罗马式地板");
        }
    }
    public class RomaHouseCelling : HouseCelling
    {
        public RomaHouseCelling()
        {
            Console.WriteLine("/n建设罗马式屋顶");
        }
    }

    public class RomaHouseBuilder : Builder
    {
        public override void BuildDoor()
        {
            Door door = new RomaDoor();
            Console.WriteLine("/n罗马式门建成了");
        }
        public override void BuildWall()
        {
            Wall wall = new RomaWall();
            Console.WriteLine("/n罗马式墙建成了");
        }
        public override void BuildWindows()
        {
            Windows windows = new RomaWindows();
            Console.WriteLine("/n罗马式窗建成了");
        }
        public override void BuildFloor()
        {
            Floor floor = new RomaFloor();
            Console.WriteLine("/n罗马式地板建成了");
        }
        public override void BuildHouseCelling()
        {
            HouseCelling housecelling = new RomaHouseCelling();
            Console.WriteLine("/n罗马式屋顶建成了");
        }
        public override House GetHouse()
        {
            return new RomaHouse();
           
        }
    }
}

     3、GameManager.cs


namespace Builder
{
    public class GameManager
    {
        public static House CreateHouse(Builder builder)
        {
            builder.BuildDoor();

            builder.BuildWall();

            builder.BuildWindows();

            builder.BuildFloor();

            builder.BuildHouseCelling();

            return builder.GetHouse();
        }
    }
}

4、Client.cs


namespace Builder
{
    class App
    {
        public static void Main()
        {
            string builderName = ConfigurationSettings.AppSettings["BuildName"].ToString();
            string assemblyName = ConfigurationSettings.AppSettings["BuildAssembly"].ToString();
            Assembly assembly = Assembly.Load(assemblyName);

            Type t = assembly.GetType(builderName);
            Builder builder = (Builder)Activator.CreateInstance(t);
           
            House house = GameManager.CreateHouse(builder);

            Console.ReadLine();
        }
    }
}

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="BuildName" value="Builder.RomaHouseBuilder"></add>
    <add key="BuildAssembly" value="Builder"></add>
  </appSettings>
</configuration>

五、代码分析

       首先看看运行结果:

       大家看代码之后也许会认为,生成器模式与抽象工厂模式几乎没什么区别,没错,确实很相似,现在我来谈谈不同之处。

       首先我们来从代码谈起,大家注意两种模式最大的不同就是GameManager.cs这个类,生成器模式中的GameManager类中各个子对象都互不相干,由各个子对象来生成一个大的对象;而抽象工厂模式GameManager类中各个对象是耦合的,大家注意到Building类中building(Road road)方法没有(也许游戏场景中房屋下面有路)

      下面总结一下两种模式是不同:

       生成器模式解决“对象部分”的需求变化,如例中假设房屋里面加上一个床,那将是相当方便的,只需要新增一个床类,然后在GameManager中加上builder.BuildBed()就ok了。

       抽象工厂模式解决是“系列对象”的需求变化,如例中只有在道路,房屋,地道,丛林这四种均不会变化的情况下才适用,假设再加一个沙漠或者是海洋什么的,这种模式就不适用了。

       最后说明一点,在App.config中有两个地方可由用户配置程序集和类名,main方法中利用反射机制根据程序集和类名实例化一个类对象,这样就可以很方便地修改房屋的风格(比如当前是Roma风格的,您也可以新增一个China风格的)

 

 http://blog.sina.com.cn/u/495615e7010004zm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值