Как я заменяю оператор переключения МОК, таким образом, я могу поддержать ТВЕРДЫЙ принцип

Я хотел избежать оператора переключения. У меня есть более чем 30 типов документов. Существует также возможность, я должен буду добавить больше продвижения типов документов. Я передал бы IDocument, и укажите тип в реализации IDocument. Что-то еще, что я забыл упоминать, было ProgressNoteViewModel, LabViewModel... все наследовались WorkspaceViewModel, и все конструкторы конкретной реализации берут тип IPatient в качестве параметра. Я также использую Замок в качестве своего контейнера МОК

Я хотел бы осуществить рефакторинг код к чему-то как

viewModel = new TreeViewModel(repository.GetPatientDocumentListing(IDocumentType);
this.DocTreeViewModel = viewModel;
//How would I then be able to instantiate the right ViewModel
//based on IDocumentType and also pass a object into the
//constructor that is not know at compile time

У меня есть следующий код:

switch (docType)
{
    case "ProgressNotes":
        viewModel = new TreeViewModel(repository.GetPatientProgressNotes());
        this.DocTreeViewModel = viewModel;
        ProgressNoteViewModel workspace = ProgressNoteViewModel.NewProgressNoteViewModel(_patient);
        break;
    case "Labs":
        viewModel = new TreeViewModel(repository.GetPatientLabs());
        this.DocTreeViewModel = viewModel;
        LabViewModel workspace = LabViewModel.NewLabViewModel(_patient);
        break;
}
this.Workspaces.Add(workspace);
this.SetActiveWorkspace(workspace);
7
задан Péter Török 17 October 2010 в 13:57
поделиться

1 ответ

Полностью не проверено:

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.

Однако стоит отметить, что выключатели не являются злом, они просто плохо пахнут и, как и все неприятные запахи, следует изолировать от всего, что хорошо пахнет; вот для чего предназначен шаблон Factory.

4
ответ дан 7 December 2019 в 12:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: