popcorny的碎碎唸
http://popcornylu.blogspot.co.uk/
易飞扬的博客
http://www.yifeiyang.net/
Learn iPhone App Development with FourTen
http://learn-iphone-app-development.com/
什么是命令模式:
将请求(命令)封装为对象,实现将“发出请求的对象”与“接收和执行这些请求的对象”分隔开来
命令模式中有几个关键的概念:
客户:发起请求的对象,开关,或者你(因为开关是由你来控制的)
命令:具体的一个命令,比如开灯命令,关灯命令
执行者:接收和执行请求的对象,比如电灯,是开灯关灯命令的接收者和执行者
调用者:通过这个对象来实现客户(开关或你)和执行者(电灯)之间的耦合
命令模式支持撤销。对于这个demo来说,开灯这个命令对应的撤销就是关灯。同理:关灯命令对应的撤销就是开灯。
LightOnCommand.java文件可以看到这一点,我通过一个List维护着用户的开灯和关灯的命令,当用户需要撤销的时候,从取出这个List的最后一个Command,执行它的undo()就实现了撤销。当然实现后你还要记得remove它,才能实现撤销到更早的Command。
这里我用一个ImageView当做灯泡。通过切换不同的图片,来实现on和off.
假如现在我要使用命令模式做一个类似按钮打开和关闭电灯的引用。实现效果如下图:
下面是工程结构:
我将开灯和关灯这两个命令封装成对象,它们都实现了Command接口,RemoteInvoker就是调用者。
下面上代码:
Command.java:
/** * 这是第一步,让所有的命令对象实现相同的包含一个方法的接口 * * */ public interface Command { public void execute(); public void undo(); }
实现这个接口:
LightOnCommand.java:(LightOffCommand.java是类似的,只不过图片是相反的,这里就不贴代码了)
public class LightOnCommand implements Command{ private ImageView light; public LightOnCommand(ImageView light){ this.light = light; } @Override public void execute() { light.setBackgroundResource(R.drawable.light_on); } @Override public void undo() { light.setBackgroundResource(R.drawable.light_off); } @Override public String toString() { return "On Command"; } }
RemoteInvoker.java:
/** * 这个就是遥控器类,这个类在这里还负责撤销操作 * * */ public class RemoteInvoker { Command slot; Command onCommand; Command offCommand; LinkedList<Command> commandList; Context context; public RemoteInvoker(Context context) { this.context = context; commandList = new LinkedList<Command>(); } public void setCommand(Command onCommand, Command offCommand){ this.onCommand = onCommand; this.offCommand = offCommand; } public void onButtonWasPressed(){ onCommand.execute(); commandList.add(onCommand); } public void offButtonWasPressed(){ offCommand.execute(); commandList.add(offCommand); } public void undoButtonWasPressed(){ for(Command c: commandList){ Log.e("**********:", ":"+c.toString()); } int sizeOfCommands = commandList.size(); if(sizeOfCommands <= 0){ Toast.makeText(context, "当前已经没有要撤销的对象了", Toast.LENGTH_SHORT).show(); }else{ Command lastCommand = commandList.get(sizeOfCommands - 1);//获取最后一个命令对象,执行它的undo方法 lastCommand.undo(); commandList.removeLast();//删除最后一个命令 } } }
最后是调用者类
MainActivity.java:
public class MainActivity extends Activity { private RemoteInvoker remoteInvoker; private LightOnCommand lightOnCommand; private LightOffCommand lightOffCommand; private ImageView light; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); light = (ImageView)findViewById(R.id.iv_light);//灯泡 Button btnOn = (Button)findViewById(R.id.btn_light_on);//开 Button btnOff = (Button)findViewById(R.id.btn_light_off);//关 Button btnUndo = (Button)findViewById(R.id.btn_undo);//撤销 //步骤1 lightOnCommand = new LightOnCommand(light);//实例化命令 lightOffCommand = new LightOffCommand(light); //步骤2 remoteInvoker = new RemoteInvoker(this); remoteInvoker.setCommand(lightOnCommand, lightOffCommand);//设置命令 btnOn.setOnClickListener(clickListener); btnOff.setOnClickListener(clickListener); btnUndo.setOnClickListener(clickListener); } private View.OnClickListener clickListener = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_light_on://开灯 remoteInvoker.onButtonWasPressed(); break; case R.id.btn_light_off://关灯 remoteInvoker.offButtonWasPressed(); break; case R.id.btn_undo://撤销 remoteInvoker.undoButtonWasPressed(); break; default: break; } } }; }
这样做之后,你就当你要开灯或关灯的时候,就不需要直接对电灯的实例进行操作了,而是通过RemoteInvoker对象,你只要告诉这个对象,你按下了哪个按钮,其它的事情交个这个对象去处理。那么你和电灯之间就解耦了。
还有一点好处是,你可以实现命令的撤销。
当然,命令模式还支持批量执行命令,以及批量撤销命令。比如我只要按下一个按钮,那么多个命令(打开电灯,打开空调,打开电视就都开始执行),当我按关闭按钮,那么就撤销前面所有的命令。
还有队列请求和日志请求的功能,这些等到下次再结合实例讲解演示。
主要实现了调用者 和真正的动作实现者之间的解耦 也就是说中间会有一个过渡者 这个过渡者会和这两者进行交互
主要实现了调用者 和真正的动作实现者之间的解耦 也就是说中间会有一个过渡者 这个过渡者会和这两者进行交互
嗯,说的很好啊,这个过渡者就是RemoteInvoker。一对比,觉得自己语言能力还有待加强。谢谢指教。
http://blog.csdn.net/chenzheng_java/article/details/6258456
http://blog.csdn.net/wolfman79/article/details/7868975
http://blog.csdn.net/zrzlj/article/details/8050633
总结一下,如果是VideoView要MP4处理成progressive streamable模式的,或者支持rtsp才可播放。。。大概应该这样的