Il s'agit principalement d'une expérience de réflexion. Donc tout ceci est un exemple de code. Mon objectif était d'utiliser le modèle de spécification pour éliminer les blocs géants de code conditionnel dans une usine. Donc, avec cet exemple, j'ai un objet StatusData que je veux obtenir une implémentation de IStatusUpdate qui est appropriée pour cela.Implémentation d'une fabrique qui utilise les spécifications pour déterminer le type d'objet à créer
Je donne les résultats suivants: Série de tests:
[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));
}
Ma mise en œuvre de l'usine semble jusqu'à présent comme ceci:
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;
}
}
Là où je suis en train de tomber vers le bas est une fois que je l'ai découvert une spécification qui est satisfaite par l'objet d'état, comment mapper cette spécification à un type qui implémente IStatusUpdate. Je suis perplexe. Quelqu'un a suggéré à juste titre que j'avais besoin d'un mappage des spécifications aux implémenteurs IStatusUpdate. Cette cartographie semble être une responsabilité de l'usine, le suspendre de la spécification sent comme une violation de SRP. Je pourrais créer une classe Mapper qui a cette responsabilité mais qui ne semble pas très générique et soulève également la question comment mapper le mappeur à la spécification.
Il y a encore un petit saut ici qui me manque.
Je pense que c'est la responsabilité des usines de faire ce mapping, n'est-ce pas? alors pourquoi pas un Dictionary pour contenir les mappages qui sont renseignés à l'initialisation de l'usine? –
NotMyself
Oui, si une spécification correspond à un type d'élément, alors le dictionnaire a du sens. Je supposais qu'un article pourrait avoir plusieurs spécifications. Et vous avez raison d'utiliser l'usine pour injecter. Je pense vraiment que c'est le point d'avoir l'usine. –