Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Patterns2015

.pdf
Скачиваний:
10
Добавлен:
14.02.2015
Размер:
42.45 Mб
Скачать

Возможныенедостатки

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

большойобъеминформациидлязанесениявпамя

тьхранилиеслиопетхлярациянения

выполняедостаточночастося

.

81

6Команда.4 (

Command)

 

Проблема

 

 

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

 

запрошиктобудетполучателемно

 

Решение

 

 

ПаттернКоманда""разрыва

етсвязьмеждуобъект,инициопеми, рацииующим

объектом,имеющиминфортом,какеевыполнитьацию,кртогосоздаетсямеобъект

 

"Команда",котможноррыйсширятьманимкакпулироватьобъектом.

 

Этоп зводнимбъляотпректзапросынеизвемвлять

стнымобъектамприложения,

преобразсамзапрвобъектсвав

 

.

82

Связывакомандысобъектомие

 

 

 

Вариантреализац,представленныйнаииаграмме,ос созданииованкоманды

 

 

параметромобъекта

-получателяобъект(

–получательявляетсяпараметромконстр

уктора

конкреткома) ндыой

 

 

 

Возможенвардинамическогоантсвязывкомполучателеман.Длядыияэтойцели

 

 

командыдолженбытьспециальныйметод

 

setReceiver(Receiver *)

 

Диаграммаклассов

Обязанностиклассов

Command - интерфейсдлявыполненоперац; ияи

• ConcreteCommand

- опредсвязьмобъектомждуляет

-получателемReceiverи

действи;реализуетоп мрацию

execute()путемвызовасоответствующихопераций

 

 

83

 

объекта Receiver;

Client - создаобъклассаеConcreteCommandкт иустанавливаегоп лучат; етля

Invoker - обращаетсяккомандедлявыполнениязапроса;

Receiver - располагаетинформациспособахвыполненоп йрацияй

Пример( class Command)

//Student - объект-получателъкоманды==

//управляемоеустройство

class Student;

// интерфейс команды class Command {

public:

virtual void execute () = 0;

};

Класс Student (получзаднавыполнениетельния)

class Student {

 

protected:

 

const char *state;

const char *myName;

Command *c;

// похранениядлякоманды

public:

void setState( const char *inState ) { state = inState; }

void printState() { cout << myName<<": "<<state << endl; } void saveCommand(Command *com) { c=com; }

// сохранениевыполняемойкоманды void doAction() { // метод,вызыизвнеамый

c->execute (); // выполняем команду

}

Student (const char * name){myName = name;}

};

Конкреткомандыые

 

class CmdRun : public Command {

// работает как invoker

protected:

 

Student *c; // объект,которымуправлятьдеткоманда

 

public:

 

CmdRun(Student * stud){ c=stud; stud->saveCommand(this); cout<<"CmdRun is ready\n";}

void execute () { c->setState("I am running along the river"); } // вызываетметод setState объекта-получат,.е.студенталя

};

class CmdShooting : public Command { protected:

Student *c; public:

84

CmdShooting(Student * stud){ c=stud; stud->saveCommand(this); cout<<"CmdShooting is ready\n";}

void execute () {

c->setState("I am shooting on dartboard"); }

};

 

Main

int main() {

Student* s[5] = { new Student("Petr"), new Student("Ivan"),

new Student("Leha"), new Student("Dasha"), new Student("Masha") }; cout<<"Students on the drill:\n\n";

//создаемкомандыуказаниемполучзапросадействиятеля:

CmdRun *cR1 = new CmdRun(s[0]); CmdShooting *cS1 = new CmdShooting(s[1]); CmdShooting *cS2 = new CmdShooting(s[2]);

CmdRun

*cR2 = new CmdRun(s[3]);

CmdShooting *cS3 = new CmdShooting(s[4]);

// выполныем действие над объектом:

for (int i=0; i<5; i ++)

s[i]->doAction();

cout<<"\n Execute is done!\n\n";

//

проверяем результат выполнения действия

for (int i=0; i<5; i ++)

s[i] -> printState();

return 0;

 

 

}

Выполнение

85

Результатыприменпатткоманданиярна

:

1. Командаразрываетсвязьмеждуобъект,инициопеми, рациюующим

объектом,

имеющиминфортом,какеевыполнитьацию;

 

2.команды - этосамыенастоящиеобъекты.Допускаетсяманимипулировать расширятьихточнотакже, вакслучаелюбымидругимиобъектами;

3. изпростыхкоможнособиратьандсостп( компоновщттернвные

ик);

4.добавлятьновыекоманды,посколькугконикакиесуществующиеклассыизменять ненужно.

6Посетитель.5 (

Visitor)

 

 

Проблема

 

 

 

Надкаждымобънекструктуоторойомнапример( ,де)выеваполняютсяоперации.

 

 

Необхоопределновуюоперациюимо,нетьз

меняяклассыобъектов

.

Решение

 

 

 

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

 

 

посетителем,передаватьего

 

элементабстрклпоамеректногоссанеобходимости

 

выпдополнительлненияопераций.Доп опервойныхение

 

ациивыптольковняется

посетителе.

 

 

 

Класспримерчский - семантическоедеревокомпилятора.Существуютразличные программыиспользэтогдерева: ования

Проверитьналичиеобъявленияпеременных

Вывесписокпеременныхти

Вычислобъемзанпамяимаемойть

ти

Вывестидампприотладкепрограммы

86

Visitor объявляетоперацию

visit()длякаждогокласElementвструктуре.Имяи

сигнатураэтойоперациииденткласс,котфицируютпопосетителюыйзапрос

 

visit()Врезульт.посетизн,элементатееткаель

когоконкретногоклассапосещает.

ConcreteVisitor - реализуетвсеоперации,объявленныеклассеVisitor.

Element - определяетоперацию

accept(),котораяпринимаетпосетивкачествееля

 

аргумента;

 

 

ConcreteElement - реализуетоперацию

accept(),прини

мающуюпосетителякак

аргумент

class Horse; class Tiger; class PussyCat; class Visitor { public:

Visitor() {}

virtual void visit(Horse *horse) {} virtual void visit(Tiger *tiger) {} virtual void visit(PussyCat *cat) {}

};

class HorseVisitor : public Visitor { public:

HorseVisitor() {}

87

void visit(Horse *horse)

{

cout << "Horse dances waltz" << endl; }

};

 

class TigerVisitor :public Visitor {

public:

 

TigerVisitor() {}

 

void visit(Tiger *tiger)

{

cout << "Tiger walks on his hind legs" << endl; }

};

class Animal { private:

int age; public:

Animal() {} virtual void feed()

{

cout << "Animal Feed" << endl;

}

virtual void accept(Visitor *v) {}

};

class Horse : public Animal { public:

Horse() {}

virtual void accept(Visitor *v) { v->visit(this); }

};

class PussyCat : public Animal{ public:

PussyCat() {}

virtual void feed() { cout << "PussyCat likes fish" << endl; }

};

class Tiger : public Animal{ public:

Tiger() {}

virtual void feed()

{

cout << "Tiger likes meet" << endl;

}

void growl() { cout << "Tiger growls" << endl; } virtual void accept(Visitor *v) { v->visit(this); }

};

int main(int argc, char *argv[]) {

Animal* zoo[4] = {new Tiger(),new Tiger(), new Horse(), new PussyCat()}; HorseVisitor *hVisitor = new HorseVisitor();

TigerVisitor *tVisitor = new TigerVisitor(); for (int i=0; i<4; i++){

88

zoo[i] -> feed();

zoo[i] -> accept(tVisitor); zoo[i] -> accept(hVisitor);

}

return 0;

}

Преимущества

Упрдощаетсябавлнопвых,объниерацийродствдиняоперацииклассетнные "Посетитель".

• Позвлегкодобаляетнооперациивитьыеб змене

ниясуществующегок дабъектов

Недостатки

ЗатрудненодобавновыхклассовениеКонкретныйЭлемент" ",посколькутребуется объявлениеновойабстрактноперацииклассеПосетитель" "й.

6.6 Перенаправление(

Indirection)

Проблема

 

Какперераспределитьобязанн

остиобъект,чтобыобеспечивтсутспрямоготьвие

связывания?

 

Решение

 

Присвоитьгруппуобязанностейвысокойстепеньюзацепленияпромежуточномуклассу, котонепредставлконкретныйпонизпредметнойятияобластигосинтезировать(

89

искусственнуюсущнос тьдляобеспечениявысокогозацепленияслабогосвязывания).

6.7 Цепочкаобязанностей(Chain of Responsibility)

Проблема

Запрможетбытьсбрабнескольтанбъе. ктамиими

Решение

Связатьобъекты -получателизапросавце очкуередатьзапрвдольс этойцепочки, понекабудетобработан.КонкретныйОбр" "обрабатываетзапрос, которыйботчик отвечает,имеетдоск воемупреемникуупнапразапрсвопрляемус,еслитемнику неможетбрзасамботатьпрос.

Пример

90

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]