Шаблон для переключения между дискретными режимами поведения - PullRequest
0 голосов
/ 27 сентября 2010

Вопрос философии дизайна:

  1. Предположим, у меня есть пользовательский элемент управления, который рисует график характеристик коллекции объектов.
  2. Элемент управления помещается в форму с долгоживущим классом контроллера, который предоставляет коллекцию объектов для рисования.
  3. Форма также содержит элемент управления, который позволяет переключаться между «режимами» или различными стилями печати. Логика, заключающаяся в том, что объекты, извлекаемые из использования для раскрытия их общедоступных свойств, в разных режимах принципиально различаются, но элемент управления не заботится об этом.
  4. Первоначальное кэширование данных для экземпляров объекта довольно трудоемко и вызывает проблемы с производительностью некоторых функций элемента управления отображением.
  5. Несмотря на разную логику, экземпляры объектов представляют один и тот же набор переменных / вещей моделирования (как бы вы ни хотели их представлять) до и после смены режима

Природа проблемы в пункте 3 предполагает, что собранные экземпляры следует рассматривать как абстрактные основы, и существуют два разных производных класса с различной внутренней логикой. К сожалению, это говорит о том, что весь набор объектов должен быть полностью регенерирован при каждом переключении режима, что приводит к потере тактов.

Есть ли у кого-нибудь примеры аккуратного шаблона для передачи кэшированных данных между различными реализациями базы? Я рассмотрел перегруженный конструктор, который берет экземпляр базового класса, но на первый взгляд это звучит довольно ужасно. Может быть, люди не согласны с этим стилем, и в этом случае я считаю, что вопрос исчерпан.

edit # 1:

Некоторые уточнения специфики этой проблемы; Я предположил, что мой первоначальный вопрос был, вероятно, довольно расплывчатым ...

Пусть свойство привязки, которое элемент управления присоединяет, например, List<BaseClass> ControllerClass.Items.

Пусть свойства, которые элемент управления запрашивает для выполнения своей работы, будут такими, как

double BaseClass.NumericProperty
IEnumerable<Thing> BaseClass.AggregateProperty

Пусть будет (как минимум) два разных подкласса BaseClass, называемых DerivedClass1 и DerivedClass2. Когда управление переключает режим, намерение состоит в том, что ControllerClass.Items будет представлять список элементов, которые выполняют соответствующую внутреннюю логику для предоставления этих свойств.

Я предлагаю, чтобы внутри переключателя режима, т.е. установки Controller.Mode = NewMode, контроллер создал новый набор DerivedClass2, выполнив что-то вроде _list_internal[i] = new DerivedClass2(_list_internal[i]), где _list_internal в настоящее время содержит набор DerivedClass1 с, затем вызвать событие (например, INotifyPropertyChanged или что-то еще), чтобы сообщить элемент управления. Конструкторы DerivedClass1 и DerivedClass2 принимают BaseClass в качестве аргумента, который разбит на части для извлечения данных, которые будут общими для обоих.

Мой вопрос: это признанный паттерн? если нет, то почему, и каковы альтернативы, учитывая эффективность и необходимость не выбрасывать данные каждый раз, когда пользовательский интерфейс что-то делает.

1 Ответ

2 голосов
/ 27 сентября 2010

Я согласен с mikemanne в том, что вопрос немного расплывчатый, но, насколько я понимаю, для максимальной производительности при переключении режимов вам придется принять несколько более высокий стартовый кризис:

  • Контроллер должен работать как с графическим пользовательским элементом управления, так и с переключателем режимов. По сути, он становится контроллером страниц вместо контроллера задач.
  • Контроллер должен предварительно увлажнять и поддерживать коллекцию объектов, которые содержат базовые данные для всех режимов отображения. Это могут быть фактические объекты из вашей доменной модели или набор облегченных DTO, которые содержат результаты, рассчитанные из домена.
  • Контроллер при запросе переключения режимов должен использовать отдельный класс DrawHelper для преобразования точек данных в график. Каждый DrawHelper работает для одного графического режима, и все они выглядят одинаково для контроллера (они наследуются от одного базового типа или интерфейса). Это известно как шаблон стратегии.

Следующие номера отсутствуют:

  • НЕ помещайте логику, необходимую для превращения данных в графическую точку, в модель вашего домена. Модель предметной области не должна знать, как вы планируете использовать ее данные, потому что, если бы она использовалась, и это изменилось, объект домена изменился бы, когда домен (его основная ответственность, которая должна быть единственной) не изменился. 1014 *
  • НЕ повторяйте данные каждый раз без исключения. Это то, что, как вы знаете, вы пытаетесь избежать, но для этого убедитесь, что ваш контроллер действительно «долговечен»; многие жизненные циклы веб-фреймворка уничтожают все, что используется на стороне сервера, между запросами, сохраняя только «состояние» сеанса и требуя повторного увлажнения контроллера.
  • НЕ помещайте логику рисования в контроллер; это станет огромным. Вы даже не должны помещать логику выбора DrawHelper в контроллер; вместо этого, пусть Контроллер знает о «фабрике», которая может предоставить ему DrawHelper, в котором он нуждается, основываясь на текущем режиме.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...