这主要是一个思想实验。所以这一切都是示例代码。我的目标是使用规范模式来消除工厂内大量的条件代码。因此,对于这个示例,我有一个 StatusData 对象,我想获得一个适合它的 IStatusUpdate 实现。
我有以下一组测试:
[TestMethod]
public void Factory_Interface_Should_Return_IStatusUpdate()
{
var factory = MockRepository.GenerateMock<IUpdateFactory<StatusData>>();
var obj = MockRepository.GenerateStub<IStatusUpdate>();
var data = new StatusData();
factory.Stub(x => x.Get(data)).Return(obj);
var item = factory.Get(data);
Assert.IsInstanceOfType(item, typeof(IStatusUpdate));
}
[TestMethod]
public void StatusUpdateFactory_Should_Return_IStatusUpdate()
{
var factory = new StatusUpdateFactory();
var data = new StatusData();
var item = factory.Get(data);
Assert.IsInstanceOfType(item, typeof(IStatusUpdate));
}
[TestMethod]
public void StatusUpdateFactory_Should_Return_NewStatusUpdate_When_Status_Is_New()
{
var data = new StatusData(Status.New);
var factory = new StatusUpdateFactory();
var item = factory.Get(data);
Assert.IsInstanceOfType(item, typeof(NewStatusUpdate));
}
到目前为止,我的工厂实现如下所示:
public class StatusUpdateFactory:IUpdateFactory<StatusData>
{
public IStatusUpdate Get(StatusData item)
{
IList<ISpecification<StatusData>> specs = GetSpecifications();
foreach (var spec in specs)
{
if (spec.IsSatisfiedBy(item))
//how do I do this?
return new NewStatusUpdate();
}
return null;
}
private IList<ISpecification<StatusData>> GetSpecifications()
{
var returnList = new List<ISpecification<StatusData>>();
var specTypes = this.GetType().Assembly.GetTypes()
.Where(z => z.IsInstanceOfType(typeof(ISpecification<StatusData>)))
.ToList();
specTypes.ForEach(x => returnList.Add(Activator.CreateInstance(x) as ISpecification<StatusData>));
return returnList;
}
}
一旦我发现了状态对象满足的规范,我就会失败,我如何将该规范映射到实现 IStatusUpdate 的类型。我很难过。
有人正确地建议我需要将规范映射到 IStatusUpdate 实现者。这种映射似乎是工厂的责任,把它挂在规范之外闻起来像是违反了 SRP。我可以创建一个具有该职责的 Mapper 类,但这似乎不是很通用,并且还提出了如何将映射器映射到规范的问题。
我在这里仍然缺少一个小飞跃。