首页 > 编程 > C# > 正文

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

2020-01-24 01:15:39
字体:
来源:转载
供稿:网友

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

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

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

 

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表