Действительно ли это - типичный вариант использования для МОК?

Мое текущее приложение позволяет пользователям определять пользовательские веб-формы через ряд администраторских экранов. это - по существу приложение типа EAV. По сути, я не могу трудно кодировать HTML или разметку ASP.NET для рендеринга данной страницы. Вместо этого UI запрашивает экземпляр Объекта формы от уровня служб, который в свою очередь создает тот с помощью нескольких RDMBS таблицы. Форма содержит вид классов, которые Вы ожидали бы видеть в таком контексте: Form=> IEnumerable<FormSections>=>IEnumerable<FormFields>

Вот то, на что похож уровень служб:

public class MyFormService: IFormService{

       public Form OpenForm(int formId){
          //construct and return a concrete implementation of Form 
       }
}

Все работает блестяще (некоторое время). UI ничего не узнал о том, какие разделы/поля существуют в данной форме: Это счастливо представляет Объект формы, который это получает в функциональную страницу ASP.NET.

Несколько недель спустя я получаю новое требование от бизнеса: При просмотре недоступного для редактирования (т.е. только для чтения) версии формы, определенные значения полей должны быть объединены вместе, и другие изобретенные/вычисляемые поля должны добавляться. Никакая проблема я говорю. Просто исправьте мой класс обслуживания так, чтобы его методы были более явными:

public class MyFormService: IFormService{

       public Form  OpenFormForEditing(int formId){
          //construct and return a concrete implementation of Form 
       }

       public Form  OpenFormForViewing(int formId){
          //construct and a concrete implementation of Form  
          //apply additional transformations to the form
       }
}

Снова все работает отлично, и баланс был восстановлен силе. UI продолжает быть агностиком относительно того, что находится в Форме, и наше разделение проблем достигается. Только несколько коротких недель спустя, однако, бизнес производит новое требование: в определенных сценариях мы должны применить только некоторые преобразования формы, на которые я сослался выше.

На данном этапе такое чувство, что "явный метод" подход достиг тупика, если я не хочу закончить со взрывом методов (OpenFormViewingScenario1, OpenFormViewingScenario2, и т.д.). Вместо этого я представляю другой уровень абстракции:

public interface IFormViewCreator{
        void CreateView(Form form);
}

public class MyFormService: IFormService{

       public Form  OpenFormForEditing(int formId){
          //construct and return a concrete implementation of Form 
       }

       public Form  OpenFormForViewing(int formId, IFormViewCreator formViewCreator){
          //construct a concrete implementation of Form  
          //apply transformations to the dynamic field list
           return formViewCreator.CreateView(form);
       }
}

На поверхности это походит на приемлемый подход и все же существует определенный запах. А именно, UI, который жил в неосведомленном счастье о деталях реализации OpenFormForViewing, должен обладать знанием и создать экземпляр IFormViewCreator.

  1. Мои вопросы являются двукратными: существует ли лучший способ достигнуть composability, который я после? (возможно, при помощи контейнера МОК или домашней прокрученной фабрики для создания конкретного IFormViewCreator)?
  2. Я существенно завинчивал абстракцию здесь?
15
задан mattytommo 19 March 2013 в 13:26
поделиться

2 ответа

-

Как я понимаю вопрос, вам нужно изменить форму, прежде чем отправлять ее на слой пользовательского интерфейса. Это звучит для меня, как декоратор . Держите старый интерфейс Iformservice без IFormviewCreator.

Теперь вы можете создать один или несколько украшений Formservice (ы), которые реализуют желаемую фильтрацию или модификацию.

public class MyDecoratingFormService : IFormService
{
    private readonly IFormService formService;

    public MyDecoratingFormService(IFormService formService)
    {
        if(formService == null)
        {
            throw new ArgumentNullException("formService");
        }

        this.formService = formService;
    }

    public Form OpenFormForEditing(int formId)
    {
        var form = this.formService.OpenFormForEditing(formId);
        return this.TransformForm(form);
    }   

    public Form OpenFormForViewing(int formId)
    {
        var form = this.formService.OpenFormForViewing(formId);
        return this.TransformForm(form);
    }

    public Form TransformForm(Form form)
    {
        // Implement transformation/filtering/modification here
    }
}

Теперь вы можете украсить вашу оригинальную реализацию IFORMSERVICE с одним или несколькими из таких декораторов.

IFormService formService = new MyDecoratingFormService(new MyFormService());

Вы можете обернуть как можно больше декораторов (каждый со своей собственной ответственностью) вокруг друг друга, как вы хотели бы.

Нет явной необходимости для Di Container, чтобы сделать это, но он хорошо вписывается с другими разными узорами. Я использую декоратор все время :)

9
ответ дан 1 December 2019 в 05:02
поделиться

Если я не хочу в конечном итоге получить взрывом методов (OpenFormViewingScenario1, OpenFormViewingScenario2, и т.д.).

Вы не можете устранить неотъемлемую сложность требований. Так или иначе, вам придется обнаружить вариант использования и действовать соответствующим образом.

Вы можете перечислить все возможные комбинации или попытаться учесть обработку интеллектуально - если это возможно. Например, если в силу самой природы требования существует N * M = X возможностей, то исчерпывающий перечень X методов действительно не годится. Вы должны использовать такой коэффициент, чтобы создать X возможных форм из композиции N и M случаев.

Не зная точного требования, трудно сказать. Тогда существует множество возможных способов факторизации такой композиции, например, Decorator, ChainOfResponsability, Filter и т.д. Все это способы компоновки сложной логики.

А именно, пользовательский интерфейс, который до этого жил в невежественном блаженстве относительно детали реализации OpenFormForViewing, должен обладать знаниями и создать экземпляр IFormViewCreator.

Презентация должна быть передана форме, созданной где-то еще, чтобы оставаться независимой от создания формы. Однако форма должна быть где-то собрана/создана.

В MVC такая логика находится в контроллере, который обновляет модель/форму и отправляет ее в нужное представление/рендеринг. То же самое можно сделать и в ASP.NET

0
ответ дан 1 December 2019 в 05:02
поделиться
Другие вопросы по тегам:

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