完全にテストされていません:
public class ViewModelBuilderFactory
{
public IViewModelBuilder GetViewModelBuilder (string docType, IRepository repository)
{
switch (docType)
{
case "ProgressNotes":
return new ProgressNotesViewModelBuilder(repository);
case "Labs":
return new LabsViewModelBuilder(repository);
default:
throw new ArgumentException(
string.Format("docType \"{0}\" Invalid", docType);
}
}
}
public interface IViewModelBuilder
{
TreeViewModel GetDocTreeViewModel();
WorkSpace GetWorkSpace(Patient patient);
}
public class LabsViewModelBuilder : IViewModelBuilder
{
private IRepository _repository;
public LabsViewModelBuilder(IRepository repository)
{
_repository = repository;
}
public TreeViewModel GetDocTreeViewModel()
{
return new TreeViewModel(_repository.GetPatientLabs());
}
public Workspace GetWorkspace(Patient patient)
{
return LabViewModel.NewLabViewModel(patient);
}
}
public class ProgressNotesViewModelBuilder : IViewModelBuilder
{
private IRepository _repository;
public ProgressNotesViewModelBuilder(IRepository repository)
{
_repository = repository;
}
public TreeViewModel GetDocTreeViewModel()
{
return new TreeViewModel(_repository.GetPatientProgressNotes());
}
public Workspace GetWorkspace(Patient patient)
{
return ProgressNoteViewModel.NewProgressNoteViewModel(patient);
}
}
これで、呼び出しコードは次のようになります。
ViewModelBuilderFactory factory = new ViewModelBuilderFactory();
IViewModelBuilder modelBuilder = factory.GetViewModelBuilder(docType, repository);
this.DocTreeViewModel = modelBuilder.GetDocTreeViewModel();
Workspace workspace = modelBuilder.GetWorkspace(patient);
this.Workspaces.Add(workspace);
this.SetActiveWorkspace(workspace);
[最初の投稿から4回の編集。間違いを見続ける]
[CastleIOCを使用していることに注意してさらに編集]
Castle xml構成で、追加することができます(ここでは、Castleに関する漠然とした知識のみに取り組んでいます)。
<component id="ProgressNotesViewModelBuilder"
type="MyNamespace.ProgressNotesViewModelBuilder, MyAssembly">
<parameters>
<!-- reference to repository here -->
</parameters>
</component>
<component id="LabsViewModelBuilder"
type="MyNamespace.LabsViewModelBuilder, MyAssembly">
<parameters>
<!-- reference to repository here -->
</parameters>
</component>
次に、ViewModelBuilderFactoryは必要ありません。置き換えるだけで、
IViewModelBuilder modelBuilder = factory.GetViewModelBuilder(docType, repository);
と
IViewModelBuilder modelBuilder = (IViewModelBuilder)
container.Resolve(docType + "ViewModelBuilder");
これで、switchステートメントはまったく必要ありません。
ただし、スイッチは悪臭ではなく、悪臭がするだけであり、すべての悪臭と同様に、悪臭のあるものすべてから隔離する必要があることに注意してください。それがファクトリパターンが達成しようとしていることです。