《模式——工程化实现及扩展》(设计模式C# 版)《创建者模式 Builder》——正文完整示例

转自:《模式——工程化实现及扩展》(设计模式C# 版)
http://www.cnblogs.com/callwangxiang/

 

 


本章正文通过Attribute指导Builder构造过程的完整示例

 

 

1、采用BuildStep定义装配过程的测试类型

 

    #region 采用BuildStep定义装配过程的测试类型

    
/// <summary>
    
/// 用于显示测试结果的委托
    
/// </summary>
    
/// <remarks>
    
///     Action<string>是实际处理Build Step操作内容的委托
    
/// </remarks>
    static Action<string, Action<string>> buildStepHandler = (x, y) =>
    {
        Trace.WriteLine(
"add " + x);
        y(x);
    };

    
class Car
    {
        
public IList<string> Parts { getprivate set; }
        
public Car(){Parts = new List<string>();}

        
/// <summary>
        
/// 为汽车添加轮胎
        
/// </summary>
        
/// <remarks>
        
///     Attributed Builder第二个执行的Setp
        
///     执行4次,即为每辆汽车装配增加4个轮胎
        
/// </remarks>
        [BuildStep(24)]
        
public void AddWheel() { buildStepHandler("wheel", Parts.Add); }

        
/// <summary>
        
/// 为汽车装配引擎
        
/// </summary>
        
/// <remarks>
        
///     没有通过Attribute标注的内容,因此不会被Attributed Builder执行
        
/// </remarks>
        public void AddEngine() { buildStepHandler("engine", Parts.Add); }

        
/// <summary>
        
/// 为汽车装配车身
        
/// </summary>
        
/// <remarks>
        
///     Attributed Builder第一个执行的Setp
        
///     执行1次,即为每辆汽车装配增加1个车身
        
/// </remarks>
        [BuildStep(1)]
        
public void AddBody() { buildStepHandler("body", Parts.Add); }
    }

    
class Computer
    {
        
public string Bus { getprivate set; }
        
public string Monitor { getprivate set; }
        
public string Disk { getprivate set; }
        
public string Memory { getprivate set; }
        
public string Keyboard { getprivate set; }
        
public string Mouse { getprivate set; }

        
/// <summary>
        
/// 缓存Computer类型的所有Property
        
/// </summary>
        static PropertyInfo[] properties = typeof (Computer).GetProperties();

        
/// <summary>
        
/// 获得Computer类型指定名称Property的Setter方法委托
        
/// </summary>
        
/// <param name="target">Computer类型实例</param>
        
/// <param name="name">Property名称</param>
        
/// <returns>指定名称Property的Setter方法委托</returns>
        static Action<string> GetSetter(Computer target, string name)
        {
            var property 
= properties.Where(x => string.Equals(x.Name, name)).FirstOrDefault();
            
return x => property.SetValue(target, x, null);
        }

        [BuildStep(
1)]
        
public void LayoutBus()
        {
            buildStepHandler(
"bus", GetSetter(this"Bus"));
        }

        [BuildStep(
2)]
        
public void AddDiskAndMemory()
        {
            buildStepHandler(
"disk", GetSetter(this"Disk"));
            buildStepHandler(
"16G memory", GetSetter(this"Memory"));
        }

        [BuildStep(
3)]
        
public void AddUserInputDevice()
        {
            buildStepHandler(
"USB mouse", GetSetter(this"Mouse"));
            buildStepHandler(
"keyboard", GetSetter(this"Keyboard"));
        }

        [BuildStep(
4)]
        
public void ConnectMonitor()
        {
            buildStepHandler(
"monitor", GetSetter(this"Monitor"));
        }
    }

    
#endregion

 

 

 2、执行单元测试

[TestMethod]
public void BuildComputerByAttributeDirection()
{
    Trace.WriteLine(
"\nassembly computer");
    var computer 
= new Computer();
    Assert.IsNull(computer.Keyboard);
    Assert.IsNull(computer.Memory);
    computer 
= new Builder<Computer>().BuildUp();
    Assert.IsNotNull(computer.Bus);
    Assert.IsNotNull(computer.Monitor);
    Assert.IsNotNull(computer.Disk);
    Assert.IsNotNull(computer.Memory);
    Assert.IsNotNull(computer.Keyboard);
    Assert.IsNotNull(computer.Mouse);
}

[TestMethod]
public void BuildCarByAttributeDirection()
{
    Trace.WriteLine(
"build car");
    var car 
= new Builder<Car>().BuildUp();
    Assert.IsNotNull(car);
    Assert.IsFalse(car.Parts.Contains(
"engine")); // 不会被执行的内容
    Assert.AreEqual<string>("body", car.Parts.ElementAt(0));
    
for (var i = 1; i <= 4; i++)
        Assert.AreEqual
<string>("wheel", car.Parts.ElementAt(i));
}

 

 3、Output窗口输出内容

------ Test started: Assembly: Builder.Tests.dll ------


assembly computer
add bus
add disk
add 16G memory
add USB mouse
add keyboard
add monitor

build car
add body
add wheel
add wheel
add wheel
add wheel

2 passed, 0 failed, 0 skipped, took 0.70 seconds (MSTest 10.0).

 

 

 

 

posted @ 2011-05-17 09:23  蜡笔小王  阅读(1485)  评论(2编辑  收藏  举报