完全未经测试:
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 次编辑;不断看到错误]
[进一步编辑注意到您正在使用 Castle IOC]
在您的 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 语句。
然而,值得注意的是,开关并不邪恶,它们只是闻起来很臭,就像所有难闻的气味都应该与所有闻起来很香的东西隔离开一样;这就是工厂模式旨在实现的目标。