C#設(shè)計(jì)模式實(shí)現(xiàn)之生成器模式和責(zé)任鏈模式
生成器
生成器模式:封裝一個(gè)產(chǎn)品的構(gòu)造過程,并允許按步驟構(gòu)造。
現(xiàn)又一個(gè)度假計(jì)劃指定,需要指定度假每一天的活動(dòng)、旅館、用餐、門票等等事情,但是每個(gè)客人的度假計(jì)劃可能不太一樣。例如天數(shù)、活動(dòng)類型、用餐等等。

我們需要一個(gè)彈性的數(shù)據(jù)結(jié)構(gòu),代表客人的規(guī)劃,以及不同的變化,也需要一系列潛在復(fù)雜順序,創(chuàng)建這樣的規(guī)劃。如何提供一種方式來創(chuàng)建復(fù)雜的結(jié)構(gòu),也不會(huì)和創(chuàng)建它的步驟混在一起。迭代器的過程就是封裝進(jìn)一個(gè)獨(dú)立的對(duì)象中,向客戶隱藏集合的內(nèi)部表現(xiàn)。這里我們也采用同樣的思路:我們將旅游規(guī)劃的創(chuàng)建過程,封裝到一個(gè)對(duì)象中(此對(duì)象稱為生成器),然后讓客戶調(diào)用生成器為它創(chuàng)建旅游規(guī)劃。
設(shè)計(jì)類圖:

實(shí)現(xiàn)代碼:
①存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)類
public class Vacation
{
public int Day { get; set; }
public string Hotel { get; set; }
public string Park { get; set; }
public string Activity { get; set; }
public string Meal { get; set; }
}
②抽象生成器
public abstract class AbstractBuilder
{
public abstract void BuildDay(int day);
public abstract void Hotel(string hotel);
public abstract void Park(string park);
public abstract void Activity(string activity);
public abstract void Meal(string meal);
public abstract Vacation GetVacationPlanner();
}
③具體生成器,具體生成器可以多個(gè)實(shí)現(xiàn)。
public class VacationBuilder : AbstractBuilder
{
private Vacation vacation=new Vacation();
public override void BuildDay(int day)
{
vacation.Day = day;
}
public override void Hotel(string hotel)
{
vacation.Hotel = hotel;
}
public override void Activity(string activity)
{
vacation.Activity = activity;
}
public override void Meal(string meal)
{
vacation.Meal = meal;
}
public override void Park(string park)
{
vacation.Park = park;
}
public override Vacation GetVacationPlanner()
{
return vacation;
}
}
④客戶使用生成器
優(yōu)點(diǎn):
1、將復(fù)雜對(duì)象創(chuàng)建過程封裝起來。
2、允許對(duì)象通過多個(gè)步驟來創(chuàng)建,并且可以改變過程。
3、向客戶隱藏產(chǎn)品內(nèi)部表現(xiàn)。
4、產(chǎn)品的實(shí)現(xiàn)可以被替換,因?yàn)榭蛻糁豢吹揭粋€(gè)抽象的接口。
用途與缺點(diǎn):
1、經(jīng)常用來創(chuàng)建組合結(jié)構(gòu)。
2、與工廠模式相比,采用生成器創(chuàng)建對(duì)象的客戶需要更多的領(lǐng)域知識(shí),才能正確的創(chuàng)建對(duì)象。
責(zé)任鏈
責(zé)任鏈模式:讓一個(gè)以上的對(duì)象有機(jī)會(huì)能夠處理某個(gè)請(qǐng)求的時(shí)候,就使用責(zé)任鏈模式。
有這樣一個(gè)場(chǎng)景,公司專門接受郵件處理的人員需要將每天接收到的郵件進(jìn)行處理,一類是需要轉(zhuǎn)給部門經(jīng)理處理的郵件,一類是給自己處理的,還有一類垃圾郵件直接刪除。如果這樣的一個(gè)場(chǎng)景,我們就可以通過責(zé)任鏈模式,為處理創(chuàng)建一個(gè)對(duì)象鏈。每個(gè)對(duì)象依序檢查郵件請(qǐng)求,并進(jìn)行處理,或者將它傳遞給鏈中的下一個(gè)對(duì)象。
設(shè)計(jì)類圖:

實(shí)現(xiàn)代碼:
①責(zé)任鏈抽象類
/// <summary>
/// 郵件類型
/// </summary>
public enum EmailType
{
Self=1,
Manager=2,
Del=3
}
public abstract class Handler
{
public Handler nextHandler;
public EmailType type;
public Handler(EmailType type) {
this.type = type;
}
public void SetNextHandler(Handler nextHandler)
{
this.nextHandler = nextHandler;
}
public abstract void HandleRequest(EmailType requsetType);
}
②責(zé)任鏈處理類
/// <summary>
/// 自己處理
/// </summary>
class SelfHandler : Handler
{
public SelfHandler() : base(EmailType.Self)
{
}
public override void HandleRequest(EmailType requsetType)
{
if (EmailType.Self == requsetType)
{
Console.WriteLine("郵件由自己處理");
}
else
{
if (nextHandler != null)
{
nextHandler.HandleRequest(requsetType);
}
}
}
}
/// <summary>
/// 轉(zhuǎn)發(fā)經(jīng)理
/// </summary>
class ManagerHandler : Handler
{
public ManagerHandler() : base(EmailType.Manager)
{
}
public override void HandleRequest(EmailType requsetType)
{
if (EmailType.Manager == requsetType)
{
Console.WriteLine("郵件轉(zhuǎn)到經(jīng)理處理");
}
else
{
if (nextHandler != null)
{
nextHandler.HandleRequest(requsetType);
}
}
}
}
/// <summary>
/// 刪除垃圾郵件
/// </summary>
class DelHandler : Handler
{
public DelHandler() : base(EmailType.Del)
{
}
public override void HandleRequest(EmailType requsetType)
{
if (EmailType.Del == requsetType)
{
Console.WriteLine("垃圾郵件已刪除");
}
else
{
if (nextHandler != null)
{
nextHandler.HandleRequest(requsetType);
}
}
}
}
③測(cè)試責(zé)任鏈
class Program
{
static void Main(string[] args)
{
//組裝責(zé)任鏈
Handler handler = new SelfHandler();
Handler handler1 = new ManagerHandler();
Handler handler2 = new DelHandler();
handler.SetNextHandler(handler1);
handler1.SetNextHandler(handler2);
//測(cè)試
handler.HandleRequest(EmailType.Del);
handler.HandleRequest(EmailType.Manager);
handler.HandleRequest(EmailType.Self);
Console.ReadKey();
}
}

優(yōu)點(diǎn):
1、請(qǐng)求的發(fā)送者和接收者解耦。
2、簡(jiǎn)化對(duì)象,因?yàn)椴恍枰梨湹慕Y(jié)構(gòu)。
3、通過改變鏈內(nèi)的成員或調(diào)動(dòng)他們的次序,允許你動(dòng)態(tài)地新增或者刪除責(zé)任。
用途和缺點(diǎn):
1、經(jīng)常被用在窗口系統(tǒng)中,處理鼠標(biāo)和鍵盤之類的事件。
2、并不保證請(qǐng)求一定被執(zhí)行,如果沒有任何對(duì)象處理它,可能會(huì)落到鏈尾端之外。
3、不容易觀察允許特征,不好排查問題。
總結(jié)
到此這篇關(guān)于C#設(shè)計(jì)模式實(shí)現(xiàn)之生成器模式和責(zé)任鏈模式的文章就介紹到這了,更多相關(guān)C#生成器模式和責(zé)任鏈模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
積累Visual Studio 常用快捷鍵的動(dòng)畫演示
在代碼開發(fā)過程中,頻繁的使用鍵盤、鼠標(biāo)操作非常麻煩,影響程序的開發(fā)效率。如何操作能用鍵盤來操作,那就節(jié)省時(shí)間了。下面小編把我平時(shí)積累的有關(guān)visul studio 常用快捷鍵的動(dòng)畫演示分享給大家,僅供大家參考2015-10-10
C#實(shí)現(xiàn)文件讀寫到SQLite數(shù)據(jù)庫
這篇文章主要為大家詳細(xì)介紹了使用?C#?將文件讀寫到?SQLite?數(shù)據(jù)庫的幾種方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考一下2025-01-01
WPF實(shí)現(xiàn)類似360安全衛(wèi)士界面的程序源碼分享
最近在網(wǎng)上看到了新版的360安全衛(wèi)士,感覺界面還不錯(cuò),于是用WPF制作了一個(gè),時(shí)間有限,一些具體的控件沒有制作,用圖片代替了。感興趣的朋友一起跟著小編學(xué)習(xí)WPF實(shí)現(xiàn)類似360安全衛(wèi)士界面的程序源碼分享2015-09-09

