Вы находитесь на странице: 1из 32

13

27.05.2013 .

,
.

CHAIN OF RESPONSIBILITY


,
.

,
,
.

#include <iostream>
struct Loan {
!
int amount;
!
Loan(int a) : amount(a) {}
};
class LoanApprover {
public:
!
void setNext(LoanApprover *_next) { next = _next; }
!
virtual void approve(Loan &loan) = 0;
protected:
!
LoanApprover *next;
};
class Manager : public LoanApprover {
public:
!
virtual void approve(Loan &loan) {
!
!
if (loan.amount < 100000)
!
!
!
std::cout << "Loan amount of " << loan.amount << " approved by the Manager" << std::endl;
!
!
else
!
!
!
next->approve(loan);
!
}
};
class Director : public LoanApprover {
public:
!
virtual void approve(Loan &loan) {
!
!
if (loan.amount < 250000)
!
!
!
std::cout << "Loan amount of " << loan.amount << " approved by the Director" << std::endl;
!
!
else
!
!
!
next->approve(loan);
!
}
};
class VicePresident : public LoanApprover {
public:
!
virtual void approve(Loan &loan) {
!
!
std::cout << "Loan amount of " << loan.amount << " approved by the Vice President" << std::endl;
!
}
};

int main() {
! Manager m;
! Director d;
! VicePresident vp;
! m.setNext(&d);
! d.setNext(&vp);
! Loan l1(50000), l2(200000), l3(500000);
! m.approve(l1);!! ! // approved by Manager
! m.approve(l2);!! ! // approved by Director
! m.approve(l3);!! ! // approved by Vice President
}

GUI.

COMMAND


, .

class TextBuffer {
! // ...
};
class EditorCommand {
public:
! EditorCommand(TextBuffer *tb) { /* ... */ }
! virtual void redo() = 0;
! virtual void undo() = 0;
};
class TypeTextCommand : public EditorCommand { /* ... */ };
class DeleteTextCommand : public EditorCommand { /* ... */ };
class SearchAndReplaceCommand : public EditorCommand { /* ... */ };
class InsertBlockCommand : public EditorCommand { /* ... */ };
// .... other commands ....
class Editor {
public:
! // ....
! void onCtrlVPressed() {
! ! addAndExecuteCommand(new InsertBlockCommand(currentSelection()));
! }
! void undo() {
! ! if (currentCommandIdx >= 0)
! ! ! commands[currentCommandIdx--]->undo();
! }
private:
! std::vector<EditorCommand *> commands;
! int currentCommandIdx;
};

,
( ),
( ).

. 8 ,
7- 1-.

+ = MacroCommand.

INTERPRETER

,
- ( ).

BooleanExp

::= VariableExp | Constant | OrExp | AndExp | NotExp |


'(' BooleanExp ')'
AndExp
::= BooleanExp 'and' BooleanExp
OrExp
::= BooleanExp 'or' BooleanExp
NotExp
::= 'not' BooleanExp
Constant
::= 'true' | 'false'
VariableExp ::= 'A' | 'B' | ... | 'Y' | 'Z'

class BooleanExp {
public:
!
BooleanExp();
!
virtual ~BooleanExp();
!
!
};

virtual bool evaluate(Context &) = 0;


virtual BooleanExp *copy() = 0;

class Context {
public:
!
bool lookup(const char *) const;
!
void assign(VariableExp *, bool);
};
class VariableExp : public BooleanExp {
public:
!
VariableExp(const char *variable_name) { /* ... */ }
!
virtual ~VariableExp();
!
};

// ....

class AndExp : public BooleanExp {


public:
!
AndExp(BooleanExp *, BooleanExp *);
!
// ....
};
class OrExp : public BooleanExp {
!
// ....
};
class NotExp : public BooleanExp {
!
// ....
};
class Constant : public BooleanExp {
!
// ....
};

BooleanExp *expression;
Context ctx;
VariableExp *x = new VariableExp("X");
VariableExp *y = new VariableExp("Y");
// (true and x) or (y and (not x))
expression = new OrExp(new AndExp(new Constant(true), x),
new AndExp(y, new NotExp(x)));
ctx.assign(x, false);
ctx.assign(y, true);
bool result = expression->evaluate(ctx);

ITERATOR


,
.

C++:

for (it = container.begin(); it != container.end(); ++it) {


! // ....
}

, / . .

MEDIATOR


,
.

class Node {
! Node *next;
! int value;
public:
Node(int v) : value(v), next(0) {}
void add_node(Node *n) {
if (next)
next->add_node(n);
else
next = n;
}
void traverse() {
cout << value << " ";
if (next)
next->traverse();
else
cout << '\n';
}

int main() {
! Node lst(11);
! Node two(22), thr(33), fou(44);
! lst.add_node(&two);
! lst.add_node(&thr);
! lst.add_node(&fou);
! lst.traverse();
! lst.remove_node(44);
! lst.traverse();
! lst.remove_node(22);
! lst.traverse();
! lst.remove_node(11);
! lst.traverse();
}

void remove_node(int v) {
if (next)
! if (next->value == v)
! next = next->next;
else
! next->remove_node(v);
}
};

class Node {
int val;
public:
Node(int v) : val(v) {}
int value() const { return val; }
};
class List {
public:
void add_node(Node *n) {
nodes.push_back(n);
}
void traverse() {
for (int i = 0; i < nodes.size(); ++i)
cout << nodes[i]->value() << " ";

int main() {
List lst;
Node one(11), two(22);
Node thr(33), fou(44);
lst.add_node(&one);
lst.add_node(&two);
lst.add_node(&thr);
lst.add_node(&fou);
lst.traverse();
lst.remove_node(44);
lst.traverse();
lst.remove_node(22);
lst.traverse();
lst.remove_node(11);
lst.traverse();
}

cout << '\n';


}
void remove_node(int v) {
for (vector<Node *>::iterator it = nodes.begin(); it != nodes.end(); ++it)
if ((*it)->value() == v) {
nodes.erase(it);
break;
}
}
private:
vector<Node *> nodes;

};

MEMENTO
,

,
.

Command.

class GraphicsBuffer;
class GraphicsBufferSnapshot {
public:
GraphicsBufferSnapshot(GraphicsBuffer *gb) {
// ...save state...
}
friend class GraphicsBuffer;
};
class GraphicsBuffer {
public:
// ...
GraphicsBufferSnapshot *createSnapshot() const;
void restoreSnapshot(GraphicsBufferSnapshot *);
};
class PaintCommand {
GraphicsBufferSnapshot *snapshot;
GraphicsBuffer
*buffer;
public:
PaintCommand(GraphicsBuffer *gb) : buffer(gb) {
snapshot = buffer->createSnapshot();
// ....
}
void redo() {
// do dirty painting
}
void undo() {
buffer->restoreSnapshot(snapshot);
}
}

OBSERVER

event-driven.

: MS Word.

class Event {
// ....
virtual const std::string &name() const = 0;
// ....
};
class EventReceiver {
public:
virtual void handleEvent(Event &) = 0;
};
class EventSource {
public:
void subscribe(std::string const &event_name, EventReceiver *receiver);
protected:
void trigger(Event &);
std::map<std::string, std::vector<EventReceiver *> > subscribers;
};
class Document : public EventSource {
public:
void insertText() {
// ...
trigger(Event("textChanged"));
}
};
class DocumentView : public EventReceiver {
protected:
void handleEvent(Event &ev) {
if (ev.name == "textChanged")
redraw();
// ...
}
}

STATE

class Machine;
class OffState;
class BaseState {
Machine *machine;
public:
BaseState(Machine *m) : machine(m) {}
virtual void on() = 0;
virtual void off() = 0;
};
class OnState : public BaseState {
public:
void on() { std::cout << "Machine Already ON!" << std::endl; }
void off() {
machine->setState(new OffState(machine));
std::cout << "Machine Turned OFF!" << std::endl;
}
};
class OffState : public BaseState {
public:
void off() { std::cout << "Machine Already OFF!" << std::endl; }
void on() {
machine->setState(new OnState(machine));
std::cout << "Machine Turned ON!" << std::endl;
}
};

class Machine {
BaseState *state;
public:
Machine() {
state = new OffState(this);
}
~Machine() { if (state) delete state; }
void on() { state->on(); }
void off() { state->off(); }
void setState(BaseState *new_state) {
if (state)
delete state;
state = new_state;
}
};

,

.

STRATEGY

,

.

,
.

class FormattingStrategy {
public:
FormattingStrategy(int width) { /* ... */ }
virtual std::string justify(std::string text) = 0;
};
class LeftJustifyStrategy : public FormattingStrategy {
public:
// ...
};
class RightJustifyStrategy : public FormattingStrategy {
public:
// ...
};
class CenterStrategy : public FormattingStrategy {
public:
// ...
};
class TextFormatter {
public:
enum {
LEFT_JUSTIFY,
RIGHT_JUSTIFY,
CENTER,
// ....
};
void setStrategy(int type, int width);
std::string justify(std::string text) = 0;
};

TEMPLATE METHOD

(hooks).

class Account {
public:
virtual void start() = 0;
virtual void allow() = 0;
virtual void end() = 0;
virtual int maxLimit() = 0;
// Template Method
void withdraw(int amount) {
start();

int main() {
AccountPower power;
power.withdraw(1500);
AccountNormal normal;
normal.withdraw(1500);

int limit = maxLimit();


if (amount < limit)
allow();
else
cout << "Not allowed" << endl;
end();
}
};
class AccountNormal : public Account {
public:
void start() { cout << "Start ..." << endl; }
void allow() { cout << "Allow ..." << endl; }
void end()
{ cout << "End ..."
<< endl; }
int maxLimit() { return 1000; }
};
// Derived class
class AccountPower
public:
void start() {
void allow() {
void end()
{
int maxLimit()
};

: public Account {
cout << "Start ..." << endl; }
cout << "Allow ..." << endl; }
cout << "End ..."
<< endl; }
{ return 5000; }

VISITOR

,
.

,
.

class Equipment {
public:
virtual ~Equipment();
const char *name() { return _name; }
virtual Watt power();
virtual Currency netPrice();
virtual Currency discountPrice();
virtual void accept(EquipmentVisitor &);
protected:
Equipment(const char *);
const char *_name;
};
class
class
class
class

FloppyDisk : public Equipment { /* ... */ };


Card : public Equipment { /* ... */ };
Chassis : public Equipment { /* ... */ };
Bus : public Equipment { /* ... */ };

class EquipmentVisitor {
public:
virtual ~EquipmentVisitor();
virtual void visitFloppyFisk(FloppyDisk *);
virtual void visitCard(Card *);
virtual void visitChassis(Chassis *);
virtual void visitBus(Bus *);
// ...
protected:
EquipmentVisitor();
};

void FloppyDisk::accept(EquipmentVisitor &visitor) {


visitor.visitFloppyFisk(this);
}
// ....
void Chassis::accept(EquipmentVisitor &visitor) {
for (i = 0; i < elements.size(); ++i)
elements[i]->accept(visitor);
visitor.visitChassis(this);
}
class PricingVisitor : public EquipmentVisitor {
public:
PricingVisitor();
Currency &getTotalPrice();
virtual void visitFloppyFisk(FloppyDisk *);
// ....
private:
Currency total;
};
class InventoryVisitor : public EquipmentVisitor {
// ....
};

.
, Visitor.