《模式——工程化实现及扩展》(设计模式C# 版)《工厂方法模式 Factory Method》——“自我检验" 参考答案
转自:《模式——工程化实现及扩展》(设计模式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;
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
{
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);
}
}
{
#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
}
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
}
贸易电子化,技术全球化
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述