参考: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方法。









  

 

 

posted on 2018-01-18 15:47  邶风  阅读(282)  评论(0编辑  收藏  举报