Builder模式主要用于以下场景:
需要创建一个较复杂的大对象实例,并且构成该对象的子对象可能经常会发生变化,但是组成大对象的算法却相对稳定。
比如:我们做b/s开发时,经常会遇到一些系统要求支持模板/皮肤切换,一个完整的页面由若干子模块组成,不管模板如何变换,子模块的内容/位置如何变化,但组成页面的算法即相对固定。
我们假定每个页面由header,body,footer三个基本模块组成,先抽象出来:


#region
把不依赖具体细节的部分(即相当稳定,不变的部分)抽象出来
public interface IShow
{
void Show();
}
/// <summary>
/// 页面头部 抽象类
/// </summary>
public abstract class Header : IShow
{
public abstract void Show();
}
/// <summary>
/// 页面主体 抽象类
/// </summary>
public abstract class Body : IShow
{
public abstract void Show();
}
/// <summary>
/// 页面底部 抽象类
/// </summary>
public abstract class Footer : IShow
{
public abstract void Show();
}
/// <summary>
/// 页面基类 抽象类
/// </summary>
public class MainPage
{
private List < IShow > _lstParts;
public List < IShow > Parts
{
set { _lstParts = value; }
get
{
if (_lstParts == null )
{
_lstParts = new List < IShow > ();
}
return _lstParts;
}
}
public void Show()
{
for ( int i = 0 ; i < _lstParts.Count; i ++ )
{
_lstParts[i].Show();
}
Console.Write( " 页面构建完毕! " );
}
}
/// <summary>
/// 创建器 抽象类
/// </summary>
public abstract class Builder
{
// 不管页面风格如何变换,下面的这些部件的创建算法,相对要求比较稳定
public abstract void BuildHeader();
public abstract void BuildBody();
public abstract void BuildFooter();
public abstract MainPage GetPage();
}
#endregion
public interface IShow
{
void Show();
}
/// <summary>
/// 页面头部 抽象类
/// </summary>
public abstract class Header : IShow
{
public abstract void Show();
}
/// <summary>
/// 页面主体 抽象类
/// </summary>
public abstract class Body : IShow
{
public abstract void Show();
}
/// <summary>
/// 页面底部 抽象类
/// </summary>
public abstract class Footer : IShow
{
public abstract void Show();
}
/// <summary>
/// 页面基类 抽象类
/// </summary>
public class MainPage
{
private List < IShow > _lstParts;
public List < IShow > Parts
{
set { _lstParts = value; }
get
{
if (_lstParts == null )
{
_lstParts = new List < IShow > ();
}
return _lstParts;
}
}
public void Show()
{
for ( int i = 0 ; i < _lstParts.Count; i ++ )
{
_lstParts[i].Show();
}
Console.Write( " 页面构建完毕! " );
}
}
/// <summary>
/// 创建器 抽象类
/// </summary>
public abstract class Builder
{
// 不管页面风格如何变换,下面的这些部件的创建算法,相对要求比较稳定
public abstract void BuildHeader();
public abstract void BuildBody();
public abstract void BuildFooter();
public abstract MainPage GetPage();
}
#endregion
客户端程序依赖于上面的抽象:


///
<summary>
/// 客户程序
/// </summary>
public class PageManager
{
Builder _builder;
public PageManager(Builder b)
{
this ._builder = b;
}
public void Show()
{
this ._builder.BuildHeader();
this ._builder.BuildBody();
this ._builder.BuildFooter();
this ._builder.GetPage().Show();
}
}
/// 客户程序
/// </summary>
public class PageManager
{
Builder _builder;
public PageManager(Builder b)
{
this ._builder = b;
}
public void Show()
{
this ._builder.BuildHeader();
this ._builder.BuildBody();
this ._builder.BuildFooter();
this ._builder.GetPage().Show();
}
}
最后完成具体模板的实现 :


#region
spring风格的具体页面及创建器
public class SpringHeader : Header
{
public override void Show()
{
Console.WriteLine( " Spring风格的header " );
}
}
public class SpringBody : Body
{
public override void Show()
{
Console.WriteLine( " Spring风格的body " );
}
}
public class SpringFooter : Footer
{
public override void Show()
{
Console.WriteLine( " Spring风格的footer " );
}
}
public class SpringBuilder : Builder
{
MainPage _mainPage;
public SpringBuilder()
{
_mainPage = new MainPage();
}
public override void BuildHeader()
{
_mainPage.Parts.Add( new SpringHeader());
}
public override void BuildBody()
{
_mainPage.Parts.Add( new SpringBody());
}
public override void BuildFooter()
{
_mainPage.Parts.Add( new SpringFooter());
}
public override MainPage GetPage()
{
return _mainPage;
}
}
#endregion
#region summer风格的具体页面及创建器
public class SummerHeader : Header
{
public override void Show()
{
Console.WriteLine( " Summer风格的header " );
}
}
public class SummerBody : Body
{
public override void Show()
{
Console.WriteLine( " Summer风格的body " );
}
}
public class SummerFooter : Footer
{
public override void Show()
{
Console.WriteLine( " Summer风格的footer " );
}
}
public class SummerBuilder : Builder
{
MainPage _mainPage;
public SummerBuilder()
{
_mainPage = new MainPage();
}
public override void BuildHeader()
{
_mainPage.Parts.Add( new SummerHeader());
}
public override void BuildBody()
{
_mainPage.Parts.Add( new SummerBody());
}
public override void BuildFooter()
{
_mainPage.Parts.Add( new SummerFooter());
}
public override MainPage GetPage()
{
return _mainPage;
}
}
#endregion
public class SpringHeader : Header
{
public override void Show()
{
Console.WriteLine( " Spring风格的header " );
}
}
public class SpringBody : Body
{
public override void Show()
{
Console.WriteLine( " Spring风格的body " );
}
}
public class SpringFooter : Footer
{
public override void Show()
{
Console.WriteLine( " Spring风格的footer " );
}
}
public class SpringBuilder : Builder
{
MainPage _mainPage;
public SpringBuilder()
{
_mainPage = new MainPage();
}
public override void BuildHeader()
{
_mainPage.Parts.Add( new SpringHeader());
}
public override void BuildBody()
{
_mainPage.Parts.Add( new SpringBody());
}
public override void BuildFooter()
{
_mainPage.Parts.Add( new SpringFooter());
}
public override MainPage GetPage()
{
return _mainPage;
}
}
#endregion
#region summer风格的具体页面及创建器
public class SummerHeader : Header
{
public override void Show()
{
Console.WriteLine( " Summer风格的header " );
}
}
public class SummerBody : Body
{
public override void Show()
{
Console.WriteLine( " Summer风格的body " );
}
}
public class SummerFooter : Footer
{
public override void Show()
{
Console.WriteLine( " Summer风格的footer " );
}
}
public class SummerBuilder : Builder
{
MainPage _mainPage;
public SummerBuilder()
{
_mainPage = new MainPage();
}
public override void BuildHeader()
{
_mainPage.Parts.Add( new SummerHeader());
}
public override void BuildBody()
{
_mainPage.Parts.Add( new SummerBody());
}
public override void BuildFooter()
{
_mainPage.Parts.Add( new SummerFooter());
}
public override MainPage GetPage()
{
return _mainPage;
}
}
#endregion
我们还是利用反射来解除最终具体类型的依赖:


<?
xml version="1.0" encoding="utf-8"
?>
< configuration >
< appSettings >
< add key ="AssemblyName" value ="Builder" />
< add key ="BuilderType" value ="Builder.SpringBuilder" />
</ appSettings >
</ configuration >
< configuration >
< appSettings >
< add key ="AssemblyName" value ="Builder" />
< add key ="BuilderType" value ="Builder.SpringBuilder" />
</ appSettings >
</ configuration >
主程序


using
System;
using System.Collections.Generic;
using System.Reflection;
using System.Configuration;
namespace Builder
{
class Program
{
static void Main( string [] args)
{
Builder bdr = (Builder)Assembly.Load(ConfigurationManager.AppSettings[ " AssemblyName " ].ToString()).CreateInstance(ConfigurationManager.AppSettings[ " BuilderType " ].ToString());
PageManager pm = new PageManager(bdr);
pm.Show();
Console.Read();
}
}
}
using System.Collections.Generic;
using System.Reflection;
using System.Configuration;
namespace Builder
{
class Program
{
static void Main( string [] args)
{
Builder bdr = (Builder)Assembly.Load(ConfigurationManager.AppSettings[ " AssemblyName " ].ToString()).CreateInstance(ConfigurationManager.AppSettings[ " BuilderType " ].ToString());
PageManager pm = new PageManager(bdr);
pm.Show();
Console.Read();
}
}
}