参考:http://blog.csdn.net/fatherican/article/details/44966891
依赖关系(Dependence)
依赖关系(Dependence):假设A类的变化引起了B类的变化,则说名B类依赖于A类。
在UML中,依赖关系用带箭头的虚线表示,由依赖的一方指向被依赖的一方。
public class Driver
{
public void drive(Car car)
{
car.move();
}
……
}
public class Car
{
public void move()
{
......
}
……
}
依赖关系有如下三种情况:
1、A类是B类中的(某中方法的)局部变量;
2、A类是B类方法当中的一个参数;
3、A类向B类发送消息,从而影响B类发生变化;
-------------------------------------------------------------------------------------------------------------------
oo原则:
封装变化
多用组合,少用继承
针对接口编程,不针对实现编程
为交互对象之间松耦合设计而努力
类应该对扩展开放,对修改关闭
依赖抽象,不要依赖具体类
------------------------------------------------------------------------------------------------------
命令模式:
发出请求的对象 和 执行请求的对象 解耦。
两者之间通过命令对象进行沟通。
命令可以撤销,方法是:实现接口的undo()方法
宏命令是命令的一种简单延伸,允许调用多个命令。
命令模式的用途:队列请求,实现日志和事物系统。
伪代码:
//执行者
public class Light{
public void on()
{
//打开...
}
public void off()
{
//关闭....
}
}
//接口
public interface Command
{
public void execute();
public void undo();
}
//命令对象
public class LightOnCommand implements Command
{
Light light;
public LightOnCommand(Light light)
{
this.light = light;
}
public void execute()
{
light.on();
}
public void undo()
{
light.off();
}
}
//需要判断命令是否加载了
public void onButtonWasPushed(int slot)
{
if(OnCommands[slot] != null)
{
OnCommands[slot].execute();
}
}
//实现一个不做任何事情的命令。避免每次判断是否加载了命名
public class NoCommand implements Command
{
public void execute()
{
}
public void undo()
{
}
}
NoCommand对象是一个空对象(null object)的例子。当你不想返回一个有意义的对象时,空对象
就很有用。在许多设计模式中,都会看到空对象的使用。甚至有些时候,空对象本身也被视为是一种
设计模式。
//批量命令执行
public class MacroCommand implements Command
{
Command[] commands;
public MacroCommand(Command[] commands)
{
this.commands = commands;
}
public void execute()
{
for(int i=0;i<commands.length;i++)
{
commands[i].execute();
}
}
public void undo()
{
for(int i=0;i<commands.length;i++)
{
commands[i].undo();
}
}
}
//调用者
public class RemoteCtrl{
Command[] OnCommands;
Command[] OffCommands;
Command undoCommand;//撤销
public RemoteCtrl()
{
OnCommands = new Command[7];
OffCommands = new Command[7];
Command noCommand = new Command();
for(int i=0;i<7;i++)
{
OffCommands[i] = noCommand;
OnCommands[i] = noCommand;
}
undoCommand = noCommand;
}
public void setCommand(int slot, Command onCommand, Command offCommand)
{
OnCommands[slot] = onCommand;
OffCommands[slot] = offCommand;
}
public void onButtonWasPushed(int slot)
{
OnCommands[slot].execute();
undoCommand = OnCommands[slot];
}
public void offButtonWasPushed(int slot)
{
OffCommands[slot].execute();
undoCommand = OffCommands[slot];
}
public void undoButtonWasPushed(int slot)
{
undoCommand.undo();
}
}
--------------------------------------------------------------------
//初始化设置
public class RemoteLoader
{
public static void main(String[] args)
{
//调用者
RemoteCtrl remoteCtrl = new RemoteCtrl();
//执行者
Light light = new Light("Bedroom");
Tv tv = new Tv("Living room");
Stereo stereo = new Stereo("Living room");
HotTub hutTub = new HotTub("Hot tub");
//命令对象
OnCommandLigth lightOn = new OnCommandLigth(light);
OnCommandTv tvOn = new OnCommandTv(tv);
OnCommandStereo stereoOn = new OnCommandStereo(stereo);
OnCommandHotTub hotTubOn = new OnCommandHotTub(hutTub);
//命令对象
OffCommandLigth lightOff = new OffCommandLigth(light);
OffCommandTv tvOff = new OffCommandTv(tv);
OffCommandStereo stereoOff = new OffCommandStereo(stereo);
OffCommandHotTub hotTubOff = new OffCommandHotTub(hutTub);
//批量命令
Command[] partyOn = {lightOn, tvOn, stereoOn, hotTubOn};
Command[] partyOff = {lightOff, tvOff, stereoOff, hotTubOff};
//命令对象
MacroCommand onMacroCommand = new MacroCommand(partyOn);
MacroCommand offMacroCommand = new MacroCommand(partyOff);
remoteCtrl.setCommand(0, onMacroCommand, offMacroCommand);
remoteCtrl.setCommand(1, lightOn, lightOff);
remoteCtrl.setCommand(2, tvOn, tvOff);
remoteCtrl.setCommand(3, stereoOn, stereoOff);
remoteCtrl.setCommand(4, hotTubOff, hotTubOff);
//测试
remoteCtrl.onButtonWasPushed(1);//打开电灯
remoteCtrl.offButtonWasPushed(1);//关闭电灯
remoteCtrl.undoButtonWasPushed(1);//撤销操作,执行打开电灯
remoteCtrl.onButtonWasPushed(2);//打开电视
remoteCtrl.offButtonWasPushed(2);//关闭电视
}
}
//使用状态实现撤销
通常实现撤销的功能,需要记录一些状态。比方说吊扇,吊扇允许有多种转速,当然也允许被关闭。
public class CeilingFan{
public static final int HIGH = 3;
public static final int MEDIUM = 2;
public static final int LOW = 1;
public static final int OFF = 0;
String location;
int speed;
public CeilingFan(String location)
{
this.location = location;
speed = OFF;
}
public void high()
{
speed = HIGH;
//设置高转速
}
public void medium()
{
speed = MEDIUM;
//...
}
public void low()
{
speed = LOW;
//...
}
public void off()
{
speed = OFF;
//...
}
//风扇当前的档位
public int getSpeed()
{
return speed;
}
}
public class CeilingFanHighCommand implements Command{
CeilingFan ceilingFan;
int preSpeed;
public CeilingFanHighCommand(CeilingFan ceilingFan)
{
this.ceilingFan = ceilingFan;
}
public void execute()
{
preSpeed = ceilingFan.getSpeed();
ceilingFan.high();
}
public void undo()
{
if(preSpeed == CeilingFan.HIGH)
{
ceilingFan.high();
}
else if(preSpeed == CeilingFan.MEDIUM)
{
ceilingFan.medium();
}
else if(preSpeed == CeilingFan.LOW)
{
ceilingFan.low();
}
else if(preSpeed == CeilingFan.OFF)
{
ceilingFan.off();
}
}
}
-------------------------------------
后记:
实际操作时,很常见使用“聪明”命令对象,也就是直接实现了
请求,而不是将工作委托给接收者。
实现多层撤销:不要只是记录最后一个被执行的命令,而使用一个堆栈记录操作
过程的每一个命令。然后,不管什么时候按下了撤销按键,都可以从堆栈中取出最上层的
命令,然后调用它的undo方法。