前文用C#代碼實現了Facade模式、Adapter模式、Strategy模式、Bridge模式和Abstract Factory模式解決實際業務需求。本文將繼續以C#代碼爲例,實現我在前面介紹的11個模式中剩下的6個模式:Decorator模式、Observer模式、Template Method模式、Singleton模式、Factory Method模式和Prototype模式。按照實現方法的不一樣,該11個模式可分紅三類:建立型模式(Abstract Factory, Singleton, Factory Method, Prototype)、結構型模式(Adapter, Bridge, Decorator)和行爲型模式(Strategy, Observer, Template Method)。html
一.Decorator模式數據庫
業務場景:在中國銷售的一塊手錶,基本配置是顯示北京時間,但也提供帶有高級功能的配置。如:中端配置支持顯示當前時區下的日期、高端配置支持第二時區(具體能夠用戶設置)。採用Decorator模式實現的代碼以下:api
namespace PartternCase { public abstract class AbstractWatch {//Component in UML public abstract void StartWork(); } public class Watch : AbstractWatch {//ConcreteComponent in UML public override void StartWork() { //Show Beijing time } } public abstract class WatchDecorator : AbstractWatch {//Decorator in UML protected AbstractWatch Watch { get; set; } protected WatchDecorator(AbstractWatch watch) { Watch = watch; } } public class ShowDateDecorator : WatchDecorator {//ConcreteDecoratorA in UML public ShowDateDecorator(AbstractWatch watch) : base(watch) { } public override void StartWork() { Watch.StartWork(); //Show date of current time zone } } public class ShowSecTimeZoneDecorator : WatchDecorator {//ConcreteDecoratorB in UML public ShowSecTimeZoneDecorator(AbstractWatch watch) : base(watch) { } public override void StartWork() { Watch.StartWork(); // Show time of sencond timezone } } public class Client {//How to use decorator pattern public void ChooseWatch() { var watch = new Watch();//Basic function var middleWatch = new ShowDateDecorator(watch);//Middle: contain show date function var advanceWatch = new ShowSecTimeZoneDecorator(middleWatch);//Advance: contain show date and second time zone function } } }
二.Observer模式ide
業務場景:盛天公司內部的報銷有嚴格的審批流程,爲提升審批效率,當員工提交報銷單時,須要向具備審批權限的領導自動發送申請審批的郵件(固然,除報銷單外,領導還會收到其餘類型的審批郵件)。採用Observer模式實現的代碼以下:ui
namespace PartternCase { public abstract class Report {//Subject in UML public string Status { get; set; } protected IList<Employee> Employees { get; set; } public void Attach(Employee employee) { Employees = Employees ?? new List<Employee>(); Employees.Add(employee); } public void Detach(Employee employee) { if (Employees == null) { return; } Employees.Remove(employee); } public void Notify(Report report) { if (Employees == null) { return; } foreach (var employee in Employees) { employee.HandleReportSubmit(report); } } } public class ExpenseReport : Report {//ConcreteSubject in UML public void Submit() { Status = "Report Submited"; Notify(this); } } public abstract class Employee {//Observer in UML public abstract void HandleReportSubmit(Report report); } public class Boss : Employee {//ConcreteObserver in UML public string Status { get; set; } public override void HandleReportSubmit(Report report) { // Send email to this boss by smtp server Status = report.Status; } } public class Client {//How to use observer pattern public void Observer() { var boss1 = new Boss(); var boss2 = new Boss(); var expense = new ExpenseReport(); expense.Attach(boss1); expense.Attach(boss2); expense.Submit(); } } }
三.Template Method模式this
業務場景:聖象飲料公司生產牛奶和礦泉水兩種飲料。運營過程都分爲生產和銷售兩個環節,但兩種飲料的生產和銷售方式不相同。如銷售方式:牛奶天天經過送貨員送貨上門,礦泉水經過各大超市銷售。採用Template Method模式實現的代碼以下:spa
namespace PartternCase { public abstract class DrinkOperation {//AbstractClass in UML public void Perform() {//Interface for client call Product(); Sales(); } protected abstract void Product(); protected abstract void Sales(); } public class MilkOperation : DrinkOperation {//ConcreteClass in UML protected override void Product() { //Get raw material from milk station then process } protected override void Sales() { //Sell by deliveryman } } public class WaterOperation : DrinkOperation {//ConcreteClass in UML protected override void Product() { //Get raw material from mountain then process } protected override void Sales() { //Sell by supermarket } } }
四. Singleton模式code
業務場景:投資組合管理系統中常常會用到一些複雜的模型對投資組合的價值進行估值。這些計算模型每每都放在一個類中,互相之間沒有依賴關係。採用Singleton模式實現的代碼以下:orm
namespace PartternCase { public class CalculationEngine {//Singleton in UML protected CalculationEngine() { } private static readonly CalculationEngine instance = new CalculationEngine(); public static CalculationEngine GetInstance { get { return instance; } }// Interface for client call //Many calculation methods } }
五. Factory Method模式server
業務場景:聖天基金公司旗下的基金在向合夥人提款時,需根據合夥人類型不一樣(普通合夥人:GP、有限合夥人:LP)將提款數據存放在相應的合夥人類型中,而後保存。採用Factory Method模式實現的代碼以下:
namespace PartternCase { public abstract class CapitalCall {//Creator in UML public abstract Partner BuildPartner(); public void Perform() { var partner = BuildPartner(); //Calculate amount of partner then save partner } } public class GpCapitalCall : CapitalCall {//ConcreteCreator in UML public override Partner BuildPartner() { return new GP(); } } public class Partner {//Product in UML public decimal Amount { get; set; } } public class GP : Partner {//ConcreteProduct in UML } }
六. Prototype模式
業務場景:聖象飲料公司在查詢牛奶和礦泉水的季度銷量時,會分別針對Milk和Water數據庫表進行查詢,查詢條件除時間外從外部傳入,內部只設置時間條件,但不能改變傳入的查詢條件。下面將採用Prototype模式實現該業務場景:
namespace PartternCase { public abstract class DrinkCriteria {//Prototype in UML public abstract string QueryTable { get; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } //Other query fields public abstract DrinkCriteria Clone(); } public class MilkCriteria : DrinkCriteria {//Concrete Prototype1 in UML public override string QueryTable { get { return "Milk"; } } public override DrinkCriteria Clone() {//This is shallow copy, in other case maybe need deep copy. return MemberwiseClone() as MilkCriteria; } } public class WaterCriteria : DrinkCriteria {//Concrete Prototype2 in UML public override string QueryTable { get { return "Water"; } } public override DrinkCriteria Clone() { return MemberwiseClone() as WaterCriteria; } } public class Client {//Client in UML //Set relative criteria at runtime private DrinkCriteria Criteria { get; set; } public void HowToUse() { var newCritera = Criteria.Clone(); //newCritera.StartDate = 2013-1-1; //newCritera.EndDate = 2013-3-31; //Start to query user new criteria } } }