zoukankan      html  css  js  c++  java
  • 温故而知新:设计模式之Builder

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

    }

     

    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    公司初创期使用 PHP,为什么很多公司都会慢慢转型到 JAVA
    Firefox 如何对发送的参数进行调试
    Spring security CSRF 跨域访问限制问题
    IntelliJ IDEA 的 Maven 如何设置自动下载源代码和文档
    Spring 的 WebSecurityConfigurerAdapter 过滤器
    Java NIO Path 接口
    Joda-Time – 可用的时区列表
    JWT 如何解码和获得令牌失效的日期
    MySQL索引相关操作
    详细了解INNODB_TRX、INNODB_LOCKs、INNODB_LOCK_waits、PROCESSLIST表
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1651712.html
Copyright © 2011-2022 走看看