Я нахожу, что всякий раз, когда я работаю с кодом GUI, код, как правило, раздувается быстрее, чем другие виды кода. Это также кажется сложным для рефакторинга. Принимая во внимание, что в других видах кода я могу довольно легко выполнить рефакторинг - я нахожу, что могу разложить большой класс на более мелкие части функциональности - с большинством каркасов GUI я часто привязан к каркасу, который требует, чтобы мой виджет / control / любой класс реализовать намного больше вещей непосредственно в виджете / элементе управления / что угодно. Иногда это происходит из-за необходимости (а) наследования какого-либо базового виджета / элемента управления / вещи или (б) доступа к защищенным методам.
Мне, как правило, также приходится, например, реагировать на большое разнообразие входных сигналов с помощью сигналов / событий / чего-либо другого из структуры, чтобы реализовать все способы взаимодействия с пользователем. Мне может понадобиться один виджет / элемент управления GUI для обработки большого разнообразия ввода / вывода, которые могут включать в себя:
- щелчок правой кнопкой мыши / контекстное меню
- реагировать на выбор из контекстного меню - может быть много
- особый способ рисовать графический интерфейс
- реагировать на ввод с клавиатуры
- кнопки, флажки,
- и т. д.
... все время управляйте классами под GUI, представляющими бизнес-логику.
Простой и понятный графический интерфейс может заставить его код расти довольно быстро, даже если отделить логику бизнеса и использовать MVC, я считаю, что код GUI является большим магнитом для изменений.
Есть ли способ управлять кодом GUI разумным способом и не допустить, чтобы он стал разбитым окном? Или масса обработчиков случайных событий / переопределенных методов действительно лучшее, что мы можем сделать для кода GUI?
источник
Ответы:
Что нужно помнить о коде GUI, так это то, что он управляется событиями, а код, управляемый событиями, всегда будет выглядеть как масса случайно организованных обработчиков событий. То, что становится действительно беспорядочным, - это когда вы пытаетесь вставить в класс код, не управляемый событиями. Конечно, похоже, что он обеспечивает поддержку для обработчиков событий, и вы можете делать ваши обработчики событий красивыми и маленькими, но весь этот дополнительный код поддержки, который плавает вокруг, делает ваш источник GUI кажущимся раздутым и грязным.
Итак, что вы можете сделать с этим, и как вы можете упростить процесс рефакторинга? Ну, я бы сначала изменил свое определение рефакторинга с того, что я делаю время от времени, на то, что я делаю постоянно, когда кодирую. Почему? Потому что вы хотите, чтобы рефакторинг позволил вам легче модифицировать ваш код, а не наоборот. Я не просто прошу вас изменить семантику здесь, но прошу вас сделать небольшую умственную гимнастику, чтобы увидеть ваш код по-другому.
Три метода рефакторинга, которые я нахожу наиболее часто используемыми, это Rename , Extract Method и Extract Class . Если бы я никогда не узнал ни одного другого рефакторинга, эти три все равно позволили бы мне сохранить мой код чистым и хорошо структурированным, и из содержания вашего вопроса мне кажется, что вы, вероятно, обнаружите, что вы почти всегда используете те же три рефакторинга в чтобы ваш код GUI был тонким и чистым.
У вас может быть наилучшее в мире разделение между GUI и бизнес-логикой, и все же код GUI может выглядеть так, будто мой код был взорван в середине. Я советую, что не помешает иметь дополнительный класс или два, чтобы помочь вам правильно управлять вашим GUI, и это не обязательно должны быть ваши классы View, если вы применяете шаблон MVC - хотя часто вы найдете промежуточные классы настолько похожи на ваш взгляд, что вы часто будете испытывать желание объединить их для удобства. Мое предположение заключается в том, что на самом деле не мешало бы добавить дополнительный специфичный для графического интерфейса слой для управления всей визуальной логикой, однако, возможно, вы захотите взвесить преимущества и затраты, связанные с этим.
Поэтому мой совет:
источник
Я думаю, что многие проблемы, с которыми вы сталкиваетесь, могут быть связаны с простой причиной. Большинство разработчиков не воспринимают код GUI как «настоящий» код. У меня нет никаких доказательств или статистики, только мое внутреннее чувство.
Может быть, они думают, что это « просто презентация » и не важно. « Там нет бизнес-логики », говорят они, « зачем это тестировать ?» Они смеются, когда вы упоминаете ориентацию объекта и пишете чистый код. Они даже не пытаются сделать вещи лучше. Не существует структуры, с которой нужно начинать, они просто бьют какой-то код и позволяют ему гнить, поскольку другие со временем добавляют свой собственный штрих. Прекрасный беспорядок, код граффити.
Код GUI имеет свои уникальные проблемы, поэтому должен рассматриваться по-разному и с уважением. Нужна любовь и разработчики, которые хотят это написать. Те, которые будут держать его тонким и придать ему хорошую структуру и правильные узоры.
источник
По какой-то причине код GUI создает в разработчиках слепую точку в разделении интересов. Может быть, это потому, что все учебники сводят все в один класс. Может быть, это потому, что физическое представление заставляет вещи казаться более тесно связанными, чем они есть. Может быть, это потому, что классы создаются медленно, поэтому люди не осознают, что им нужен рефакторинг, как, например, пресловутая лягушка, которую варят, медленно поднимая огонь.
Независимо от причины, решение состоит в том, чтобы сделать ваши классы намного меньше. Я делаю это, постоянно спрашивая себя, возможно ли поместить то, что я печатаю, в отдельный класс. Если возможно поместить в другой класс, и я могу придумать разумное и простое имя для этого класса, то я делаю это.
источник
Возможно, вы захотите взглянуть на образец представления модели / пассивного представления модели. Рэй Райан выступил с речью в Google IO о лучших практиках в области архитектуры для GWT.
http://www.google.com/events/io/2009/sessions/GoogleWebToolkitBestPractices.html
Легко абстрагировать идеи от других рамок и языков. Основным преимуществом MVP (на мой взгляд) является юнит-тестируемость. И вы получите это только в том случае, если ваш код не раздут и не спагетти (судя по вашему вопросу, это то, что вы хотите). Это работает путем введения логического слоя представления, называемого презентатором. Фактическое представление отделено от этого через интерфейс (и, следовательно, может быть легко смоделировано в модульных тестах). Теперь, так как ваш логический уровень представления (презентатор) освобожден от внутренних компонентов конкретной структуры GUI, вы можете организовать его как обычный код, и вы не привязаны, например, к иерархии наследования Swings. В идеале вы могли бы переключать реализации GUI в разных средах, если они соответствуют одному и тому же интерфейсу.
источник
Мой ответ состоит из четырех частей: структура, простота, тестирование и синтаксис.
Первые три действительно сложно сделать!
Структура означает уделять большое внимание использованию наименьшего количества кода и максимального количества фреймворков, библиотек и т. Д.
Простота означает простоту вещей от первоначального проекта до фактической реализации. Простая навигация, использование простых плагинов, простое и понятное расположение помогут вам в этом. Теперь их можно «продавать» клиентам / пользователям, которые могут быстро увидеть преимущества страниц, работающих на ПК, iPad, мобильных и других устройствах.
Средства тестирования, в том числе инструменты тестирования браузера (мне приходят в голову webrat и capybara в моей работе с рельсами), которые улавливают кросс-браузерные проблемы заранее, когда можно разработать лучший код для их решения в начале, а не частое «исправление» кода разными разработчиками, так как они «открыты» пользователями разных браузеров.
Синтаксис. Действительно полезно использовать средство проверки кода / IDE / редактор-плагин и т. Д. Для HTML, CSS, Javascript и т. Д. Преимущество, которое браузеры получили благодаря способности обрабатывать некорректно сформированный HTML, работает против вас, когда разные браузеры по-разному работают с это, так что инструмент, который проверяет ваш формат HTML имеет важное значение. Правильно сформированный HTML очень полезен при наличии неблокированного HTML, так как плохой код должен иметь большую видимость.
источник
Решение, которое я нашел, - это декларативный код. Использование только процедурного кода - рецепт для спагетти-кода GUI. Конечно, «особый способ рисования виджета», вероятно, останется кодом. Но это код, изолированный в классе. Обработчики событий, сочетания клавиш, размеры окон - все эти грязные вещи лучше всего декларировать.
источник
Здесь много хороших ответов.
Одна вещь, которая помогла мне упростить код GUI, - убедиться, что GUI имеет свою собственную модель данных.
В качестве простого примера: если у меня есть графический интерфейс с 4 полями для ввода текста, то у меня есть отдельный класс данных, в котором хранится содержимое этих 4 полей для ввода текста. Более сложные графические интерфейсы требуют больше классов данных.
Я проектирую GUI как модель - представление. Модель GUI контролируется контроллером приложения модели приложения - view - controller. Представление приложения - это модель GUI, а не сам код GUI.
источник
Такие приложения, как обработка текстов, графические редакторы и т. Д., Имеют сложные интерфейсы, и их код не может быть простым. Однако для бизнес-приложений графический интерфейс не обязательно должен быть таким сложным, как некоторые.
Вот некоторые из ключей к упрощению графического интерфейса (большинство относится к .NET):
Стремитесь к более простому дизайну, когда это возможно. Избегайте причудливого поведения, если этого не требует бизнес.
Используйте хорошего поставщика контроля.
Не создавайте пользовательские функции управления в самом коде клиента. Вместо этого создайте пользовательские элементы управления, которые расширяют исходный элемент управления таким образом, чтобы вы могли отражать свое конкретное поведение в элементах управления, а не в коде использования формы / страницы.
Используйте каркас (даже самодельный) для управления интернационализацией, управлением ресурсами, стилями и т. Д., Чтобы вы не повторяли этот код в каждом пользовательском интерфейсе.
Используйте компонент (или структуру) для навигации.
Создание стандартных диалогов для ошибок, предупреждений, подтверждения и т. Д.
источник
Примените объектно-ориентированный дизайн к своему коду и для разработки пользовательского интерфейса:
Вот небольшое, но нетривиальное приложение, чтобы проиллюстрировать некоторые из моих моментов. Вы можете найти код и диаграмму взаимодействия вида / модели здесь: https://github.com/vanfrankie/pushpopbox
источник
Вы хотите взглянуть на концепцию «привязки данных» . Это способ связать элементы пользовательского интерфейса с абстрактными элементами модели декларативным способом, так что элементы модели автоматически синхронизируются с содержимым пользовательского интерфейса. Этот подход имеет много преимуществ, например, не нужно самостоятельно писать обработчики событий для синхронизации данных.
Существует поддержка связывания данных для многих сред пользовательского интерфейса, например .NET и Eclipse / JFace .
источник