附录A: 余下的模式
6中介者 Mediator 集中相关对象之间复杂的沟通和控制方式
每个对象都会在自己的状态改变时告诉中介者; 每个对象都会对中介者发出的请求作出回应; 对象之间解耦;
>优点 对象的彼此解耦 增加对象的复用性; 将控制逻辑集中 简化系统维护; 让对象之间传递的信息变的简单轻量
>用途和缺点 用来协调相关的GUI组件; 如果设计不当 中介者对象本身会变得过于复杂
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
//***********Mediator***********
class Agent;
class Customer
//Colleague
{
public
:
Customer() : miCounter(0) {};
void purchase(Agent* m, int num);
void updateCounter(int n);
private
:
int miCounter;
};
class Producer
//IColleague
{
public
:
Producer(int n) : miInventory(n) {};
void delivery(int n);
private
:
intmiInventory;
};
classAgent
//Mediator
{
public
:
void setCustomer(Customer* c) { mCustomer = c;}
Customer* getColleagueA() { returnmCustomer;}
void setProducer(Producer* B) { mProducer = B;}
Producer* getProducer() { returnmProducer;}
void purchase(int num);
private
:
Customer* mCustomer;
Producer* mProducer;
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
//***********Mediator***********
void Customer::purchase(Agent* m, int num)
{
m->purchase(num);
}
void Customer::updateCounter(int n)
{
miCounter += n;
cout<<
"Customer: "
<<miCounter<<endl;
}
void Producer::delivery(int n)
{
miInventory -= n;
cout<<
"Producer: "
<<miInventory<<endl;
}
void Agent::purchase(int num)
{
mProducer->delivery(num);
mCustomer->updateCounter(num);
}
//Mediator
Agent* agent = newAgent();
Customer* customer = newCustomer();
Producer* producer = newProducer(100);
agent->setCustomer(customer);
agent->setProducer(producer);
customer->purchase(agent, 7);
|
7备忘录 Memeto 需要让对象返回之前的状态(请求'撤销')
>存储系统关键对象的重要状态; 维护关键对象的封装;
1)Memento 将Originator对象的内部状态存储起来; 2)Originator 创建一个含有当前内部状态的备忘录对象, 使用备忘录对象存储其内部状态; 3)Caretaker 负责保存备忘录对象, 不保存备忘录对象的内容
>优点 将状态放在外部, 防止和关键对象混淆, 帮助维护内聚; 保持关键对象的数据封装; 提供了容易实现的恢复能力;
>用途和缺点 用于存储状态; 缺点-存储和恢复状态的过程比较耗时; Java系统中可以使用序列化Serialization机制存储系统的状态.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
//***********Memento***********
class
StateMem
{
public
:
StateMem() : level(1), health(100) {};
int
level;
int
health;
};
class
Memento
{
public
:
void
setState(
const
StateMem& state);
StateMem getState() {
return
mstate;}
private
:
StateMem mstate;
};
class
Originator
{
public
:
Originator(
const
StateMem& state) { mstate = state;}
void
setLevel(
int
lev) { mstate.level = lev;}
void
setHealth(
int
h) { mstate.health = h;}
Memento* createMemento();
void
restoreMemento(Memento* mem);
void
StateOutput();
private
:
StateMem mstate;
};
class
Caretaker
{
public
:
void
saveMemento(Memento* mem) { mMemento = mem;}
Memento* retrieveMemento() {
return
mMemento;}
private
:
Memento* mMemento;
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
//***********Memento***********
void
Memento::setState(
const
StateMem& state)
{
mstate = state;
}
Memento* Originator::createMemento()
{
Memento* mem =
new
Memento();
mem->setState(mstate);
return
mem;
}
void
Originator::restoreMemento(Memento* mem)
{
mstate = mem->getState();
}
void
Originator::StateOutput()
{
cout<<
"------State------"
<<endl;
cout<<
"Health: "
<<mstate.health<<endl;
cout<<
"Level: "
<<mstate.level<<endl;
}
//Memento
StateMem state;
Originator* originator =
new
Originator(state);
Memento* memento = originator->createMemento();
Caretaker* caretaker =
new
Caretaker();
caretaker->saveMemento(memento);
originator->setLevel(3);
originator->setHealth(150);
originator->StateOutput();
originator->restoreMemento(caretaker->retrieveMemento());
originator->StateOutput();
|
8原型 Prototype(拷贝) 当创建给定类的实例的过程很复杂很昂贵时使用
>Prototype 抽象原型角色, 抽象原型的定义, 包含一个Clone接口; ConcretePrototype 具体原型角色, 被原型复制的具体对象; Client 客户调用端.
>优点 对客户隐藏制造新实例的复杂性; 提供让客户能产生未知类型对象的选项; 某些情况复制对象比创建新对象更有效;
>用途和缺点 在复杂的类层次中, 当系统必须从其中的许多类型创建新对象时考虑原型; 实例化的类是在运行时刻决定的; 缺点-对象的复制有时很复杂;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
//***********Prototype************
class
Prototype
{
public
:
typedef
enum
{
NotDefined = 0,
Human = 1,
Alien= 2,
} Category;
Prototype() {};
virtual
~Prototype() {};
virtual
Prototype* clone() = 0;
};
class
Human :
public
Prototype
{
public
:
typedef
enum
{
NotDefined = 0,
Male = 1,
Female = 2,
} Gender;
Human(
const
char
* name,
int
height);
Human(
const
Human& h);
virtual
~Human();
void
setGender(Gender g) { mGender = g;}
virtual
Human* clone();
void
Display();
private
:
char
* mName;
int
mHeight;
Gender mGender;
static
int
miObject;
static
int
ObjectNum();
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
//***********Prototype***********
int
Human::miObject = 0;
Human::Human(
const
char
* name,
int
height)
{
if
(name == NULL)
{
mName =
new
char
[1];
mName =
'\0'
;
}
else
{
mName =
new
char
[
strlen
(name) + 1];
strcpy
(mName, name);
}
mHeight = height;
mGender = NotDefined;
miObject++;
}
Human::Human(
const
Human& h)
{
mHeight = h.mHeight;
mGender = h.mGender;
mName =
new
char
[
strlen
(h.mName) + 1];
strcpy
(mName, h.mName);
miObject++;
}
Human::~Human()
{
delete
[]mName;
miObject--;
}
Human* Human::clone()
{
Human* human =
new
Human(*
this
);
//copy construct
return
human;
}
void
Human::Display()
{
cout<<
"Object number: "
<<ObjectNum()<<endl;
cout<<
"Name-"
<<mName<<
"& Height-"
<<mHeight<<endl;
}
int
Human::ObjectNum()
{
return
miObject;
}
//Prototype
Human* humanA =
new
Human(
"Peter"
, 180);
humanA->setGender(Human::Male);
Human* humanB = humanA->clone();
humanB->Display();
delete
humanA;
humanB->Display();
|
9访问者 Visitor 为一个对象的组合增加新的能力, 并且封装不重要时
>优点 允许对组合结构加入新的操作, 无需修改结构本身; 相对易于加入新操作; 访问者进行的操作代码比较集中;
>用途和缺点 访问者模式打破组合类的封装; 由于游走的功能, 组合结构更加难以改变;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
//***********Vistor************
class
IVistor;
class
IOperatingSystem
{
public
:
virtual
void
accept(IVistor* v) = 0;
virtual
void
setName(string n) { mName = n;}
virtual
string getName()
const
{
return
mName;}
private
:
string mName;
};
class
Windows :
public
IOperatingSystem
{
public
:
Windows(string name);
virtual
void
accept(IVistor* v);
};
class
Linux :
public
IOperatingSystem
{
public
:
Linux(string name, string version);
virtual
void
accept(IVistor* v);
string getVersion()
const
{
return
mVersion;}
private
:
string mVersion;
};
class
IVistor
{
public
:
virtual
void
visit(
const
Windows& win) = 0;
virtual
void
visit(
const
Linux& lin) = 0;
};
class
Display :
public
IVistor
{
public
:
virtual
void
visit(
const
Windows& win);
virtual
void
visit(
const
Linux& lin);
};
class
Collection
{
public
:
~Collection();
void
Add(IOperatingSystem* opSys);
void
Print(IVistor* v);
private
:
typedef
list<IOperatingSystem*> OperationSysList;
OperationSysList sysList;
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
//***********Vistor***********
Windows::Windows(string name)
{
setName(name);
}
void
Windows::accept(IVistor* v)
{
v->visit(*
this
);
}
Linux::Linux(string name, string version) : mVersion(version)
{
setName(name);
}
void
Linux::accept(IVistor* v)
{
v->visit(*
this
);
}
void
Display::visit(
const
Windows& win)
{
cout<<
"---Windows---"
<<endl;
cout<<
"Name: "
<<win.getName()<<endl;
}
void
Display::visit(
const
Linux& lin)
{
cout<<
"---Linux---"
<<endl;
cout<<
"Name: "
<<lin.getName()<<endl;
cout<<
"Version: "
<<lin.getVersion()<<endl;
}
Collection::~Collection()
{
OperationSysList::const_iterator iter = sysList.begin();
for
(; iter != sysList.end(); iter++)
delete
*iter;
}
void
Collection::Add(IOperatingSystem* opSys)
{
sysList.push_back(opSys);
}
void
Collection::Print(IVistor* v)
{
OperationSysList::const_iterator iter = sysList.begin();
for
(; iter != sysList.end(); iter++)
{
(*iter)->accept(v);
}
}
//Vistor
Collection collection;
collection.Add(
new
Windows(
"Windows 7"
));
Linux* lin =
new
Linux(
"Red Hat"
,
"6.0"
);
collection.Add(lin);
collection.Print(
new
Display());
|
End