• Nie Znaleziono Wyników

Obiektowe metody projektowania systemów

N/A
N/A
Protected

Academic year: 2021

Share "Obiektowe metody projektowania systemów"

Copied!
26
0
0

Pełen tekst

(1)

Obiektowe metody projektowania systemów

Command Pattern

(2)

Wstęp:

Command Pattern zawiera żądania jako obiekty, tym samym pozwala parametryzować użytkowników w

zależności od ich żądań, ustawia się lub rejestruje żądania i pobiera operacje.

Pozwala oddzielać wychodzenie od rozkazu z jego wykonania (opóźnionego działania).

Pozwala oddzielać użytkowników interfejsu od działań które wykonują.

Znany jest również jako Action lub Transaction.

(3)

Plan:

1. Cel stosowania 2. Przydatność 3. Struktura

4. Konsekwencja zastosowania 5. Przykładowy kod

6. Podsumowanie

(4)

Cel stosowania

Czasami jest konieczne przydzielać żądania do obiektów bez wiedzy o istnieniu jakichkolwiek operacji.

Na przykład użytkownik interfejsu narzędzi zawiera obiekty jako przyciski i menu, które doprowadzają żądania odzewu do użytkownika wejściowego.

Ale narzędzia nie mogą wykonywać rozkazów bezpośrednio w przycisku czy w menu, ponieważ tylko aplikacje, które używają narzędzi wiedzą co powinny zrobić z tym obiektem.

Jako projektanci narzędzi nie mamy możliwości wiedzieć co odbiorca żądań lub operacji będzie chciał zrobić.

Cel stosowania

(5)

Cel stosowania

Command pattern opisuje żądania nie

sprecyzowanych obiektów aplikacji poprzez zwrot zadań do obiektów.

Ten obiekt może być gromadzony i wpuszczany w obieg tak jak inne obiekty.

Kluczem do tego wzoru jest abstrakcyjna klasa Command, w której deklarujemy interfejs do

wykonywania operacji.

W najprostszej formie ten interfejs zawiera

Cel stosowania

(6)

Przydatność

Command pattern używaj wszędzie tam gdy:

• parametryzujesz obiekty poprzez akcje które wykonują

• precyzujesz, ustawiasz w kolejce i wykonujesz żądania w różnym czasie

• chcesz mieć możliwość cofać akcje

• chcesz mieć możliwość rejestrowania zmian tak by

mogły być one ponownie wykorzystane w przypadku gdy system przestanie działać

• chcesz budować system z wysokim poziomem operacji na operacjach prymitywnych

(7)

Struktura

(8)

Konsekwencje zastosowania

Zastosowanie Command Pattern pociąga za sobą następujące konsekwencje:

1. Command odsprzęga obiekty tak by wywoływać operacje jedną z tych, z których wiesz jak jest wykonywana

2. Command ma klasy obiekty. One mogą być zmieniane i powiększane tak jak inne obiekty.

3. Możliwe jest gromadzenie Command-ów w zbiorowym Commmand-dzie

4. W bardzo prosty sposób można dodać nowe

Command-y, ponieważ nie zmieniasz istniejących klas

(9)

Przykładowy kod

class Command {

public:

virtual ~Command() ;

virtual void Execute() = 0 ; protected:

Command() ; };

(10)

Przykładowy kod

class OpenCommand : public Command {

public:

OpenCommand(Application*) ; virtual void Execute() ;

protected:

virtual const char * AskUser() ; private:

Application* _application ; char * _response ;

};

(11)

Przykładowy kod

OpenCommand::OpenCommand (Application * a) {

_application = a ; }

(12)

Przykładowy kod

void OpenCommand::Execute() {

const char * name = AskUser() ; if (name != 0)

{ Document * document = new Document(name) ; _application->Add(document) ;

document->Open() ; }

}

(13)

Przykładowy kod

class PasteCommand : public Command {

public:

PasteCommand(Document*) ; virtual void Execute() ;

private:

Document* _document ; };

(14)

Przykładowy kod

PasteCommand::PasteCommand (Document * doc) {

_document = doc ; }

void PasteCommand::Execute () {

_document->Paste() ; }

(15)

Przykładowy kod

template <class Receiver>

class SimpleCommand : public Command {

public:

typedef void (Receiver::*Action)() ;

SimpleCommand(Receiver* r, Action a) : _receiver(r), _action(a) {}

virtual void Execute() ;

(16)

Przykładowy kod

template <class Receiver>

void SimpleCommand<Receiver>::Execute () {

(_receiver->*_action)() ; }

MyClass* receiver = new MyClass ; Command* aCommand = new

SimpleCommand<MyClass>(receiver, &MyClass::Action) ; aCommand->Execute() ;

(17)

Przykładowy kod

class MacroCommand : public Command {

public:

MacroCommand() ;

virtual ~MacroCommand() ; virtual void Add(Command*) ;

virtual void Remove(Command*) ; virtual void Execute() ;

(18)

Przykładowy kod

void MacroCommand::Execute () {

ListIterator<Command*> i(_cmds) ; for (i.First(); !i.IsDone(); i.Next())

{ Command* c = i.CurrentItem() ; c->Execute() ;

} }

(19)

Przykładowy kod

void MacroCommand::Add (Command * c) {

_cmds->Append(c) ; }

void MacroCommand::Remove (Command * c) {

_cmds->Remove(c) ; }

(20)

Podsumowanie:

Zawiera żądania jako obiekty

• Daje możliwość parametryzowania użytkowników w zależności od ich żądań

• Rejestruje zmiany

(21)

Przykład Commanda

class Policz { public:

void Podwoic( int& Wartosc ) {

Wartosc *= 2;

} };

class Command {

public:

virtual void Wykonaj( int& ) = 0;

(22)

Przykład Commanda

class SimpleCommand : public Command

{ typedef void (Policz::* Akcja)(int&);

Policz* Odbiorca;

Akcja Zadanie;

public:

SimpleCommand( Policz* rec, Akcja act ) { Odbiorca = rec;

Zadanie = act;

}

virtual void Wykonaj( int& num ) {

(Odbiorca->*Zadanie)( num );

}; }

(23)

Przykład Commanda

class MacroCommand : public Command { vector<Command*> list;

public:

void add( Command* cmd ) {

list.push_back( cmd );

}

virtual void Wykonaj( int& num ) {

for (int i=0; i < list.size(); i++)

(24)

Przykład Commanda

void main( void ) {

Policz Objekt;

Command* commands[3];

commands[0] = &SimpleCommand( &Objekt, &Policz::Podwoic );

MacroCommand two;

two.add( commands[0] );

two.add( commands[0] );

commands[1] = &two;

MacroCommand four;

four.add( &two );

four.add( &two );

commands[2] = &four;

int num, index;

while (true) {

cout << "Wybierz zadanie (0=2x 1=4x 2=16x): ";

cin >> num >> index;

commands[index]->Wykonaj( num );

cout << " " << num << '\n';

(25)

Bibliografia:

Stroustrup B.: The C++ Programming Language, Addison-Wesley, 2004

Gamma E., Helm R., Johnson R,

Vlissides J.: Design patterns

Elements of Reusable Object-Oriented Software,

Addison

Wesley

(26)

...i to by było tyle

na dzisiaj!

Cytaty

Powiązane dokumenty

Jedynie w metodzie main dla atrybutów typu static dodano do nazwy metody nazwę klasy Napis1 oraz operator wyboru „.”.(Nie jest to obowiązkowe, czyli bez podania nazwy klasy

void println() Terminate the current line by writing the line separator string.. void println(boolean x) Print a boolean and then terminate

Wywołanie metody niestatycznej Rysuj_graficznie() za pomocą referencji napis do obiektu typu Napis3 oraz operatora wyboru „.”-obowiązkowe w metodzie main własnej klasy dla

 Tworzenie obiektów klas produktów należących do tej samej rodziny..  Potrzeba

Adapter stanowi przykład niezwykle użyte- cznego wzorca projektowego, którego działanie polega na dostosowywaniu interfejsu istniejących już obiektów do interfejsu,

 Proces konstruowania musi zezwalać na różne reprezentacje

dać przy tym użytkownikowi możliwość podstawienia swojej wyspecjalizowanej wersji. CreateFileDialog zamiast. zwykłego dialogu otwarcia pliku da nam dialog z podglądem

•Każdy observer jest powiadamiany o zmianie w danych w obiekcie subject.. •W odpowiedzi na powiadomienie o zmianie observer wysyła zapytanie w celu synchronizacji własnych danych