Структурирование программ
Объектно-ориентированные программы имеют два вида структуры. Можно быть замечен в иерархии наследования определений классов. Другой очевидно в образце передачи сообщений, когда работает программа. Эти сообщения показывают сеть соединений объектов.
-
Иерархия наследования объясняет, как объекты связаны типом. Например, в программе, что использование воды моделей, могло бы оказаться, что краны и каналы являются тем же видом объекта, за исключением того, что краны могут быть включены и выключены и каналы могут иметь многократные соединения с другими каналами. Это подобие было бы получено в проектировании программы если
FaucetиPipeклассы наследовались от общего суперкласса. -
Сеть соединений объектов объясняет, как работает программа. Например,
Applianceобъекты могли бы отправить сообщения, запрашивающие воду к клапанам и клапанам к каналам. Каналы могли бы связаться сBuildingобъект, иBuildingобъект со всеми клапанами, кранами и каналами, но не непосредственно с устройствами. Для передачи друг с другом таким образом объекты должны знать друг о друге.Applianceобъекту было бы нужно соединение с aValveобъект и aValveвозразите против aPipeобъект, и т.д. Эти соединения определяют структуру программы.
Объектно-ориентированные программы разработаны путем разметки сети объектов с их способами поведения и образцами взаимодействия и путем расположения иерархии классов. Существует структура и в действии программы и в его определении.
Соединения розетки
Часть задачи разработки объектно-ориентированной программы должна расположить объектную сеть. Сеть не должна быть статичной; это может измениться динамично, когда работает программа. Отношения между объектами могут быть импровизированы по мере необходимости, и бросок объектов, играющих присвоенные роли, может время от времени изменяться. Но должен быть сценарий.
Некоторые соединения могут быть полностью переходными. Сообщение могло бы содержать параметр, идентифицирующий объект, возможно отправитель сообщения, что получатель может связаться с. Поскольку это реагирует на сообщение, получатель может отправить сообщения в тот объект, возможно идентифицировав себя или все еще другой объект, с которым может поочередно связаться объект. Такие соединения являются мимолетными; они длятся только пока цепочка сообщений.
Но не все соединения между объектами может быть обработан на лету. Некоторая потребность, которая будет зарегистрирована в структурах данных программы. Существуют различные способы сделать это. Таблица могла бы быть сохранена соединений объектов, или могла бы быть служба, идентифицирующая объекты по имени. Однако самый простой путь для каждого объекта иметь переменные экземпляра, отслеживающие другие объекты, с которыми это должно связаться. Эти переменные экземпляра — назвали выходы , потому что они записывают выходы для сообщений — определяют основные соединения между объектами в сети программы.
Несмотря на то, что имена переменных экземпляра выхода произвольны, они обычно отражают роли та игра объектов выхода. Рисунок 4-1 иллюстрирует объект с четырьмя выходами — агент, друг, сосед и босс. Объекты, играющие эти роли, могут измениться время от времени, но роли остаются тем же.
Когда объект сначала инициализируется и никогда может не изменяться, установлены некоторые выходы. Другие могли бы быть установлены автоматически как последствие других действий. Все еще другие могут быть установлены свободно, с помощью методов, предоставленных просто с этой целью.
Однако, они установлены, переменные экземпляра выхода показывают структуру приложения. Они объекты ссылки в связывающуюся сеть, очень поскольку компоненты водной системы соединяются их физическими соединениями или как частные лица, соединяются их образцами общественных отношений.
Внешние и внутренние соединения
Соединения розетки могут получить много различных видов отношений между объектами. Иногда соединение между объектами, связывающимися более или менее как равноправные партнеры в приложении, каждом с его собственной ролью для игры и никакое доминирование другой. Например, Appliance объект мог бы иметь переменную экземпляра выхода для отслеживания клапан, с которым он подключен.
Иногда один объект должен быть замечен как являющийся частью другого. Например, a Faucet объект мог бы использовать a Meter возразите для измерения суммы выпускаемой воды. Meter объект не служил бы никакому другому объекту и будет действовать только согласно заказам от Faucet объект. Это была бы внутренняя часть Faucet объект, в отличие от Appliance внешнее соединение объекта с a Valve объект.
Точно так же объект, наблюдающий за другими объектами, мог бы сохранить список своих зарядов. A Building объект, например, мог бы иметь список весь Pipe объекты в программе. Pipe объекты считали бы внутренней частью Building возразите и принадлежите ему. Pipe объекты, с другой стороны, поддержали бы внешние соединения друг с другом.
Внутренние выходы ведут себя по-другому от внешних. Когда объект освобожден или заархивирован в файле на диске, объекты, на которые указывают его внутренние выходы, должны быть освобождены или заархивированы с ним. Например, когда кран освобожден, его метр представляется бесполезный и поэтому должен быть освобожден также. Кран, заархивированный без его метра, был бы мало полезен, когда он разархивировал (если он не мог создать новое Meter объект для себя).
Внешние выходы, с другой стороны, получают организацию программы в более высоком уровне. Они записывают соединения между относительно независимыми субкомпонентами программы. Когда Appliance объект освобожден, Valve объект, с которым это было подключено все еще, полезен и остается на месте. Когда Appliance объект разархивирован, он может быть подключен к другому клапану и резюме, играя тот же вид роли, которую он играл прежде.
Активация объектной сети
Объектная сеть установлена в движение внешним стимулом. Если Вы запишете интерактивное приложение с пользовательским интерфейсом, то это будет реагировать на пользовательские действия с клавиатурой и мышью. Программа, пробующая к факторным очень большим количествам, могла бы запуститься при передаче ее целевое число командной строке. Другие программы могли бы реагировать на данные, полученные по телефонной линии, информация, полученная из базы данных, или информация о состоянии механического устройства обрабатывает мониторы программы.
Программы часто активируются потоком событий, которые являются отчетами внешнего действия некоторого вида. Приложения, выводящие на экран пользовательский интерфейс, управляются событиями с клавиатуры и мыши. Каждое нажатие ключа или щелчок мыши генерируют события, которые приложение получает и отвечает на. Объектно-ориентированная структура программы (сеть объектов, это подготовлено реагировать на внешний стимул) идеально подходит для этого вида управляемого пользователями приложения.
Агрегация и разложение
Другая часть задачи проекта решает расположение классов — когда добавить функциональность к существующему классу путем определения подкласса и когда определить независимый класс. Проблема может быть разъяснена путем воображения того, что произошло бы в крайнем случае:
-
Возможно забеременеть программы, состоящей всего из одного объекта. Поскольку это - единственный объект, это может отправить сообщения только в себя. Это поэтому не может использовать в своих интересах полиморфизм или модульный принцип множества классов или проектирования программы, задуманного как сеть соединенных объектов. Истинная структура программы была бы скрыта в определении класса. Несмотря на то, чтобы быть записанным в объектно-ориентированном языке, был бы очень мало, который был объектно-ориентирован об этом.
-
С другой стороны, также возможно вообразить программу, состоящую из сотен различных видов объектов, каждого с очень немногими методами и ограниченной функциональностью. Здесь, также, структура программы была бы потеряна, на сей раз в лабиринте соединений объектов.
Очевидно, лучше избегать любого из этих экстремальных значений, сохранять объекты достаточно большими для взятия на себя существенной роли в программе, но достаточно маленький для хранения той роли четко определенной. Структура программы должна быть легкой для понимания в образце соединений объектов.
Тем не менее, вопрос часто возникает того, добавить ли больше функциональности к классу или факторизовать дополнительную функциональность и помещать его в отдельное определение класса. Например, a Faucet возразите должен отслеживать то, сколько воды используется в течение долгого времени. Чтобы сделать это, Вы могли или реализовать необходимые методы в Faucet класс, или Вы могли разработать обобщение Meter объект выполнить работу, как предложено ранее. Каждый Faucet объект имел бы выход, подключающий его к a Meter объект и метр не взаимодействовали бы ни с каким объектом, но краном.
Выбор часто зависит от Ваших целей проекта. Если Meter объект мог использоваться больше чем в одной ситуации, возможно в другом проекте полностью, это увеличит возможность многократного использования Вашего кода к фактору задача измерения в отдельный класс. Если у Вас есть причина сделать Faucet объекты, максимально автономные, функциональность измерения могла быть добавлена к Faucet класс.
Обычно лучше попробовать за повторно используемый код и избежать иметь большие классы, делающие столько вещей, что они не могут быть адаптированы к другим ситуациям. Когда объекты разработаны как компоненты, они становятся так намного больше допускающими повторное использование. Какие работы в одной системе или конфигурации могли бы хорошо работать в другом.
Деление функциональности между различными классами не обязательно усложняет интерфейс программирования. Если Faucet класс сохраняет Meter частный объект, Meter интерфейс не должен был бы быть опубликован для пользователей Faucet класс; объект был бы так же скрыт как любой другой Faucet переменная экземпляра.
Модели и платформы
Объекты комбинируют состояние и поведение, и тем самым напомните вещи в реальном мире. Поскольку они напоминают реальные вещи, разрабатывание объектно-ориентированной программы очень походит на взгляды о реальных вещах — что они делают, как они работают, и как одна вещь подключена к другому.
При разработке объектно-ориентированной программы Вы, в действительности, соединяете компьютерное моделирование того, как что-то работает. Объектные сети смотрят и ведут себя как модели реальных систем. Объектно-ориентированная программа может считаться моделью, даже если нет никакого фактического дубликата к ней в реальном мире.
Каждый компонент модели — каждого вида объекта — описан с точки зрения его поведения, ответственности и взаимодействий с другими компонентами. Поскольку интерфейс объекта находится в своих методах, не своих данных, можно начать процесс проектирования путем размышления о том, что системный компонент должен сделать, не, как это представлено в данных. Как только поведение объекта решено, надлежащая структура данных может быть выбрана, но это - вопрос реализации, не первоначальный проект.
Например, в программе водного использования, Вы не начали бы путем решения что Faucet структура данных была похожа, но что Вы хотели a Faucet объект сделать — делает соединение с каналом, быть включенным и выключенным, скорректировать скорость потока, и т.д. Проект поэтому не связывается с самого начала выбором данных. Можно выбрать поведение сначала и реализовать данные впоследствии. Ваш выбор структур данных может изменяться в течение долгого времени, не влияя на проект.
Разработка объектно-ориентированной программы не обязательно влечет за собой пишущие большие объемы кода. Возможность многократного использования определений классов означает, что возможность является большой для создания программы в основном из классов, разработанных другими. Могло бы даже быть возможно создать интересные программы полностью из классов, которые кто-то еще определил. Когда комплект определений классов растет, у Вас есть все больше допускающих повторное использование частей для выбора из.
Допускающие повторное использование классы прибывают из многих источников. Проекты разработки часто приводят к допускающим повторное использование определениям классов, и некоторые инициативные разработчики представляют их на рынке. Среды объектно-ориентированного программирования обычно идут с библиотеками классов. В библиотеках Cocoa существует хорошо более чем тысяча классов. Некоторые из этих классов предлагают базовые услуги (хеширование, хранение данных, удаленный обмен сообщениями). Другие являются более определенными (устройства пользовательского интерфейса, видеодисплеи, звук).
Как правило, группа классов библиотеки сотрудничает для определения частичной структуры программы. Эти классы составляют платформу программного обеспечения (или набор), который может использоваться для создания множества различных видов приложений. При использовании платформы Вы принимаете модель программы, которую она обеспечивает, и адаптируйте свой проект к ней. Вы используете платформу:
-
Инициализация и расположение экземпляров классов платформы
-
Определение подклассов классов платформы
-
Определение новых собственных классов для работы с классами, определенными в платформе
Каждым из этих способов Вы не только адаптируете свою программу к платформе, но и Вы также адаптируете универсальную структуру платформы к специализированным целям Вашего приложения.
Платформа, в сущности, устанавливает часть объектной сети для Вашей программы и обеспечивает часть ее иерархии классов. Ваш собственный код завершает модель программы, запущенную платформой.