详解C#设计模式编程中生成器模式的使用

 更新时间:2016年02月25日 09:23:30   作者:scucj  
这篇文章主要介绍了详解C#设计模式编程中生成器模式的使用,生成器模式主张创建对象的过程和对象的表现应该分离开来,需要的朋友可以参考下

一、概述
在软件系统中,有时候面临着复杂的对象创建,该对象由一定算法构成的子对象组成,由于需求变化,这些子对象会经常变换,但组合在一起的算法却是稳定的。生成器模式可以处理这类对象的构建,它提供了一种封装机制来隔离各类子对象的变化,从而保证系统的稳定。
二、生成器模式
生成器模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。其结构图如下:

201622592147347.gif (424×179)

  • Builder为创建Product对象的各个子对象指定抽象接口。
  • ConcreteBuilder实现了Builder接口,用于创建Product对象的各个子对象。
  • Director使用Builder来创建Product对象。
  • Product表示被构造的复杂对象。


三、示例

using System;
using System.Collections.Generic;
using System.Text;

namespace BuilderPattern
{
  /// <summary>
  /// 所有课程
  /// </summary>
  public class Coures
  {    
    /// <summary>
    /// 保存课程信息
    /// </summary>
    IDictionary<string, decimal> coures = new Dictionary<string, decimal>();

    /// <summary>
    /// 选课
    /// </summary>
    /// <param name="serialNumber"></param>
    /// <param name="score"></param>
    public void Select(string serialNumber, decimal score)
    {
      coures.Add(serialNumber, score);
    }

    /// <summary>
    /// 计算总学分
    /// </summary>
    /// <returns>总学分</returns>
    public decimal ComputeScores()
    {
      decimal scores = 0;
      foreach (KeyValuePair<string, decimal> kvp in coures) 
      {  
        Console.WriteLine(kvp.Key + ":" + kvp.Value);
        Console.WriteLine(" ");
        scores += kvp.Value;
      }
      return scores;
    }
  }
  
  /// <summary>
  /// 选课建造者抽象类,表现(下面的抽象函数)是相对稳定的。
  /// </summary>
  public abstract class Builder
  {
    /// <summary>
    /// 必修课程成绩
    /// </summary>
    public abstract void BuildCompulsory();

    /// <summary>
    /// 选修课程成绩
    /// </summary>
    public abstract void BuildElective();

    /// <summary>
    /// 限制课程成绩
    /// </summary>
    public abstract void BuildRestriction();

    /// <summary>
    /// 获得课程字典对象
    /// </summary>
    /// <returns></returns>
    public abstract Coures GetCoures();
  }

  /// <summary>
  /// 本科生选课成绩
  /// </summary>
  public class UndergraduateBuilder : Builder
  {
    private Coures coures = new Coures();

    /// <summary>
    /// 本科生选必修课程成绩
    /// </summary>
    public override void BuildCompulsory()
    {
      coures.Select("001", 80M);
    }

    /// <summary>
    /// 本科生选选修课程成绩
    /// </summary>
    public override void BuildElective()
    {
      coures.Select("101", 85M);
    }

    /// <summary>
    /// 本科生选限制课程成绩
    /// </summary>
    public override void BuildRestriction()
    {
      coures.Select("201", 95M);
    }

    /// <summary>
    /// 本科生选获得课程字典对象
    /// </summary>
    /// <returns></returns>
    public override Coures GetCoures()
    {
      return coures;
    }
  }

  /// <summary>
  /// 研究生选课成绩
  /// </summary>
  public class GraduateBuilder : Builder
  {
    private Coures coures = new Coures();

    /// <summary>
    /// 研究生选必修课程成绩
    /// </summary>
    public override void BuildCompulsory()
    {
      coures.Select("S001", 70M);
    }

    /// <summary>
    /// 研究生选选修课程成绩
    /// </summary>
    public override void BuildElective()
    {
      coures.Select("S101", 75M);
    }

    /// <summary>
    /// 研究生选限制课程成绩
    /// </summary>
    public override void BuildRestriction()
    {
      coures.Select("S201", 80M);
    }

    /// <summary>
    /// 研究生选获得课程字典对象
    /// </summary>
    /// <returns></returns>
    public override Coures GetCoures()
    {
      return coures;
    }
  }

  /// <summary>
  /// 课程成绩管理类
  /// </summary>
  public class CourseScoresManager
  {
    /// <summary>
    /// 这里的参数便是未确定的
    /// </summary>
    /// <param name="builder"></param>
    public void CourseScoresManager(Builder builder)
    {
      builder.BuildCompulsory();
      builder.BuildElective();
      builder.BuildRestriction();
    }
  }

  class Program
  {
    static void Main(string[] args)
    {      
      /* Builder instance = new UndergraduateBuilder(); */
      Builder instance = new GraduateBuilder();
      CourseScoresManager courseScoresManager = new CourseScoresManager(instance);
      Coures coures = instance.GetCoures();
      decimal totalScores = coures.ComputeScores();
      Console.WriteLine(totalScores);
      Console.WriteLine(" ");
      Console.ReadLine();
    }
  }
}

四、使用场景
      应用场景是当创建一个复杂的对象时,这个对象由各个子对象构成,而由于需求的变化导致子对象的性质也是未确定的。
 我们一般为一个类提供构造函数,并利用这个构造函数完成对象的创建工作。当客户知道为哪个类创建实例,并知道构造函数的参数时(假设是用带参数的构造函数)。然而由于条件的现限制,是无法用通常的方式来构造对象的实例! 在进行对象构造之前,要逐步收集与构造相关的信息.那么创建对象的过程和对象的表现就应该分离开来。此时对象的表现是相对稳定的。

 

相关文章

  • 基于C# 生成Zip压缩包代码

    基于C# 生成Zip压缩包代码

    压缩包制作也是很多项目中需要用到的功能。接下来通过本文给大家介绍基于C# 生成Zip压缩包代码,对c生成zip压缩包相关知识感兴趣的朋友一起学习吧
    2016-04-04
  • c#中XML解析文件出错解决方法

    c#中XML解析文件出错解决方法

    在解析xml时,经常因为文件中含特殊字符而解析失败。原因有两个:一是内容中含有XML预定义好的实体,二是内容中含有低位非打印字符
    2014-08-08
  • C#实现弹窗提示输入密码

    C#实现弹窗提示输入密码

    这篇文章主要为大家详细介绍了C#实现弹窗提示输入密码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • DevExpress GridView自动滚动效果

    DevExpress GridView自动滚动效果

    这篇文章主要为大家详细介绍了DevExpress GridView自动滚动效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • C#和lua相互调用的方法教程

    C#和lua相互调用的方法教程

    lua是一种脚本语言,可以方便的移植到各种宿主语言中,并且可以支持热更新,在游戏开发中也能当做主要的语言来编写游戏的逻辑,所以这篇文章主要给大家介绍了关于C#和lua相互调用的方法教程,需要的朋友可以参考下。
    2017-11-11
  • C# 中使用 Exceptionless的方法

    C# 中使用 Exceptionless的方法

    这篇文章主要介绍了C# 中使用 Exceptionless的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下
    2020-12-12
  • C#中使用强制类型实现字符串和ASCII码之间的转换

    C#中使用强制类型实现字符串和ASCII码之间的转换

    这篇文章主要介绍了C#中使用强制类型实现字符串和ASCII码之间的转换,本文还给出了另一种方法,需要的朋友可以参考下
    2014-08-08
  • C#多线程数组模拟socket

    C#多线程数组模拟socket

    这篇文章主要为大家详细介绍了C#多线程数组模拟socket的相关代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • C#图像处理之头发检测的方法

    C#图像处理之头发检测的方法

    这篇文章主要介绍了C#图像处理之头发检测的方法,可实现针对图像中头发的检测功能,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • 如何在c#中使用opencv函数库

    如何在c#中使用opencv函数库

    这篇文章主要介绍了如何在c#中使用opencv,对图像匹配处理感兴趣的同学可以参考下
    2021-04-04

最新评论