Это в основном мысленный эксперимент. Итак, это все пример кода. Моя цель состояла в том, чтобы использовать шаблон спецификации для устранения гигантских блоков условного кода внутри фабрики. Поэтому с этим образцом у меня есть объект 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;
}
}
Где я падаю вниз это, как только я обнаружил спецификацию, которая удовлетворяется по объекту status, как мне сопоставить эту спецификацию с типом, который реализует IStatusUpdate .. Я в тупике.
Кто-то справедливо предположил, что мне нужно сопоставление спецификаций с исполнителями IStatusUpdate. Это сопоставление, по-видимому, несет ответственность за завод, и его отклонение от спецификации пахнет как нарушение SRP. Я мог бы создать класс Mapper, который несет эту ответственность, но это не кажется очень общим, а также поднимает вопрос о том, как сопоставить картограф с спецификацией.
Есть еще один небольшой прыжок здесь, я пропал без вести.
Я вроде как думает, что фабрика несет ответственность за правильное отображение? так почему бы не словарь удерживать сопоставления, которые заполняются при инициализации фабрики? –
NotMyself
Да, если одна спецификация сопоставляется с одним типом элемента, то словарь имеет смысл. Я предполагал, что один элемент может иметь несколько спецификаций. И вы правы в использовании фабрики для инъекций. Я определенно думаю, что это точка с фабрикой. –