Builder模式

来源:互联网 发布:网架设计软件 编辑:程序博客网 时间:2024/05/17 07:23


 Builder模式的结构:

 

建造者(Builder)角色:给出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者(ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的方法:一个是建造方法,另一个是结果返还方法。

具体建造者(Concrete Builder)角色:担任这个角色的是于应用程序紧密相关的类,它们在应用程序调用下创建产品实例。这个角色主要完成的任务包括:

  • 实现Builder角色提供的接口,一步一步完成创建产品实例的过程。
  • 在建造过程完成后,提供产品的实例。

指导者(Director)角色:担任这个角色的类调用具体建造者角色以创建产品对象。导演者并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者对象。

产品(Product)角色:产品便是建造中的复杂对象。

指导者角色是于客户端打交道的角色。导演者角色将客户端创建产品的请求划分为对各个零件的建造请求,再将这些请求委派给具体建造者角色。具体建造者角色是做具体建造工作的,但却不为客户端所知。

 

Builder模式所面对的情况是:各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将他们组合在一起的算法却相对稳定。简单的说:子对象变化较频繁,对算法相对稳定。

 


      Builder生成器模式是一种创建型模式,它主要是应对项目中一些复杂对象的创建工作。所谓“复杂对象”,是指:此对象中还含有其它的子对象。Builder模式所面对的情况是:各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将他们组合在一起的算法却相对稳定。简单的说:子对象变化较频繁,对算法相对稳定。
       这是解决一个复杂对象的创建工作,现在变化的部分和相对稳定的部分已经明确,我们要做的是隔离变化,如何将子对象和算法隔离是要解决的问题。
       《设计模式》中说道:将一个复杂对象的构建与其表示向分离,使得同样的构建过程可以创建不同的表示。
       我们现在定义一个场景:还是选择汽车,BMW和BORA。试想一下,如果我们用较为普通的写法可以写成如下代码:
public static void Main()
        {
            Car car = new Car();
            Console.Write("Wheel:" + car._wheel + "/n");
            Console.Write("OilBox:" + car._oilBox + "/n");
            Console.Write("Body:" + car._body + "/n");
            Console.Read();
        }
 
        public class Car
        {
            public string _wheel = “BMWWheel”;
            public string _oilbox = “BMWOilBox”;
            public string _body = “BMWBody”;
}
当我们不确定或因需求变化而改变对汽车品牌的选择时,我们也许会频繁的更改Car类中的实现。
现在我们用Manager来管理汽车的构建。当然是构建一个抽象的类对象(对象如下图的builder,抽象类为AbstractBuilder),对于BMW和BORA的构建类型继承AbstractBuilder类

 

首先我们先来编写AbstractBuilder抽象类的实现,代码如下:
public abstract class AbstractBuilder
    {
        public string _wheel;
        public string _oilBox;
        public string _body;
        public abstract void BuildWheel();
        public abstract void BuildOilBox();
        public abstract void BuildBody();
 
        public abstract Car GetCar();  
    }
 
    public abstract class Car
    {
    }
然后我们再来实现BMW和BORA的构建,也就是Builder模式中频繁变化的部分,他们都要继承AbstractBuilder
BMW:
public class BMWBuilder:AbstractBuilder
    {
        public BMWBuilder()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }
 
        public override void BuildWheel()
        {
            _wheel = "BMWWheel";
        }
 
        public override void BuildOilBox()
        {
            _oilBox = "BMWOilBox";
        }
 
        public override void BuildBody()
        {
            _body = "BMWBody";
        }
 
        public override Car GetCar()
        {
            return new BMWCar();
        }
 
    }
 
    public class BMWCar:Car
    {}
BORA:
public class BORABuilder:AbstractBuilder
    {
        public BORABuilder()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }
 
        public override void BuildWheel()
        {
            _wheel = "BORAWheel";
        }
 
        public override void BuildOilBox()
        {
            _oilBox = "BORAOilBox";
        }
 
        public override void BuildBody()
        {
            _body = "BORABody";
        }
 
        public override Car GetCar()
        {
            return new BORACar();
        }
    }
 
    public class BORACar:Car
    {}
现在我们使用一种Manager方法来管理汽车的构建,这也就是Builder模式中提到的相对稳定的算法,我用一个类来实现:
private class CarManager
        {
            public BuilderClass.Car CreateCar(BuilderClass.AbstractBuilder builder)
            {
                builder.BuildBody();
                builder.BuildOilBox();
                builder.BuildWheel();
 
                Console.Write("Wheel:" + builder._wheel + "/n");
                Console.Write("OilBox:" + builder._oilBox + "/n");
                Console.Write("Body:" + builder._body + "/n");
                Console.Read();
                return builder.GetCar();
            }
        }
现在我们可以在客户程序中调用这个Manager来构建Car:
public static void Main()
        {
            CarManager manager = new CarManager();
            BuilderClass.Car car =
manager.CreateCar(new BuilderClass.BORABuilder());
        }
结果如下:
Wheel:BORAWheel
OilBox:BORAOilBox
Body:BORABody
如果我们现在要换成BMW,我们只要在Main()函数中改变manager.CreateCar中的参数就可以:
public static void Main()
        {
            CarManager manager = new CarManager();
            BuilderClass.Car car = 
manager.CreateCar(new BuilderClass.BMWBuilder());
        }
结果如下:
Wheel:BMWWheel
OilBox:BMWOilBox
Body:BMWBody
这样,经过简单的修改可以实现对不同Car的构建。如果我们还有其他汽车的实现只要将他的类继承AbstractBuilder,然后在Main()中修改就可以。说道这里,我想起了在第一篇中提到的设计模式中的“开---闭原则”,这个方式是很符合这个原则的,对代码进行了扩展,以减少了代码修改量。而且我们还有很多方法可以利用,如:WebConfig中的appSettings来动态的配置,从数据库中读取,或利用依赖方式动态生成。
现在我们再来看看Builder模式的几个要点:
Builder模式主要用于构建一个复杂的对象,但这个对象构建的算法是稳定的,对象中的各个部分经常变化。Builder模式主要在于应对复杂对象各个部分的频繁需求变动。但是难以应对算法的需求变动。这点一定要注意,如果用错了,会带来很多不必要的麻烦。
课程中还提到了.Net中的Builder模式的应用。如:Page类中的OnInit()等方法的实现。我们在写一个Web页面的时候。他的codebehind代码都是继承System.Web.UI.Page基类的。OnInit()函数是可以重写的
 
原创粉丝点击