Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТП шпоры.docx
Скачиваний:
10
Добавлен:
20.09.2019
Размер:
115.03 Кб
Скачать

Обратное влияние клиентов на интерфейсы

Когда речь идет о воздействиях, вызывающих изменения в программах, обыч­но это относится к тому, каким образом изменения в интерфейсах влияют на пользователей. Иногда пользователь вносит изменения в интерфейс. Например, некоторые пользователи Timer регистрируют более одного запро­са за единицу времени. Рассмотрим объект TimedDoor. Если проверка показала, что объект Door открыт, объекту Timer направляется сообщение Register, содержащее запрос о перерыве. Но еще до окончания перерыва дверь закрыва­ется, остается некоторое время закрытой, потом открывается снова. Вследствие этого регистрируется новый запрос об интервале еще до завершения первого ин­тервала. Наконец, завершается первый интервал, вызывается функция Timeout из TimedDoor. Звуковой сигнал Door подается ошибочно. Можно исправить эту ситуацию с помощью соглашения

Timer with ID class Timer {

public:

void Register(int timeout,int timeOutld, TimerClient* client);};

class TimerClient {public:

virtual void TimeOut (int timeOutld =0;};

Ясно, что это изменение окажет влияние на всех пользователей TimerClient. Это происходит вследствие недостатков, присущих timeOutld.

ISP: принцип отделения интерфейса Когда клиенты вынужденно зависят от методов, которыми не пользуются, они становятся субъектами тех изменений, которым подвержены эти методы. В ре­зультате между всеми клиентами могут возникать непредсказуемые состыковки. Другими словами, если клиент находится в зависимости от класса, содержащего неиспользуемые данным клиентом методы, которые применяются другими кли­ентами, то клиент находится под влиянием изменений, вносимых в класс этими клиентами. Желательно избегать подобных состыковок, поэтому необходимо от­делить интерфейсы.

Группировка клиентов Часто клиенты группируются вместе в соответствии со служебными мето­дами, к которым они обращаются. Подобная группировка позволяет создавать выделенные интерфейсы для каждой группы, а не для каждого клиента. При этом подходе значительно сокращается количество интерфейсов, реализуемых данной службой, причем в данном случае служба не должна зависеть от каждого типа клиента. Иногда методы, вызываемые различными группами клиентов, "накладывают­ся" друг на друга. Если "наложение" невелико, тогда интерфейсы этих групп остаются отделенными. Общие функции объявляются во всех частично совпада­ющих интерфейсах. Серверный класс наследует общие функции из каждого из этих интерфейсов, но реализует их только один раз. При поддержке объектно-ориентированных приложений часто изменяются ин­терфейсы существующих классов и компонентов. Иногда эти изменения имеют большое влияние и приводят к повторному компилированию и развертыванию очень больших частей системы. Эти процессы можно упростить, добавляя к су­ществующим объектам новые интерфейсы без изменения существующего ин­терфейса. Клиенты "старых" интерфейсов, которым необходим доступ к новому интерфейсу, могут запрашивать объект для этого интерфейса, как показано в ли­стинге/

void Client(Service* s) {

if (NewService* ns - dynamic_cast<NewService*>(s))

{// применение нового служебного интерфейса}

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