在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
转自:《模式——工程化实现及扩展》(设计模式C# 版) http://www.cnblogs.com/callwangxiang/
请修改本章最后完成的那个比较适于工程应用的工厂类型,使其支持含参数的构造函数
分析: 1、本着OCP原则,我们不对原有Factory<T> 进行修改,而是通过继承对其进行扩展 2、继续采用.NET Framework自带的Activator提供对于带参数构造函数的支持 3、为了与原有Factory<T>的方法签名作区别,我们在新的接口中要求只有明确声明为object[]的数组才作为构造函数参数
参考答案
1、为了不引起其歧义,首先修改引用的命名空间
using System; using F = MarvellousWorks.PracticalPattern.FactoryMethod; using Microsoft.VisualStudio.TestTools.UnitTesting; 2、定义新的工厂接口和具体工厂类型
interface IFactory : F.IFactory { #region factory method TTarget Create<TTarget>(object[] parametes); TTarget Create<TTarget>(string name, object[] parametes); #endregion } class Factory : F.Factory, IFactory {
public TTarget Create<TTarget>(object[] parametes)
{return (TTarget)Activator.CreateInstance(registry[typeof(TTarget)], parametes); } public TTarget Create<TTarget>(string name, object[] parametes) { return (TTarget)Activator.CreateInstance(registry[typeof(TTarget), name], parametes); } }
3、编写单元测试验证
[TestMethod] public void CreateInstance() { var factory = new Factory() .RegisterType<IFruit, Apple>() .RegisterType<IFruit, Orange>("o") .RegisterType<IVehicle, Bicycle>() .RegisterType<IVehicle, Bicycle>("a") .RegisterType<IVehicle, Train>("b") .RegisterType<IVehicle, Car>("c") .RegisterType<IEntry, EntryWithName>() .RegisterType<IEntry, EntryWithName>("n") .RegisterType<IEntry, EntryWithNameAndAgeAndTitle>("nat"); #region 构造函数无参数的类型 Assert.IsInstanceOfType(factory.Create<IFruit>(), typeof(Apple)); Assert.IsInstanceOfType(factory.Create<IFruit>("o"), typeof(Orange)); Assert.IsInstanceOfType(factory.Create<IVehicle>(), typeof(Bicycle)); Assert.IsInstanceOfType(factory.Create<IVehicle>("a"), typeof(Bicycle)); Assert.IsInstanceOfType(factory.Create<IVehicle>("b"), typeof(Train)); Assert.IsInstanceOfType(factory.Create<IVehicle>("c"), typeof(Car)); #endregion #region 构造函数带参数的类型 // 转换为新的扩展接口形式 var f = (IFactory) factory; // 使用扩展的功能 var e1 = f.Create<IEntry>(new object[] { "joe" }); Assert.IsInstanceOfType(e1, typeof(EntryWithName)); Assert.AreEqual<string>("joe", ((EntryWithName) e1).Name); var e2 = f.Create<IEntry>("nat", new object[] { "joe", 20}); Assert.IsInstanceOfType(e2, typeof(EntryWithNameAndAgeAndTitle)); Assert.AreEqual<string>("joe", ((EntryWithName)e2).Name); Assert.AreEqual<int>(20, ((EntryWithNameAndAgeAndTitle)e2).Age); Assert.AreEqual<string>(EntryWithNameAndAgeAndTitle.DefaultTitle, ((EntryWithNameAndAgeAndTitle)e2).Title); #endregion }
|
请发表评论