设计模式学习之Builder模式

  

  这篇随笔的关注点是Builder(创建者、生成器)模式:适用的场景是产品局部加工变化较大,但是组装过程相对固定。创建者模式和工厂模式有点类似,不过关注点不同。工厂模式往往只关心你要的是什么,而创建模式则关心的是这个东西的具体细节的创建。例如:

  • 攒机。尽管上网本、游戏PC的形态、功能相差比较大,但是它们都有必须的主板、内存、硬盘、显示器、外设等不同的元件,而且组装工程相对固定
  • 搭建简单的门户网站。导航条、搜索框、页面主体、页脚的设计和实现千差外别,但是它们都经过类似的组装过程,最终形成Web Site

 

 

  网上找了一张图,很好的表示了经典创建者模式的静态结构,其中包含3个角色:

  • Director:指导产品的加工步骤,但指导完全基于Builder的抽象方法
  • Builder:描述创建一个产品各个组成部分的抽象类
  • ConcreteBuilder:实现Builder要求的内容,提供一个获得最终产品的方法

    最终加工的产品类型并没有统一抽象为IProduct接口,主要原因是经过不同的ConcreteBuilder加工后的产品产别性对比较大,没必要给一个公共的基准抽象对象。针对特定类型的产品,设计特定的ConcreteBuilder

  下面直接上例子吧,需求如下:

  • 制造一些交通工具,具备轮子和车灯
  • 汽车:前后各2个轮子(共4个),前后各2个车灯(共4个);自行车:前后轮(共2个),无车灯(null)

定义目标产品

1     public class Vehicle
2     {
3         public IEnumerable<string> Wheels { getset; }
4         public IEnumerable<string> Lights { getset; }
5     }

定义抽象创建者类型

1     public abstract class VehicleBuilderBase
2     {
3         public Vehicle Vehicle { getprotected set; }
4         public virtual void Create() { Vehicle = new Vehicle(); }
5         public abstract void AddWheels();
6         public abstract void AddLights();
7     }

定义具体的创建者类型

 1     public class CarBuilder:VehicleBuilderBase
 2     {
 3         public override void AddWheels()
 4         {
 5             Vehicle.Wheels = new string[] { "front1""front2""back1""back2" };
 6         }
 7 
 8         public override void AddLights()
 9         {
10             Vehicle.Lights = new string[] { "front1""front2""back1""back2" };
11         }
12     }


 1     class BicycleBuilder:VehicleBuilderBase
 2     {
 3         public override void AddWheels()
 4         {
 5             Vehicle.Wheels = new string[] { "front""back" };
 6         }
 7 
 8         public override void AddLights()
 9         {
10             Vehicle.Lights = null;
11         }
12     }

定义产品生产指导类

 1     public class VehicleBuilderDirector
 2     {
 3         public VehicleBuilderBase Builder { getset; }
 4         public Vehicle Vehicle { get { return Builder.Vehicle; } }
 5 
 6         public void Construct()
 7         {
 8             Builder.Create();
 9             Builder.AddLights();
10             Builder.AddWheels();
11         }
12     }

 

 

单元测试

 1         [TestMethod()]
 2         public void BuildUpTest()
 3         {
 4             var director = new VehicleBuilderDirector();
 5             director.Builder = new CarBuilder();
 6             director.Construct();
 7             Assert.AreEqual<int>(4, director.Vehicle.Wheels.Count());
 8             Assert.AreEqual<int>(4, director.Vehicle.Lights.Count());
 9 
10             director.Builder = new BicycleBuilder();
11             director.Construct();
12             Assert.AreEqual<int>(2, director.Vehicle.Wheels.Count());
13             Assert.IsNull(director.Vehicle.Lights);
14         }

 

     到目前为止,目标已经初步实现了,但是创建者模式暴露出较多的执行步骤,Director(Client)需要较多的领域知识,很容易造成高耦合。

 

 

 

posted @ 2012-09-03 17:49  Hans Huang  Views(458)  Comments(0Edit  收藏  举报