詳解C#設(shè)計(jì)模式編程中生成器模式的使用
一、概述
在軟件系統(tǒng)中,有時(shí)候面臨著復(fù)雜的對(duì)象創(chuàng)建,該對(duì)象由一定算法構(gòu)成的子對(duì)象組成,由于需求變化,這些子對(duì)象會(huì)經(jīng)常變換,但組合在一起的算法卻是穩(wěn)定的。生成器模式可以處理這類(lèi)對(duì)象的構(gòu)建,它提供了一種封裝機(jī)制來(lái)隔離各類(lèi)子對(duì)象的變化,從而保證系統(tǒng)的穩(wěn)定。
二、生成器模式
生成器模式將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示。其結(jié)構(gòu)圖如下:

- Builder為創(chuàng)建Product對(duì)象的各個(gè)子對(duì)象指定抽象接口。
- ConcreteBuilder實(shí)現(xiàn)了Builder接口,用于創(chuàng)建Product對(duì)象的各個(gè)子對(duì)象。
- Director使用Builder來(lái)創(chuàng)建Product對(duì)象。
- Product表示被構(gòu)造的復(fù)雜對(duì)象。
三、示例
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>
/// 計(jì)算總學(xué)分
/// </summary>
/// <returns>總學(xué)分</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>
/// 選課建造者抽象類(lèi),表現(xiàn)(下面的抽象函數(shù))是相對(duì)穩(wěn)定的。
/// </summary>
public abstract class Builder
{
/// <summary>
/// 必修課程成績(jī)
/// </summary>
public abstract void BuildCompulsory();
/// <summary>
/// 選修課程成績(jī)
/// </summary>
public abstract void BuildElective();
/// <summary>
/// 限制課程成績(jī)
/// </summary>
public abstract void BuildRestriction();
/// <summary>
/// 獲得課程字典對(duì)象
/// </summary>
/// <returns></returns>
public abstract Coures GetCoures();
}
/// <summary>
/// 本科生選課成績(jī)
/// </summary>
public class UndergraduateBuilder : Builder
{
private Coures coures = new Coures();
/// <summary>
/// 本科生選必修課程成績(jī)
/// </summary>
public override void BuildCompulsory()
{
coures.Select("001", 80M);
}
/// <summary>
/// 本科生選選修課程成績(jī)
/// </summary>
public override void BuildElective()
{
coures.Select("101", 85M);
}
/// <summary>
/// 本科生選限制課程成績(jī)
/// </summary>
public override void BuildRestriction()
{
coures.Select("201", 95M);
}
/// <summary>
/// 本科生選獲得課程字典對(duì)象
/// </summary>
/// <returns></returns>
public override Coures GetCoures()
{
return coures;
}
}
/// <summary>
/// 研究生選課成績(jī)
/// </summary>
public class GraduateBuilder : Builder
{
private Coures coures = new Coures();
/// <summary>
/// 研究生選必修課程成績(jī)
/// </summary>
public override void BuildCompulsory()
{
coures.Select("S001", 70M);
}
/// <summary>
/// 研究生選選修課程成績(jī)
/// </summary>
public override void BuildElective()
{
coures.Select("S101", 75M);
}
/// <summary>
/// 研究生選限制課程成績(jī)
/// </summary>
public override void BuildRestriction()
{
coures.Select("S201", 80M);
}
/// <summary>
/// 研究生選獲得課程字典對(duì)象
/// </summary>
/// <returns></returns>
public override Coures GetCoures()
{
return coures;
}
}
/// <summary>
/// 課程成績(jī)管理類(lèi)
/// </summary>
public class CourseScoresManager
{
/// <summary>
/// 這里的參數(shù)便是未確定的
/// </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();
}
}
}
四、使用場(chǎng)景
應(yīng)用場(chǎng)景是當(dāng)創(chuàng)建一個(gè)復(fù)雜的對(duì)象時(shí),這個(gè)對(duì)象由各個(gè)子對(duì)象構(gòu)成,而由于需求的變化導(dǎo)致子對(duì)象的性質(zhì)也是未確定的。
我們一般為一個(gè)類(lèi)提供構(gòu)造函數(shù),并利用這個(gè)構(gòu)造函數(shù)完成對(duì)象的創(chuàng)建工作。當(dāng)客戶(hù)知道為哪個(gè)類(lèi)創(chuàng)建實(shí)例,并知道構(gòu)造函數(shù)的參數(shù)時(shí)(假設(shè)是用帶參數(shù)的構(gòu)造函數(shù))。然而由于條件的現(xiàn)限制,是無(wú)法用通常的方式來(lái)構(gòu)造對(duì)象的實(shí)例! 在進(jìn)行對(duì)象構(gòu)造之前,要逐步收集與構(gòu)造相關(guān)的信息.那么創(chuàng)建對(duì)象的過(guò)程和對(duì)象的表現(xiàn)就應(yīng)該分離開(kāi)來(lái)。此時(shí)對(duì)象的表現(xiàn)是相對(duì)穩(wěn)定的。
- C#實(shí)現(xiàn)文字視頻生成器的示例代碼
- C#實(shí)現(xiàn)封面圖片生成器的示例代碼
- C#設(shè)計(jì)模式之建造者模式生成器模式示例詳解
- Python實(shí)現(xiàn)C#代碼生成器應(yīng)用服務(wù)于Unity示例解析
- C#設(shè)計(jì)模式實(shí)現(xiàn)之生成器模式和責(zé)任鏈模式
- C# Guid長(zhǎng)度雪花簡(jiǎn)單生成器的示例代碼
- c# 如何實(shí)現(xiàn)代碼生成器
- C#設(shè)計(jì)模式之Builder生成器模式解決帶老婆配置電腦問(wèn)題實(shí)例
- 詳解C#中有趣的?SourceGenerator生成器
相關(guān)文章
DevExpress GridView自動(dòng)滾動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了DevExpress GridView自動(dòng)滾動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
C#中使用強(qiáng)制類(lèi)型實(shí)現(xiàn)字符串和ASCII碼之間的轉(zhuǎn)換
這篇文章主要介紹了C#中使用強(qiáng)制類(lèi)型實(shí)現(xiàn)字符串和ASCII碼之間的轉(zhuǎn)換,本文還給出了另一種方法,需要的朋友可以參考下2014-08-08

