您的位置:首页 > 编程语言 > C#

《模式——工程化实现及扩展》(设计模式C# 版)《模板方法模式 Template》——“自我检验" 参考答案

2011-05-21 12:09 1106 查看
转自:《模式——工程化实现及扩展》(设计模式C# 版) http://www.cnblogs.com/callwangxiang/ http://www.cnblogs.com/callwangxiang/archive/2011/05/20/ExerciseAATemplate.html的参考答案
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>
/// 响应事件方式的模板“填充”内容
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sender"></param>
/// <param name="eventArgs"></param>
void OnDocumentSent<T>(object sender, DocumentEventArgs<T> eventArgs)
where T : IDocument
{
Trace.WriteLine(string.Format("docuemnt [{0}] has been sent by {1}",
eventArgs.Document.GetType().Name,
sender.GetType().Name));
}

/// <summary>
/// 响应事件方式的模板“填充”内容
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sender"></param>
/// <param name="eventArgs"></param>
void OnDocumentCrossPlatformSent<T>(object sender, DocumentEventArgs<T> eventArgs)
where T : IDocument
{
Trace.WriteLine("cross platform communication");
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐