Head First 设计模式 Design Pattern 5-6
Section 5 单件模式 Singleton
创建独一无二的, 只能有一个实例的对象. 延迟实例化 Lazy Instantiaze
单件模式 确保一个类只有一个实例, 并提供一个全局访问点
处理多线程
>Java 利用同步, 缺点是降低性能;
>Java 利用急切 Eagerly方式创建单件, JVM保证在任何线程访问instance之前先创建实例
1public
static
synchronized
Singleton getInstance()
1234567public
class
Singleton{
private
static
Singleton instance =
new
Singleton();
private
Singleton();
public
static
Singleton getInstance(){
return
instance;
}
}
>双重检查加锁 double checked locking, Java - volatile, synchronized
>Java 单件模式要避免多个类加载器
12345678910111213class
Singleton
{
public
:
static
Singleton* instance();
void
Print();
private
:
Singleton() {};
void
lockForSync() {};
void
unLockForSync() {};
private
:
static
Singleton* mpInstance;
};
123456789101112131415161718Singleton* 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;
}
1Singleton::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, 一整批操作需必须全部完成, 否则退回原点, 没有做任何操作.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990//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;
};
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293//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();
}
}
123456789101112131415161718192021//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---