Слабая связь и ОО-практики для начинающих - PullRequest
7 голосов
/ 27 марта 2009

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

Я более или менее понимаю, как я могу инкапсулировать строки, целые числа и простые типы данных в свои собственные классы. Однако когда я начинаю работать с такой информацией, как форматированное текстовое форматирование, все становится действительно сложным - если только я не использую различные методы, уже присутствующие в компоненте. Чтобы продолжить этот пример, предположим, что я писал что-то, что включало компонент меморандума RTF в пользовательском интерфейсе. В Delphi компонент имеет встроенные методы для выполнения таких задач, как сохранение форматированного текста. Кроме того, иногда кажется, что единственный (или, по крайней мере, лучший) способ работы с самим текстом RTF - это методы, вновь встроенные в компонент.

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

Самостоятельно я обычно заканчиваю тем, что (а) делаю что-то, что кажется гораздо более сложным, чем нужно, переизобретаю уже существующие методы, или (б) создаю плохо выполненные классы, которые все еще тесно связаны друг с другом. Как говорится в информационных роликах: «Должен быть лучший путь!»

Я просто потерял концептуальность того, как работает этот «лучший путь». Есть мысли?

Ответы [ 4 ]

5 голосов
/ 27 марта 2009

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

Когда вы используете интерфейсы с внедрением зависимостей, то есть даете классу фактическую реализацию, над которой он должен работать, вместо того, чтобы создавать отдельную реализацию самостоятельно, вы достигаете еще большей развязки в своем приложении. Теперь класс знает только об интерфейсе и даже не знает, как его создать, просто используйте его. Внедрение зависимостей часто используется с шаблонами создания, такими как Builder или Factory, где вы локализуете конструирование объектов в одном классе, так что при расширении приложения дополнительными классами нужно изменять только этот класс.

Кроме того, помните, что сцепление (и его близнец, сплоченность) является относительной мерой. Вы не можете устранить все связи, иначе ваши объекты не смогут взаимодействовать. Наличие некоторого уровня зависимости необходимо. Вы должны сбалансировать его с простотой использования и реализации.

Что касается вашего конкретного примера, трудно сказать без реального кода. Я подозреваю, что вы чрезмерно разрабатываете решение и нарушаете принцип СУХОГО (не повторяйте себя). Возможно, вам придется поискать способы использования интерфейсов и, возможно, облегченную оболочку для отделения ваших классов от компонента фреймворка, а не для полной переопределения.

5 голосов
/ 27 марта 2009

Я полагаю, что вы упустили некоторые основные понятия.

Идея ООП начинается с дискретных, многократно используемых единиц логики. С упором на создание самодостаточных модулей.

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

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

Слабая связь идет рука об руку с идеей Разделение интересов (SoC); это процесс разбивки программы на отдельные функции, чтобы уменьшить дублирование функций и облегчить управление. Но они не одно и то же. Между прочим, это было также одним из основных движущих факторов, от которых отошел от процедурного стиля программирования в ООП. Поскольку ООП заставляет программирование мыслить с точки зрения связанной и дискретной функциональности.

Похоже, вы действительно спрашиваете о SoC.

Есть много способов достичь SoC. Иногда это подразумевает разделение пользовательского интерфейса, логики обработки и персистентных слоев (например, рассмотрим шаблон проектирования MVC). Иногда это просто объединение связанных функций для уменьшения сложности; что RTF-контроль уже делает, содержащий все функции, необходимые для манипулирования данными, чтобы у вас не было дальнейших зависимостей.

0 голосов
/ 28 марта 2009

Пример, который вы выбрали, довольно сложный.

Вы правы, когда говорите, что компонент rtf memo очень слабо связан. Настолько свободно, что он практически не расширяется и может использоваться только как есть, так как объединяет представление / представление, контроллер и модель.

Если вы хотите увидеть пример хорошо спроектированной, расширяемой системы форматированного текста, взгляните на документацию Текстовая система OS X (или Gnustep, если вы хотите прочитать код) , Это сложно, потому что есть много проектных решений, которые необходимо принять и которые нужно скрыть от одного модуля к другому. Там вы можете напрямую работать в хорошей структуре.

Компонент rtf memo имеет ограниченную область использования, с которой вам, возможно, придется работать, используя хорошо разработанные классы:

  • Загрузка и сохранение данных компонентов имеет смысл, только если вам не нужно сохранять другие данные в вашей программе в том же файле / DB.
  • Он также плохо обрабатывает большие объемы данных.
  • И он понимает только небольшое подмножество rtf.
0 голосов
/ 27 марта 2009

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

Создайте объект на основе вашего родительского объекта RTF, но задайте методы обработки для хранения и т. Д. Как определенные объекты с помощью своих собственных методов.

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

...