Мое текущее приложение позволяет пользователям определять пользовательские веб-формы через набор экранов администратора. по сути это приложение типа EAV. Таким образом, я не могу жестко кодировать HTML или ASP.NET разметку для отображения данной страницы. Вместо этого пользовательский интерфейс запрашивает экземпляр объекта Form из сервисного уровня, который, в свою очередь, создает его, используя несколько таблиц RDMBS. Форма содержит классы, которые вы ожидаете увидеть в таком контексте: Form
=> IEnumerable<FormSections>
=> IEnumerable<FormFields>
Вот как выглядит сервисный слой:
public class MyFormService: IFormService{
public Form OpenForm(int formId){
//construct and return a concrete implementation of Form
}
}
Все работает великолепно (на время). Пользовательский интерфейс не является мудрым в отношении того, какие разделы / поля существуют в данной форме: он с радостью выводит объект формы, который он получает, на функциональную страницу 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
}
}
Опять все прекрасно работает, и сила восстановлена. Пользовательский интерфейс продолжает быть независимым от того, что находится в Форме, и наше разделение интересов достигнуто. Однако всего через несколько недель бизнес выдвигает новое требование: в определенных сценариях мы должны применять только некоторые преобразований форм, на которые я ссылался выше.
В этот момент кажется, что подход «явного метода» зашел в тупик, если только я не хочу закончить взрывом методов (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);
}
}
На первый взгляд это кажется приемлемым подходом, но все же есть определенный запах. А именно, пользовательский интерфейс, который жил в невежественном блаженстве по поводу деталей реализации OpenFormForViewing, должен обладать знаниями и создавать экземпляр IFormViewCreator.
- У меня два вопроса: есть ли
лучший способ достичь
сочетаемость я после? (возможно
используя контейнер IoC или дом
прокатный завод для создания
конкретный IFormViewCreator)?
- Я фундаментально испортил
абстракция здесь?