之前看了命令模式,但还是不能自如的运用,后来多看了看多线程,觉得可以用多线程的思想来理解命令模式:
考虑到这样一种场景:某个方法需要完成某一个行为,但是这个行为的具体实现无法确定,必须等到执行该方法时才可以确定。就好像Ruby语言那样,可以传入一个代码块作为参数,但是java 7中目前还不支持代码块作为参数,就是说我们必须把“处理行为”作为参数传入该方法,这个“处理行为”实际上就是一段代码,那么怎样把这段代码传入该方法呢?
例如:假设有个方法需要遍历某个数组的数组元素,但无法确定在遍历数组元素是如何处理这些元素,需要在调用该方法时指定具体的处理行为。
我们在学习多线程时,java是用Runnable接口中定义run方法来封装线程要运行的代码,我们也可以使用一个Command接口来定义一个方法,并用这个方法来封装处理行为。- public interface Command {
- //接口里定义的process方法用于封装“处理行为”
- void process(int[] target);
- }
复制代码- /*
- * 定义一个需要处理数组的类,这个类中包含了一个process方法,
- * 但这个方法无法确定处理数组的处理行为。
- */
- public class ProcessArray {
- public void process(int[] target,Command cmd){
- cmd.process(target);
- }
- }
复制代码- /*
- * 定义一个具备遍历数组行为的类
- */
- public class PrintCommand implements Command{
- public void process(int[] target){
- for(int tmp : target){
- System.out.println("目标数组中的元素:" + tmp);
- }
- }
- }
复制代码- /*
- *定义一个具备给数组中元素求和的类
- */
- public class AddCommand implements Command{
- public void process(int[] target){
- int sum = 0;
- for(int tmp :target){
- sum += tmp;
- }
- System.out.println("数组元素和sum=" + sum);
- }
- }
复制代码- public class CommandTest {
- public static void main(String[] args) {
- ProcessArray pa = new ProcessArray();
- int[] arr = {3,-4,6,4};
- pa.process(arr, new PrintCommand());
- System.out.println("---------------");
- pa.process(arr, new AddCommand());
- }
- }
复制代码 对于PrintCommand 和 AddCommand两个实现类而言,实际有意义的部分就是Process(int[] target)方法,该方法的方法体就是传入ProcessArray类里的process方法的“处理行为”,通过这种方式可以实现process方法和“处理行为的分离”。
如果“处理行为”只运行一次,可以用内部类实现,如下:- public class CommandTest {
- public static void main(String[] args) {
- ProcessArray pa = new ProcessArray();
- int[] arr = {3,-4,6,4};
- //如果代码只执行一次,可以用内部类实现
- pa.process(arr, new Command(){
- public void process(int[] target){
- for(int tmp : target){
- System.out.println("目标数组中的元素:" + tmp);
- }
- }
- });
- System.out.println("---------------");
- pa.process(arr, new Command(){
- public void process(int[] target){
- int sum = 0;
- for(int tmp :target){
- sum += tmp;
- }
- System.out.println("数组元素和sum=" + sum);
- }
- });
- }
- }
复制代码 如果我们忘记了命令模式也没关系,只要记住多线程Runnable接口中的run()方法是封装线程要运行的代码就行了,命令模式也是类似的,这样就简单了。
|