程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 《模式——工程化實現及擴展》模板方法模式 Template——“自我檢驗 參考答案

《模式——工程化實現及擴展》模板方法模式 Template——“自我檢驗 參考答案

編輯:C#入門知識

1、

分析:從描述看,盡管計算通脹的指標不同,而且每個指標的計算過程都很復雜,但其算法結構穩定。因此,考慮將采用模板定義算法,而將具體指標的計算交給子類完成


 

模板類型

/// <summary>
/// 模板類型
/// </summary>
abstract class InflationRateCalactorBase
{
    #region 交由子類實現的內容

    public abstract double LastYearIndicator{get;}
    public abstract double ThisYearIndicator { get;}

    #endregion

    /// <summary>
    /// 算法模板
    /// </summary>
    /// <returns></returns>
    public double GetInflationRate()
    {
        return (ThisYearIndicator - LastYearIndicator)/LastYearIndicator;
    }
}
 

子類

class GdpInflationRateCalactor : InflationRateCalactorBase
{
    public override double LastYearIndicator { get { throw new NotImplementedException(); } }
    public override double ThisYearIndicator { get { throw new NotImplementedException(); } }
}

class CpiInflationRateCalactor : InflationRateCalactorBase
{
    public override double LastYearIndicator { get { throw new NotImplementedException(); } }
    public override double ThisYearIndicator { get { throw new NotImplementedException(); } }
}

class PpiInflationRateCalactor : InflationRateCalactorBase
{
    public override double LastYearIndicator { get { throw new NotImplementedException(); } }
    public override double ThisYearIndicator { get { throw new NotImplementedException(); } }
}
 

單元測試

 

[TestClass]
public class InflationRateFixture
{

    InflationRateCalactorBase c1;
    InflationRateCalactorBase c2;
    InflationRateCalactorBase c3;

    [TestInitialize]
    public void Initialize()
    {
        c1 = new GdpInflationRateCalactor();
        c2 = new CpiInflationRateCalactor();
        c3 = new PpiInflationRateCalactor();
    }

    [TestMethod]
    public void TestInflationRateCalculatorTemplate()
    {
        ExecuteInflationRateCalactor(c1);
        ExecuteInflationRateCalactor(c2);
        ExecuteInflationRateCalactor(c3);
    }

    void ExecuteInflationRateCalactor(InflationRateCalactorBase calculator)
    {
        if (calculator == null) throw new ArgumentNullException("calculator");
        try
        {
            calculator.GetInflationRate();
        }
        catch(NotImplementedException){}
    }
}
 

 

2、

定義模板類型及其對外、對內的模板方法以及算法模板

 

interface IDocument { }
class D1 : IDocument { }
class D2 : IDocument { }
class D3 : IDocument { }

class DocumentEventArgs<T> : EventArgs
    where T : IDocument
{
    public T Document { get; set; }
}

interface IDocumentBroker<T>
    where T : IDocument
{
    void Process(T document);
    event EventHandler<DocumentEventArgs<T>> DocumentSent;
}

/// <summary>
/// 對外部看到的模板方法是一個方法void Process(T document)和一個事件event EventHandler<DocumentEventArgs<T>> DocumentSent
/// 對於子類而言,內部模板是T ProcessInternal(T document)和 Send(T document)兩個方法
/// 而整個算法的模板定義在void Process(T document)中
/// </summary>
/// <typeparam name="T">文件實體類型</typeparam>
abstract class DocumentBrokerBase<T> : IDocumentBroker<T>
    where T : IDocument
{

    public event EventHandler<DocumentEventArgs<T>> DocumentSent;

    protected abstract void Send(T document);
    protected abstract T ProcessInternal(T document);

    public virtual void Process(T document)
    {
        if (document == null) throw new ArgumentNullException("document");

        #region 算法的模板

        Trace.WriteLine(string.Format("begin process document [{0}]", document.GetType().Name));
        document = ProcessInternal(document);

        Send(document);
        if (DocumentSent != null)
            DocumentSent(this, new DocumentEventArgs<T>() { Document = document });

        #endregion
    }
}
 

單元測試


 

[TestClass]
public class DocumentBrokerFixture
{
    IFactory factory;

    [TestInitialize]
    public void Initialize()
    {
        factory = new Factory()
            .RegisterType<IDocumentBroker<D1>, D1DocumentBroker>()
            .RegisterType<IDocumentBroker<D2>, D2DocumentBroker>()
            .RegisterType<IDocumentBroker<D3>, D3DocumentBroker>();
    }

    [TestMethod]
    public void TestD1Broker()
    {
        var broker = factory.Create<IDocumentBroker<D1>>();
        broker.DocumentSent += OnDocumentSent<D1>;
        broker.Process(new D1());
    }

    [TestMethod]
    public void TestD2Broker()
    {
        var broker = factory.Create<IDocumentBroker<D2>>();
        broker.DocumentSent += OnDocumentSent<D2>;
        broker.Process(new D2());
    }

    [TestMethod]
    public void TestD3Broker()
    {
        var broker = factory.Create<IDocumentBroker<D3>>();
        broker.DocumentSent += OnDocumentSent<D3>;
        broker.DocumentSent += OnDocumentCrossPlatformSent<D3>;
        broker.Process(new D3());
    }

    /// <summary>
    /// 響應事件方式的模板“填充”

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved