一、单例模式
1、定义:确保一个类只有一个实例,并提供全局访问点
1)保证该类只有一个实例
2)提供全局的访问的入口
3)某些情况下我们只想有一个实例,例如:线程池、缓存、对话框、注册表的对象和日志对象、显卡等设备程序的对象,如果是多个对象,会出现问题,例如资源浪费、程序的行为异常或者不一致的情况。
2、单例模式三种方式
1)加锁
MethodSynSingleton.class
public class MethodSynSingleton {
private static MethodSynSingleton instance = null;
private MethodSynSingleton(){
}
public synchronized MethodSynSingleton getInstance(){
if (null == instance){
instance = new MethodSynSingleton();
}
return instance;
}
}
缺点:使用方法锁会大大的降低处理效率
2)饱汉式Singleton.java
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){
}
public synchronized Singleton getInstance(){
return instance;
}
}
3)饿汉式单例
public class SingletonDouble {
private static SingletonDouble instance = null;
private SingletonDouble(){
}
public SingletonDouble getInstance(){
if (instance == null){
synchronized (SingletonDouble.class){
if (instance == null){
instance = new SingletonDouble();
}
}
}
return instance;
}
}
二、命令模式
1、定义:”请求”封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象。命令模式也支持可撤销的操作
2、命令对象 通过在特定接受者上绑定一组动作来封装一个请求。要达到这一点,命令对象将动作和接受者包进对象中,这个对象只是暴露execute()方法,当此方法被调用时,接受者就会进行这些动作
3、应用
1)队列请求
2)日志请求
3)事务系统
4、特点
1)命令模式将发出的请求的对象和执行请求的对象解耦
2)在被解耦的俩者之间是通过命令对象封装了接受者和一个或多个动作
3)调用者通过调用命令对象的execute()发出请求,这会使得接受者的动作被调用
4)调用者可以接受命令当做参数,甚至在运行时动态的进行
5)命令可以支持撤销,做法是实现一个undo()方法来回到execute()被执行前的状态
6)宏命令是命令模式的一种简单点的延伸,允许调用多个命令。宏方法也可以支持撤销
7)实际操作时,很常见使用“聪明”命令对象,也就是之间实现了请求,可不是将工作委托给接受者
8)命令也可以用来实现日志和事务系统
5、代码实例
统一接口:Command.java、NoCommand.java
只有一个方法:execute()方法
电灯基础类:Light.java
电灯开的实现类:LightOnCommand.java
电灯关的实现类:LightOffCommand.java
public class LightOffCommand implements Command {
Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
远程控制方法,用于初始化命令、设置槽位、按下开、关
public class RemoteControl {
Command[] onCommands;
Command[] offCommands;
public RemoteControl() {
onCommands = new Command[7];
offCommands = new Command[7];
Command noCommand = new NoCommand();
for (int i = 0; i < 7; i++) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
}
public void setCommand(int slot, Command onConmmand, Command offCommand) {
onCommands[slot] = onConmmand;
offCommands[slot] = offCommand;
}
public void onButterWasPushed(int slot) {
if (onCommands[slot] != null) {
onCommands[slot].execute();
}
}
public void offButterWasPushed(int slot) {
if (onCommands[slot] != null) {
offCommands[slot].execute();
}
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
System.out.println("\n----------- Remote Control ----\n");
for (int i = 0; i < onCommands.length; i++) {
buffer.append(" [slot" + i + "] " + onCommands[i].getClass().getName() + " " + offCommands[i].getClass()
.getName() + "\n");
}
return buffer.toString();
}
}
测试类:RemoteControl
public class RemoteLoader {
public static void main(String[] args) {
RemoteControl control = new RemoteControl();
Light light = new Light("卧室的电灯");
Command lightOn = new LightOnCommand(light);
Command lightOff = new LightOffCommand(light);
control.setCommand(0,lightOn,lightOff);
System.out.println(control);
control.onButterWasPushed(0);
control.offButterWasPushed(0);
}
}