详解C#设计模式编程中生成器模式的使用
程序员文章站
2022-05-25 23:10:22
一、概述
在软件系统中,有时候面临着复杂的对象创建,该对象由一定算法构成的子对象组成,由于需求变化,这些子对象会经常变换,但组合在一起的算法却是稳定的。生成器模式可以处理...
一、概述
在软件系统中,有时候面临着复杂的对象创建,该对象由一定算法构成的子对象组成,由于需求变化,这些子对象会经常变换,但组合在一起的算法却是稳定的。生成器模式可以处理这类对象的构建,它提供了一种封装机制来隔离各类子对象的变化,从而保证系统的稳定。
二、生成器模式
生成器模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。其结构图如下:
- 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#实现图片加相框的方法
下一篇: 浅析Android加载字体包及封装的方法