Любой успех с использованием структурирования программ на основе пользовательского интерфейса? - PullRequest
2 голосов
/ 06 июня 2009

Вы когда-нибудь структурировали свой исходный код на основе частей вашего пользовательского интерфейса? Например, если ваш пользовательский интерфейс состоит из:

  1. GridView для отображения некоторых свойств
  2. Панель 3D-рендеринга
  3. панель выбора активных инструментов

, затем вы называете и группируете свои переменные и функции более или менее следующим образом:

class Application
{
  string   PropertiesPanel_dataFile;
  DataSet  PropertiesPanel_dataSet;
  string[] PropertiesPanel_dataIdColumn;
  void     PropertiesPanel_OpenXml();
  void     PropertiesPanel_UpdateGridView();

  string   ThreeDView_modelFile;
  Panel    ThreeDView_panel;
  PointF[] ThreeDView_objectLocations;
  void     ThreeDView_RenderView();

  string   ToolPanel_configurationFile;
  Button[] ToolPanel_buttons;
  void     ToolPanel_CreateButtons();
}

Что вы думаете по этому поводу? Может ли эта архитектура работать в долгосрочной перспективе?

PS. Хотя это решение может напомнить вам о шутке первоапрельского проекта http://thedailywtf.com/Articles/FrontAhead-Design.aspx у меня серьезный вопрос.

EDIT

В течение полугода поддерживала и расширяла этот вид кода. Приложение выросло до более 3000 строк в основном файле .cs, и около 2000 строк разбиты на более мелкие файлы (которые содержат вспомогательные функции общего назначения и классы). Есть много частей кода, которые должны быть обобщены и извлечены из основного файла, и я постоянно работаю над этим, но в конце концов это не имеет значения. Структура и подразделение кода настолько просты, что с ним легко ориентироваться. Поскольку пользовательский интерфейс содержит менее 7 основных компонентов, нет проблем в том, чтобы сразу вписать весь дизайн в вашу голову. Всегда приятно вернуться к этому коду (после некоторого перерыва) и сразу узнать, с чего начать.

Полагаю, одной из причин, по которой эта гигантская процедурно-подобная структура работает в моем случае, является событийный характер программирования пользовательского интерфейса на c #. По большей части весь этот код является реализацией различных видов событий, которые действительно специфичны для этого проекта. Несмотря на то, что некоторые функции событий сразу превращаются в монстров длиной в несколько страниц, связь между обработчиками событий не так уж и тесна, поэтому впоследствии ее проще реорганизовать и сжать. Вот почему я намеренно оставляю обобщение и рефакторинг на более позднее время, когда другие проекты начинают требовать тех же частей реализации, которые использует этот проект.

PS, чтобы сделать возможным навигацию по 3000 строкам кода, я использую макросы FindNextSelection и FindPrevSelection в Visual Studio. После щелчка левой кнопкой мыши по некоторой переменной я нажимаю F4, чтобы перейти к следующему экземпляру, и F2 к предыдущему. Также возможно выбрать некоторую часть имени переменной и перейти между частичными совпадениями имен. Без этих ярлыков я бы очень давно заблудился:)

Ответы [ 3 ]

1 голос
/ 06 июня 2009

Это выглядит очень процедурно в концепции и полностью игнорирует значение OOD. Разумным подходом было бы создание объектов для каждого из ваших элементов, а значения, которые вы дали, были бы свойствами этих объектов, то есть

class PropertiesPanel 
{
  public string DataFile { get; set; }
  public DataSet DataSet { get; set; }
  public string[] DataIDColumn { get; set; }
  etc...

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

Лучший совет, который я когда-либо получал для OOD, заключался в поиске наименьшего объекта, к которому может быть передана каждая логическая ветвь вашего приложения, вероятно, оно имеет собственные типы для свойств (в .NET нет смысла заново изобретать объекты Framework поэтому они могут находиться в вашем базовом классе), а затем использовать наследование, полиморфизм и инкапсуляцию для расширения этих базовых классов, пока у вас не появится объект, который инкапсулирует логическую ветвь.

В то время, когда я писал приложение, которое помещало данные на устройство I2C, я начал с класса, который помещал бит в шину I2C, который был унаследован классом, который помещает байт в шину, унаследованный класс, который помещает массив байтов на шину, и, наконец, класс, который помещает адрес и массив байтов. Это довольно экстремальный OOD, но он генерирует очень чистый код, каждый класс очень маленький и его очень легко отлаживать.

Возможно, стоит подумать о проблеме заранее, но в конечном итоге это сэкономит много времени, просто не смешно.

0 голосов
/ 06 июня 2009

Что вы думаете по этому поводу?

Это беспорядок.

Может ли эта архитектура работать долго бежать?

Нет. (По крайней мере, без большого количества пота.)

Имена безумно многословны. Если подумать, префиксы длинных имен существуют для того, чтобы создать некое отдельное «пространство имен», чтобы группировать связанные вещи вместе. Для такого рода вещей уже существует лучшая языковая конструкция - это классы . Но главная проблема в другом месте.

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

(Я надеюсь, что часть «базовые концепции из проблемной области» понятна. Например, если вы создаете систему для локального театра, вы должны основывать свой дизайн на понятиях «Кино», «Посетитель», «Место» и и так далее, вместо того, чтобы структурировать его вокруг MovieList, SeatMap, TheaterPlan и т. д.)

Большую часть времени хорошей идеей будет максимально отделить основной код от графического интерфейса пользователя (это как раз то, чем занимается система проектирования Model – View – Controller .) не академическая тренировка, и она не требуется, только если интерфейс будет изменен. Отличным примером отделения GUI от остальной части кода является программирование GUI на Mac OS X с дизайнером интерфейсов, привязками и тому подобным. К сожалению, это займет некоторое время, вы не можете просто просмотреть документы в Интернете и быть просвещенными.

0 голосов
/ 06 июня 2009

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

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

class Application
{
  PropertiesPanel
  ThreeDView
  ToolPanel
}

class PropertiesPanel {
  string   dataFile;
  DataSet  dataSet;
  string[] dataIdColumn;
  void     OpenXml();
  void     UpdateGridView();
}

class ThreeDView {
  string   modelFile;
  Panel    panel;
  PointF[] objectLocations;
  void     RenderView();
}

class ToolPanel {
  string   configurationFile;
  Button[] buttons;
  void     CreateButtons();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...