如何编写优雅的代码:07. 设计模式应用案例(下)
前文用C#代碼實(shí)現(xiàn)了Facade模式、Adapter模式、Strategy模式、Bridge模式和Abstract Factory模式解決實(shí)際業(yè)務(wù)需求。本文將繼續(xù)以C#代碼為例,實(shí)現(xiàn)我在前面介紹的11個(gè)模式中剩下的6個(gè)模式:Decorator模式、Observer模式、Template Method模式、Singleton模式、Factory Method模式和Prototype模式。按照實(shí)現(xiàn)方法的不同,該11個(gè)模式可分成三類:創(chuàng)建型模式(Abstract Factory, Singleton, Factory Method, Prototype)、結(jié)構(gòu)型模式(Adapter, Bridge, Decorator)和行為型模式(Strategy, Observer, Template Method)。
一.Decorator模式
業(yè)務(wù)場(chǎng)景:在中國(guó)銷售的一塊手表,基本配置是顯示北京時(shí)間,但也提供帶有高級(jí)功能的配置。如:中端配置支持顯示當(dāng)前時(shí)區(qū)下的日期、高端配置支持第二時(shí)區(qū)(具體可以用戶設(shè)置)。采用Decorator模式實(shí)現(xiàn)的代碼如下:
namespace PartternCase {public abstract class AbstractWatch{//Component in UMLpublic abstract void StartWork();}public class Watch : AbstractWatch{//ConcreteComponent in UMLpublic override void StartWork(){//Show Beijing time }}public abstract class WatchDecorator : AbstractWatch{//Decorator in UMLprotected AbstractWatch Watch { get; set; }protected WatchDecorator(AbstractWatch watch){Watch = watch;}}public class ShowDateDecorator : WatchDecorator{//ConcreteDecoratorA in UMLpublic ShowDateDecorator(AbstractWatch watch): base(watch){}public override void StartWork(){Watch.StartWork();//Show date of current time zone }}public class ShowSecTimeZoneDecorator : WatchDecorator{//ConcreteDecoratorB in UMLpublic ShowSecTimeZoneDecorator(AbstractWatch watch): base(watch){}public override void StartWork(){Watch.StartWork();// Show time of sencond timezone }}public class Client{//How to use decorator patternpublic void ChooseWatch(){var watch = new Watch();//Basic functionvar middleWatch = new ShowDateDecorator(watch);//Middle: contain show date functionvar advanceWatch = new ShowSecTimeZoneDecorator(middleWatch);//Advance: contain show date and second time zone function }} }二.Observer模式
業(yè)務(wù)場(chǎng)景:盛天公司內(nèi)部的報(bào)銷有嚴(yán)格的審批流程,為提高審批效率,當(dāng)員工提交報(bào)銷單時(shí),需要向具有審批權(quán)限的領(lǐng)導(dǎo)自動(dòng)發(fā)送申請(qǐng)審批的郵件(當(dāng)然,除報(bào)銷單外,領(lǐng)導(dǎo)還會(huì)收到其他類型的審批郵件)。采用Observer模式實(shí)現(xiàn)的代碼如下:
namespace PartternCase {public abstract class Report{//Subject in UMLpublic 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 UMLpublic void Submit(){Status = "Report Submited";Notify(this);}}public abstract class Employee{//Observer in UMLpublic abstract void HandleReportSubmit(Report report);}public class Boss : Employee{//ConcreteObserver in UMLpublic string Status { get; set; }public override void HandleReportSubmit(Report report){// Send email to this boss by smtp serverStatus = report.Status;}}public class Client{//How to use observer patternpublic void Observer(){var boss1 = new Boss();var boss2 = new Boss();var expense = new ExpenseReport();expense.Attach(boss1);expense.Attach(boss2);expense.Submit();}} }
三.Template Method模式
業(yè)務(wù)場(chǎng)景:圣象飲料公司生產(chǎn)牛奶和礦泉水兩種飲料。運(yùn)營(yíng)過程都分為生產(chǎn)和銷售兩個(gè)環(huán)節(jié),但兩種飲料的生產(chǎn)和銷售方式不相同。如銷售方式:牛奶每天通過送貨員送貨上門,礦泉水通過各大超市銷售。采用Template Method模式實(shí)現(xiàn)的代碼如下:
namespace PartternCase {public abstract class DrinkOperation{//AbstractClass in UMLpublic void Perform(){//Interface for client call Product();Sales();}protected abstract void Product();protected abstract void Sales();}public class MilkOperation : DrinkOperation{//ConcreteClass in UMLprotected override void Product(){//Get raw material from milk station then process }protected override void Sales(){//Sell by deliveryman }}public class WaterOperation : DrinkOperation{//ConcreteClass in UMLprotected override void Product(){//Get raw material from mountain then process }protected override void Sales(){//Sell by supermarket }} }
四. Singleton模式
業(yè)務(wù)場(chǎng)景:投資組合管理系統(tǒng)中經(jīng)常會(huì)用到一些復(fù)雜的模型對(duì)投資組合的價(jià)值進(jìn)行估值。這些計(jì)算模型往往都放在一個(gè)類中,互相之間沒有依賴關(guān)系。采用Singleton模式實(shí)現(xiàn)的代碼如下:
namespace PartternCase {public class CalculationEngine{//Singleton in UMLprotected CalculationEngine() { }private static readonly CalculationEngine instance = new CalculationEngine();public static CalculationEngine GetInstance { get { return instance; } }// Interface for client call//Many calculation methods } }
五. Factory Method模式
業(yè)務(wù)場(chǎng)景:圣天基金公司旗下的基金在向合伙人提款時(shí),需根據(jù)合伙人類型不同(普通合伙人:GP、有限合伙人:LP)將提款數(shù)據(jù)存放在相應(yīng)的合伙人類型中,然后保存。采用Factory Method模式實(shí)現(xiàn)的代碼如下:
namespace PartternCase {public abstract class CapitalCall{//Creator in UMLpublic abstract Partner BuildPartner();public void Perform(){var partner = BuildPartner();//Calculate amount of partner then save partner }}public class GpCapitalCall : CapitalCall{//ConcreteCreator in UMLpublic override Partner BuildPartner(){return new GP();}}public class Partner{//Product in UMLpublic decimal Amount { get; set; }}public class GP : Partner{//ConcreteProduct in UML } }
六. Prototype模式
業(yè)務(wù)場(chǎng)景:圣象飲料公司在查詢牛奶和礦泉水的季度銷量時(shí),會(huì)分別針對(duì)Milk和Water數(shù)據(jù)庫(kù)表進(jìn)行查詢,查詢條件除時(shí)間外從外部傳入,內(nèi)部只設(shè)置時(shí)間條件,但不能改變傳入的查詢條件。下面將采用Prototype模式實(shí)現(xiàn)該業(yè)務(wù)場(chǎng)景:
namespace PartternCase {public abstract class DrinkCriteria{//Prototype in UMLpublic abstract string QueryTable { get; }public DateTime StartDate { get; set; }public DateTime EndDate { get; set; }//Other query fieldspublic abstract DrinkCriteria Clone();}public class MilkCriteria : DrinkCriteria{//Concrete Prototype1 in UMLpublic 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 UMLpublic override string QueryTable { get { return "Water"; } }public override DrinkCriteria Clone(){return MemberwiseClone() as WaterCriteria;}}public class Client{//Client in UML//Set relative criteria at runtimeprivate 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 }} }轉(zhuǎn)載于:https://www.cnblogs.com/zhouwei0213/p/3358224.html
總結(jié)
以上是生活随笔為你收集整理的如何编写优雅的代码:07. 设计模式应用案例(下)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ODT .NET 详解之 SqlData
- 下一篇: [笔记][原创]Verilog HDL语