Принципы проектирования GRASP
GRASP (шаблон программного обеспечения для распределения общей ответственности) — это шаблон проектирования программного обеспечения для распределения общей ответственности.
Он был предложен Крейгом Ларманом, автором книги «Применение UML и шаблонов». Общий общий подход в процессе объектно-ориентированного проектирования состоит в том, чтобы представить обязанности, роли и взаимодействие объектов. Обычно мы сначала анализируем проблемную область в процессе кодирования и абстрагируем от нее объекты для решения проблемы. Разница между простым объектно-ориентированным дизайном и хорошим объектно-ориентированным дизайном заключается в том, как более разумно разделить роли объектов, назначить разумные обязанности объектам и взаимодействие между объектами.
В моем понимании девять принципов GRASP, семь принципов SOLID и 23 шаблона проектирования GOF. GRASP находится на верхнем уровне, SOLID дорабатывается на его основе, а GOF дополнительно обобщает более конкретные модели, основанные на этих принципах. Шаблон GoF — это решение конкретной проблемы, и GRASP смотрит на проектирование объектно-ориентированного программного обеспечения с более высокой точки зрения, которая является основой шаблона проектирования GoF. GRASP — это основной принцип распределения ответственности за объект, основная идея которого заключается в назначении ответственности и проектировании объектов с ответственностью.
Режим Информационного Эксперта (Информационный Эксперт)
определение:
Если у класса есть необходимая информация для выполнения обязанности, назначьте эту ответственность этому классу.
понимать:
Мы можем следовать этому принципу, когда не уверены, следует ли отнести ответственность к классу А или классу В. Этот принцип проектирования отличается от принципа единого проекта.Принцип единой ответственности рассматривает, относятся ли обязанности в одном классе к классу обязанностей. Информационная экспертная модель рассматривает, следует ли отнести один и тот же тип ответственности к классу A или классу B. Предположим, у нас есть прямоугольный класс Rectangle (со свойствами ширины и высоты в классе) и класс Measure, должны ли мы поместить метод getArea() в Rectangle или передать параметры ширины и высоты классу Measure и реализовать getArea в Measure () Шерстяная ткань? В соответствии с этим руководством, поскольку метод Rectangle уже имеет необходимые свойства для реализации getArea(), пришло время поместить метод getArea() в класс Retangle. Точно так же, что, если есть вычисляемое свойство? Предполагая соотношение сторон widthHeightRatio, этот принцип также соблюдается. == Этот принцип согласуется с моделью перегрузки в идее дизайна DDD, вы можете ее понять. ==
Создатель
определение:
Ответственность за создание экземпляров класса A может быть возложена на класс B, если выполняется одно или несколько из следующих условий.
- В содержит А;
- В агрегаты А;
- B владеет данными, которые инициализируют A и передают данные классу A при создании экземпляра класса A;
- B записывает экземпляр A;
- Б часто использует А.
понимать:
В объектно-ориентированном дизайне невозможно избежать создания объектов. Предположим, что объект B создает объект A, затем объект B соединяется с объектом A. И такого рода связь не может быть устранена, даже если вы возлагаете ответственность за создание объекта А на объект С, эта связь все равно существует, но она только переносится с объекта Б на объект С, и связь все еще существует в системе, которая нельзя избежать. Поэтому, когда мы не можем устранить связь, нам следует подумать о том, как уменьшить степень связи этой связи. Этот принцип дает ориентиры. Вышеприведенные условия потенциально указывают на то, что на самом деле B уже связан с A. Поскольку B уже имеет связь с A, мы могли бы также возложить на него ответственность за создание A. Таким образом, в системе существует только одна связь А и В. Если ответственность за создание A возложена на C, то между B и A будет две связи (B включает A, B часто использует A и т. д.) и C и A в системе. В Map JDK ответственность за создание класса Entry возлагается на Map, который его содержит. Еще один классический пример — заказ на создание артикула.
Низкое сцепление
определение:
Сцепление — это оценка степени зависимости между элементами (классами, модулями, подсистемами) в системе, и хороший дизайн должен максимально снизить эту степень.
Вот несколько примеров связующих отношений:
- A имеет свойство типа B;
- A вызывает метод B;
- Метод A содержит ссылку на B, например тип параметра метода B или возвращаемый тип B;
- A является прямым или косвенным подклассом B;
- B — это интерфейс, а A реализует этот интерфейс.
понимать:
Среди приведенных выше условий связи, чем больше случаев, тем выше степень связи. Эти условия просто и обычно называются «восприятием» А Б. Это восприятие отражается в свойствах объектов, параметрах методов, возвращаемых значениях методов и интерфейсах. Сильно связанные классы слишком сильно полагаются на другие классы, и такой дизайн приведет к следующему: модификация одного класса приведет к большему влиянию на другие классы, и систему будет сложно поддерживать и понимать. При повторном использовании сильно связанного класса ему приходится повторно использовать другие классы, от которых он зависит, а система имеет плохую возможность повторного использования. Есть несколько способов уменьшить степень связанности: свести к минимуму ссылки на другие классы, улучшить доступ к методам и свойствам и попытаться использовать принципы композиции/агрегации вместо наследования. По сути, полиморфизм в объектно-ориентированном программировании — это способ уменьшить связанность типов.Если полиморфизма нет, нашему методу нужно знать все типы подклассов, а полиморфизму нужно знать только родительский класс. Муфта уменьшенного типа.
Высокая сплоченность
определение:
То есть функционально тесно связанные обязанности должны быть помещены в класс и работать вместе для выполнения ограниченных функций. Это соответствует принципам единой ответственности и разделения интерфейсов SOLID.
понимать:
Очень наглядный пример: если функции класса очень связаны и несут единую ответственность, сложность класса будет снижена, а стоимость обслуживания будет снижена за счет снижения сложности. В традиционном шаблоне проектирования Дао мы должны попытаться разделить Дао с одной детализированной ответственностью за вызов Службы. В сервисе очевидно, какой Dao вызывается для какого типа операции с данными, и один Dao не будет слишком раздутым, чтобы ухудшить ремонтопригодность. Высокая связность также представляет собой высокую степень изоляции.Высокая изоляция означает, что изменение метода не повлияет на слишком много других классов.
Контроллер
определение:
Назначенные обязанности или полученное сообщение о событии в систему обработки класса. Этот класс может представлять: всю систему, устройства или подсистемы; соответствующее событие возникает, когда в сценариях вариантов использования системы один и тот же контроллер используется в тех же сценариях вариантов использования для обработки всех системных событий.
понимать:
Контроллер — это компонентный объект, отвечающий за получение или обработку событий. C в шаблоне MVC — это шаблон контроллера. И контроллер должен обрабатывать класс событий. Например, часто встречающийся в нашем проекте UserController отвечает за события добавления и удаления пользователей. Подсистема должна определить несколько контроллеров, соответствующих разным обработкам событий. Вообще говоря, контроллер должен делегировать функции, которые должны быть выполнены, сервису или другим объектам бизнес-обработки, он отвечает только за координацию и контроль бизнес-процесса и старается не включать слишком много бизнес-логики.
Полиморфизм
определение:
Используйте полиморфные операции, чтобы назначать обязанности типам, поведение которых изменяется при изменении связанных вариантов или поведения по мере изменения типов (классов).
понимать:
В объектно-ориентированном проектировании часто необходимо выполнять соответствующие операции в зависимости от типа объекта. Предположим, у нас есть класс рисования Draw, есть несколько графических классов Rectangle, Circle, Square. Если вы хотите рисовать в соответствии с разными классами графики, вам нужно использовать программную структуру if-else в методе класса Draw, а затем по очереди выбирать типы для рисования. Если вы добавите новый класс графики, вам нужно будет внести изменения в этот код. Это нарушает принцип открытого-закрытого. В форме полиморфизма конкретные шаги рисования передаются подклассу класса графики. Нет необходимости использовать программную структуру if-else и нет необходимости модифицировать класс Draw при добавлении графических классов. Внедряя полиморфизм, объекты подкласса могут переопределять поведение объектов суперкласса и лучше адаптироваться к изменениям. Шаблон стратегии и шаблон фабричного метода являются хорошими примерами полиморфизма.
Чистое изготовление
определение:
Назначьте набор высокосвязных обязанностей вымышленному или удобному классу «поведения», который не является концепцией в проблемной области, а вымышленной вещью для поддержки высокой сплоченности, низкой связанности и повторного использования.
понимать:
Модель предметной области в объектно-ориентированном проектировании — это смоделированное представление понятий предметной области или объектов реального мира. Ключевая идея создания модели предметной области заключается в уменьшении репрезентативных различий между мышлением программистов и шаблонами программного обеспечения. Поэтому в объектно-ориентированном проектировании большинство классов в системе являются производными от реальных классов в реальном мире. Однако при назначении ответственности этим классам можно столкнуться с некоторыми принципами проектирования, которые трудно удовлетворить при низкой связанности и высокой связности. Чисто вымышленный подход к этой проблеме состоит в том, чтобы возложить набор очень связанных обязанностей на искусственный класс, который представляет собой не понятие в проблемной области, а вымышленную вещь. Очевидным примером является шаблон адаптера, который устраняет связь между двумя объектами, изобретая концепцию адаптера.
Многим проектам необходимо работать с базой данных, чтобы сохранить некоторые объекты в системе. Совет, который дает шаблон информационного эксперта, состоит в том, чтобы возложить ответственность за сохраняемость на каждый конкретный класс модели. Но было показано, что это предположение несовместимо с принципом высокой сплоченности и низкой связанности. Поэтому текущая практика имеет тенденцию добавлять в проект такие классы, как DAO или Repository. Эти классы не существуют в модели предметной области.
Косвенность
определение:
Назначьте обязанности промежуточным объектам для координации операций между компонентами или службами, чтобы они не были связаны напрямую. Промежуточный объект — это посредник, установленный между другими компонентами.
понимать:
«Посредник» просто означает обрабатывать вещи через посредника. Два объекта, которые изначально находились в непосредственном контакте, могут взаимодействовать через другой промежуточный объект, чем достигается изоляция и развязка.Изменения в одном объекте не повлияют на другой объект, а только на промежуточный объект. В шаблоне проектирования шаблон адаптера и шаблон моста используют промежуточный объект для разделения.
Защищенные варианты
определение:
Определите элементы, которые, как ожидается, изменятся или станут нестабильными, и назначьте ответственных за создание для них стабильных «интерфейсов».
понимать:
Режим защищенных изменений, или сокращенно PV, является основой большей части программирования и проектирования и одним из основных мотивов для режима, который позволяет системе адаптироваться и изолировать изменения. Он соответствует принципу «открыто-закрыто» в принципах объектно-ориентированного проектирования, то есть расширению функциональности элемента без изменения исходного элемента (класса, модуля, подсистемы или системы). Очевидным примером является шаблон стратегии, который имеет дело с новыми стратегиями, которые могут возникнуть путем создания интерфейсов стратегии и определения внутри них абстрактных методов. Когда в будущем появится новая стратегия, вам не нужно менять исходный код, а нужно создать новый класс, реализующий интерфейс стратегии.