これは主に思考実験です。これはすべてサンプルコードです。私の目標は、仕様パターンを使用して、ファクトリ内の条件付きコードの巨大なブロックを排除することでした。したがって、このサンプルには、適切な IStatusUpdate の実装を取得する StatusData オブジェクトがあります。
次の一連のテストがあります。
[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));
}
これまでの My Factory の実装は次のようになります。
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クラスを作成することはできますが、それはあまり一般的ではないようで、マッパーを仕様にどのようにマップするかという疑問も生じます。
ここには、私が見逃している小さな飛躍がまだ 1 つあります。