Подходящий рефакторинг - PullRequest
       7

Подходящий рефакторинг

7 голосов
/ 17 января 2010

У меня очень ориентированное на данные приложение, написанное на Python / PyQt. я планирую сделать некоторый рефакторинг, чтобы действительно отделить интерфейс от ядра, главным образом потому, что реальных тестов пока нет, и это явно должно измениться.

Уже есть какое-то разделение, и я думаю, что я сделал несколько правильных вещей, но это далеко не идеально. Два примера, чтобы показать вам, что меня беспокоит:

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

  • Когда что-то записывается в базу данных, но запись не выполняется (например, потому что запись базы данных заблокирован другим пользователем), классическое окно сообщения «Повторить / прервать» предоставляется пользователю. это диалог создается поставщиком данных *, хотя поставщик, очевидно, не должен иметь никаких функциональных возможностей пользовательского интерфейса. Очевидно, что провайдер может вместо этого вызвать исключение или иным образом указать сбой, и пользовательский интерфейс может перехватить что и действовать соответственно.

    * это слово, которое я использую для объекта, который в основном представляет таблицу базы данных и является посредником между его объектами данных и механизмом базы данных; Я не уверен, что это обычно называют «провайдер»

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

Там нет сложной бизнес-логики (это в основном просто CRU D , да, даже без D), и это было бы гораздо более реорганизованным, чем переписывание, поэтому я не очень заинтересован в представлении ошибки регрессии, подобные обсужденным в этом вопросе .

Мой план состоит в том, чтобы начать рефакторинг, имея в виду, что часть пользовательского интерфейса может быть легко разорвана, чтобы быть заменяется, скажем, веб-интерфейсом или текстовым интерфейсом вместо интерфейса Qt. С другой стороны, Сам Qt все еще будет использоваться ядром, потому что механизм сигнал / слот используется во многих местах, например объекты данных испускают сигнал changed, чтобы указать, ну, вы знаете, что.

Итак, мой вопрос: возможен ли этот подход для повышения тестируемости и ремонтопригодности? Любые другие замечания, особенно с учетом Python?

Ответы [ 4 ]

7 голосов
/ 17 января 2010

Если вы еще этого не сделали, прочитайте «Эффективная работа с устаревшим кодом» Майкла Фезерса (Michael Feathers) - он имеет дело именно с такой ситуацией и предлагает множество методов для ее решения.

Один из ключевых моментов, которые он делает, - попытаться провести некоторые тесты перед рефакторингом. Поскольку он не подходит для модульных тестов, попробуйте выполнить некоторые сквозные тесты. Я считаю, что Qt имеет свою собственную среду тестирования для управления графическим интерфейсом, поэтому добавьте тесты, которые манипулируют этим интерфейсом для известной базы данных и проверяют результат. По мере очистки кода вы можете заменить или дополнить сквозные тесты модульными тестами.

2 голосов
/ 17 января 2010

Если вы хотите извлечь все части GUI вашего приложения из всех других частей, чтобы протестировать все ваше приложение, вы должны использовать Model-View-Presenter: здесь вы можете найти объяснение здесь .

В этой модели все ваши службы вашего приложения используют презентаторы, в то время как только пользователь может напрямую взаимодействовать с представлениями (части GUI). Докладчики управляют представлениями из приложения. У вас будет часть графического интерфейса, независимая от вашего приложения, в случае, если вы хотите изменить структуру GUI. Единственное, что вам нужно изменить, - это сами докладчики и сами представления.

Для тестов GUI, которые вы хотите, вам просто нужно написать модульные тесты для докладчиков. Если вы хотите протестировать использование GUI, вам нужно создать интеграционные тесты .

Надеюсь, это поможет!

1 голос
/ 28 января 2010

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

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

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

1 голос
/ 27 января 2010

Я уже делал рефакторинг для большого унаследованного кода с целью разделения пользовательского интерфейса и бэкенда. Это весело и полезно.

/ хвала;)

Какой бы паттерн ни называли, или быть частью MVC, бесценно иметь очень чистый API-слой . Если возможно, вы можете направить все запросы интерфейса через диспетчера, который обеспечит вам больший контроль над интерфейсом <-> Логическая связь, например. реализация кэширования, аутентификации и т. д.

Для визуализации:

[QT Frontend]
[CLIs]             <=======> [Dispatcher] <=> [API] <==> [Core/Model]
[SOAP/XMPRPC/Json]
[API Test Suite]

Так

  • проще добавить набор тестов для тестирования ваших API.
  • Также это делает добавление большего количества пользовательских интерфейсов единообразным и простым способом.
  • Документация по API. Скажем, если вы хотите документировать и выставлять API-интерфейсы через интерфейс RPC, проще создавать документацию по API. Если кто-то не согласен с важностью документации по API, всегда можно посмотреть на Twitter API, и это удача.
  • Вы можете быстро импортировать слой API в оболочку Python и играть с ним

Проектирование API может произойти задолго до того, как вы начнете кодировать для уровня API. В зависимости от приложения вы можете воспользоваться помощью таких пакетов, как zinterfaces. Это общий подход, который я использую, даже когда пишу очень маленькие приложения, и он никогда не подводил меня.

Посмотри на

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

Другие предложения - иметь готовый набор тестов. См. Рекомендации Interstar на Каковы первые задачи по внедрению модульного тестирования в приложениях Brownfield? .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...