前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >温故而知新:设计模式之Builder

温故而知新:设计模式之Builder

作者头像
菩提树下的杨过
发布2018-01-22 16:24:06
4340
发布2018-01-22 16:24:06
举报

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

客户端程序依赖于上面的抽象:

代码

/// <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();
        }
    }

最后完成具体模板的实现 :

代码

#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

我们还是利用反射来解除最终具体类型的依赖:

代码

<?xml version="1.0" encoding="utf-8" ?>
<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();
        }
    }

}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2010-01-19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档