装饰模式:动态的给一个对象添加一些额外的职责。当然我们也可以通过继承来实现类似的功能,但是随着子类的增多,各种子类的组合会造成子类的急剧膨胀。
Requirement:
假设客户有一个要求,需要打一个report,并且report 的header 和footer 各有3种,然后要求打出所有可能组合的report。
Analysis:
当然纯粹的通过子类继承也可以实现,但是现在如果header 和footer各有10种呢,那么你就要有100个扩展类。但是通过使用装饰模式,你只要10 header 类+10个footer类(即20个类)就可以轻松搞定。下面我们以header 和footer 各有两个具体实现一下。
Sample Code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace TestDecoratorPatternSample { public abstract class Report { public abstract void ReportContent(); } public class Content : Report { public override void ReportContent() { Console.WriteLine("This is report content."); } } public abstract class ReportDecorator : Report { private Report report; public ReportDecorator(Report myReport) { report = myReport; } public override void ReportContent() { report.ReportContent(); } } #region Header1 public class Header1 : ReportDecorator { public Header1(Report myReport) : base(myReport) { } public override void ReportContent() { ReportHeader(); base.ReportContent(); } public void ReportHeader() { Console.WriteLine("This is report header1."); } } #endregion #region Header2 public class Header2 : ReportDecorator { public Header2(Report myReport) : base(myReport) { } public override void ReportContent() { ReportHeader(); base.ReportContent(); } public void ReportHeader() { Console.WriteLine("This is report header2."); } } #endregion #region Header3 public class Header3 : ReportDecorator { public Header3(Report myReport) : base(myReport) { } public override void ReportContent() { ReportHeader(); base.ReportContent(); } public void ReportHeader() { Console.WriteLine("This is report header3."); } } #endregion #region Footer1 public class Footer1 : ReportDecorator { public Footer1(Report myReport) : base(myReport) { } public override void ReportContent() { base.ReportContent(); ReportFooter(); } public void ReportFooter() { Console.WriteLine("This is report Footer1."); } } #endregion #region Footer2 public class Footer2 : ReportDecorator { public Footer2(Report myReport) : base(myReport) { } public override void ReportContent() { base.ReportContent(); ReportFooter(); } public void ReportFooter() { Console.WriteLine("This is report Footer2."); } } #endregion #region Footer3 public class Footer3 : ReportDecorator { public Footer3(Report myReport) : base(myReport) { } public override void ReportContent() { base.ReportContent(); ReportFooter(); } public void ReportFooter() { Console.WriteLine("This is report Footer3."); } } #endregion }
下面是客户端的调用代码,你需要怎么组合在你调用的时候就怎么组合。
Content clientReport = new Content(); Report header2 = new Header2(clientReport); Report footer1 = new Footer1(header2); footer1.ReportContent();
欢迎各位网友拍砖,本人也在不断学习中。。。