一、概述
在軟件系統中,有時候面臨著復雜的對象創建,該對象由一定算法構成的子對象組成,由于需求變化,這些子對象會經常變換,但組合在一起的算法卻是穩定的。生成器模式可以處理這類對象的構建,它提供了一種封裝機制來隔離各類子對象的變化,從而保證系統的穩定。
二、生成器模式
生成器模式將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。其結構圖如下:
三、示例
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(); } }}
四、使用場景
應用場景是當創建一個復雜的對象時,這個對象由各個子對象構成,而由于需求的變化導致子對象的性質也是未確定的。
我們一般為一個類提供構造函數,并利用這個構造函數完成對象的創建工作。當客戶知道為哪個類創建實例,并知道構造函數的參數時(假設是用帶參數的構造函數)。然而由于條件的現限制,是無法用通常的方式來構造對象的實例! 在進行對象構造之前,要逐步收集與構造相關的信息.那么創建對象的過程和對象的表現就應該分離開來。此時對象的表現是相對穩定的。
新聞熱點
疑難解答