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---