Head First 设计方式 Design Pattern 5-6
Section 5 单件模式 Singleton
创建独一无二的, 只能有一个实例的对象. 延迟实例化 Lazy Instantiaze
单件模式 确保一个类只有一个实例, 并提供一个全局访问点
处理多线程
>Java 利用同步, 缺点是降低性能;
>Java 利用急切 Eagerly方式创建单件, JVM保证在任何线程访问instance之前先创建实例
1
|
public static synchronized Singleton
getInstance()
|
1
2
3
4
5
6
7
|
public class Singleton{
private static Singleton
instance = new Singleton();
private Singleton();
public static Singleton
getInstance(){
return instance;
}
}
|
>双重检查加锁 double checked locking, Java - volatile, synchronized
>Java 单件模式要避免多个类加载器
1
2
3
4
5
6
7
8
9
10
11
12
13
|
class Singleton
{
public :
static Singleton*
instance();
void Print();
private :
Singleton()
{};
void lockForSync()
{};
void unLockForSync()
{};
private :
static Singleton*
mpInstance;
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
Singleton*
Singleton::mpInstance = NULL; //static
member must be initialized
Singleton*
Singleton::instance()
{
if (
!mpInstance )
{
lockForSync();
if (
!mpInstance )
mpInstance
= new Singleton;
unLockForSync();
}
return mpInstance;
}
void Singleton::Print()
{
cout
<< "Print
the instance" <<
endl;
}
|
1
|
Singleton::instance()->Print();
|
Summary
>单件模式 确保一个类只有一个实例, 并提供全局访问点
>要点 确保程序中一个类只有一个实例; 提供访问这个实例的全局点; 私有构造器, 静态方法, 静态变量; 多线程问题; 双重检查加锁;
Java避免多个JVM加载器产生多个实例; Java单件注册表;
GlobalAccessPoint, DoubleChecked, Lazy, Private, ClassLoaders, Statically, GarbageCollector, Constructor, MultiThreading, Instance
---Section 5 End---
Section 6 命令模式 Command
封装方法调用 Method Invocation
命令模式 将请求封装成对象, 以便使用不同的请求, 队列或者日志来参数化其他对象. 支持可撤销的操作.
>Client创建一个ConcereteCommand, 设置Receiver; Invoke持有一个Command对象, 可调用execute方法执行请求; Command为所有命令声明了接口, 调用
命令对象的execute()方法, 让接收者进行相应的操作, 接口也具备undo()方法; 任何类可以作为接收者; ConcreteCommand定义了动作和接收者之间的绑定关系,
调用者通过execute()发出请求, 由ConcreteCommand调用接收者的一个或多个动作.
Party模式 MacrcoCommand, MetaCommandPattern
>队列请求 将运算打包, 在不同的线程中调用, example 线程池, 日程安排, 工作队列
>日志请求 store() load(), JAVA 对象序列化 Serialization; 在执行命令时将历史记录储存在磁盘上, 在重新启动时将命令对象重新加载, 依次调用 (持久化 Persistence).
从检查点 checkpoint 开始应用这些操作. 事务处理 Transaction, 一整批操作需必须全部完成, 否则退回原点, 没有做任何操作.
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
//Command
class ICommand
{
public :
enum commandType
{
TLight
= 1,
TDoor
= 2,
}
cmdType;
virtual void execute()
= 0;
virtual void undo()
= 0;
};
typedef map
< int ,
ICommand*> CmdMap;
typedef vector
<ICommand*> CmdVec;
class NoCommand
: public ICommand
{
public :
NoCommand()
{};
virtual void execute()
{ cout << "NoCommand" <<
endl ;};
virtual void undo()
{};
};
class Light
{
public :
void on()
{ cout << "Light
On" <<
endl; }
void off()
{ cout << "Light
Off" <<
endl; }
};
class LightOnCommand
: public ICommand
{
public :
LightOnCommand(Light*
light);
virtual void execute();
virtual void undo();
private :
Light*
mpLight;
};
class Door
{
public :
void open()
{ cout << "Door
Open" <<
endl; }
void close()
{ cout << "Door
Close" <<
endl; }
};
class DoorOpenCommand
: public ICommand
{
public :
DoorOpenCommand(Door*
door);
virtual void execute();
virtual void undo();
private :
Door*
mpDoor;
};
class SimpleRemoteControl
{
public :
SimpleRemoteControl()
{};
void setCommand(ICommand*
cmd);
void buttonPressed();
private :
ICommand*
mpCmdSlot;
};
class RemoteControl
{
public :
RemoteControl();
void setOnCommand( int id,
ICommand* onCmd);
void ButtonOnPressed( int id);
void ButtonUndoPressed();
private :
CmdMap
mOnCommands;
ICommand*
undoCommand;
};
class MacroCommand
: public ICommand
{
public :
MacroCommand()
{};
void addCommand(ICommand*
cmd);
virtual void execute();
virtual void undo();
private :
CmdVec
mCommands;
CmdVec
mUndoCmds;
};
|
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
//Command
LightOnCommand::LightOnCommand(Light*
light)
{
mpLight
= light;
}
void LightOnCommand::execute()
{
mpLight->on();
}
void LightOnCommand::undo()
{
mpLight->off();
}
void SimpleRemoteControl::setCommand(ICommand*
cmd)
{
mpCmdSlot
= cmd;
}
void SimpleRemoteControl::buttonPressed()
{
mpCmdSlot->execute();
}
DoorOpenCommand::DoorOpenCommand(Door*
door)
{
mpDoor
= door;
}
void DoorOpenCommand::execute()
{
mpDoor->open();
}
void DoorOpenCommand::undo()
{
mpDoor->close();
}
RemoteControl::RemoteControl()
{
undoCommand
= new NoCommand();
}
void RemoteControl::setOnCommand( int id,
ICommand* onCmd)
{
//mOnCommands.insert(pair<int,
ICommand*>(id, onCmd));
mOnCommands[id]
= onCmd;
}
void RemoteControl::ButtonOnPressed( int id)
{
CmdMap::iterator
iter = mOnCommands.find(id);
if (iter
!= mOnCommands.end())
{
ICommand*
pCmd = iter->second;
pCmd->execute();
undoCommand
= pCmd;
}
else
cout
<< "Command
NOT Found" <<
endl;
}
void RemoteControl::ButtonUndoPressed()
{
undoCommand->undo();
}
void MacroCommand::addCommand(ICommand*
cmd)
{
mCommands.push_back(cmd);
}
void MacroCommand::execute()
{
CmdVec::iterator
iter = mCommands.begin();
for (;
iter != mCommands.end(); iter++)
{
(*iter)->execute();
mUndoCmds.push_back(*iter);
}
}
void MacroCommand::undo()
{
while (!mUndoCmds.empty())
{
mUndoCmds.back()->undo();
mUndoCmds.pop_back();
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
//Command
SimpleRemoteControl*
sRemoteControl = new SimpleRemoteControl();
Light*
light = new Light();
LightOnCommand*
lightOnCmd = new LightOnCommand(light);
sRemoteControl->setCommand(lightOnCmd);
sRemoteControl->buttonPressed();
Door*
door = new Door();
DoorOpenCommand*
doorOpenCmd = new DoorOpenCommand(door);
sRemoteControl->setCommand(doorOpenCmd);
sRemoteControl->buttonPressed();
RemoteControl*
remoteControl = new RemoteControl();
remoteControl->setOnCommand(ICommand::TLight,
lightOnCmd);
remoteControl->ButtonOnPressed(ICommand::TLight);
remoteControl->ButtonOnPressed(ICommand::TDoor);
remoteControl->ButtonUndoPressed();
MacroCommand*
partyoCmd = new MacroCommand();
partyoCmd->addCommand(doorOpenCmd);
partyoCmd->addCommand(lightOnCmd);
partyoCmd->execute();
partyoCmd->undo();
|
Summary
>命令模式 将请求封装成对象, 可以使用不同的请求, 队列, 或者日志请求来参数化其他对象, 支持撤消操作.
>要点 将发出请求的对象和执行请求的对象解耦; 被解耦的两者之间通过命令对象进行沟通, 命令对象封装了接收者的一个或一组动作; 调用者通过调用命令对象的execute()发出请求,
调用接收者的动作; 调用者接受命令当作参数, 可以运行时动态进行; 命令可撤消, 实现undo()来回到执行前状态; 宏命令是命令的简单延伸, 允许调用多个命令, 支持撤消; 聪明命令对象,
直接实现请求, 代替接收者; 日志和事务系统;
Client, Invoker, Binds, Decoupled, VendorClasses, Execute, Receiver, Command, Undo, Request
---Section 6 End---