行爲型模式關注於應用運行過程當中算法的提供和通訊關係的梳理。
相比於建立型模式和結構型模式,行爲型模式包含了最多的設計模式種類,包括:算法
職責鏈模式爲了不請求發送者與接收者耦合在一塊兒,讓多個對象都有可能接收請求,會將這些對象鏈接成一條鏈,而且沿着這條鏈傳遞請求,直到有對象處理它爲止。設計模式
GOF對外觀模式的描述爲:
Avoid coupling the sender of a request to its receiver by giving morethan one object a chance to handle the request. Chain the receivingobjects and pass the request along the chain until an object handles it.
— Design Patterns : Elements of Reusable Object-Oriented Softwareide
在平常生活中,也會遇到相似的具備一系列「工序」的場景,好比用洗衣機洗衣服,須要通過注水、洗滌、漂洗、排水等過程,但做爲使用者,咱們並不須要關注這些步驟,須要作的只是把衣服放到洗衣機、加入洗滌劑、等結束後取出而已。性能
UML類圖:
this
代碼示例
假設商品的價格分紅內部認購價、折扣價、平價,以及郵購價格,用職責鏈模式來進行價格的計算:設計
public enum PurchaseType { Internal, //內部認購價格 Discount, //折扣價 Regular, //平價 Mail //郵購價 } //請求對象 public class Request { public double Price { get; set; } public PurchaseType Type { get; set; } public Request(double price, PurchaseType type) { this.Price = price; this.Type = type; } } //抽象的操做對象 public interface IHandler { void HandleRequest(Request request); IHandler Next { get; set; } PurchaseType Type { get; set; } } public abstract class HandlerBase : IHandler { public IHandler Successor { get; set; } public PurchaseType Type { get; set; } public HandlerBase(PurchaseType type, IHandler successor) { this.Type = type; this.Successor = successor; } public HandlerBase(PurchaseType type) : this(type, null) { } //須要具體IHandler類型處理的內容 public abstract void Process(Request request); //在當前結點處理,仍是傳遞給下一個結點 public virtual void HandleRequest(Request request) { if (request == null) return; if (request.Type == Type) { Process(request); } else if (Successor != null) { Successor.HandleRequest(request); } } public class InternalHandler : HandlerBase { public InternalHandler() : base(PurchaseType.Internal) { } public override void Process(Request request) { request.Price *= 0.6; } } public class MailHandler : HandlerBase { public MailHandler() : base(PurchaseType.Mail) { } public override void Process(Request request) { request.Price *= 1.3; } } public class DiscountHandler : HandlerBase { public DiscountHandler() : base(PurchaseType.Discount) { } public override void Process(Request request) { request.Price *= 0.9; } } public class RegularHandler : HandlerBase { public RegularHandler() : base(PurchaseType.Regular) { } public override void Process(Request request) { } } }
組裝職責鏈並調用調試
static void Main(string[] args) { IHandler handler1 = new InternalHandler(); IHandler handler2 = new DiscountHandler(); IHandler handler3 = new MailHandler(); IHandler handler4 = new RegularHandler(); handler1.Next = handler3; handler3.Next = handler2; handler2.Next = handler4; IHandler head = handler1; Request request = new Request(20, PurchaseType.Mail); head.HandleRequest(request); Console.Write(request.Price); //26 //將MailHandler短路 handler1.Next = handler1.Next.Next; request = new Request(20, PurchaseType.Mail); head.HandleRequest(request); Console.Write(request.Price); //20 }
在實際應用中,組裝職責鏈的過程能夠交給建立型模式,或者從配置讀取。code
優點
從上面的示例能夠發現這種模式的一些優點:對象
缺點blog
參考書籍: 王翔著 《設計模式——基於C#的工程化實現及擴展》