命令与策略之争

一 概要说明

命令模式

意图(Intent):
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;
对请求排队或记录请求日志,以及支持可撤消的操作。
个人观点:把函数用一个对象封装起来,使其可被别人拿走,想什么时候用就上面时候用。

策略模式

意图:
定义一系统的算法,把它们一个个封装起来,并且使它们可相互替换。
本模式使得算法可独立于使用它的客户而变化。
个人观点:把函数用一个对象封装起来,可以通过换这个封装的不同状态换算法。

总结

通过上面的定义可以看出来吧,他俩的共性都是把,函数变成了对象。
一个侧重点在时间维度上,一个侧重可多态的换算法。
我的理解:就是把函数封装成对象的目的不同。做法一样,目的不同。

下面我用坦克大战颜色一下他们的作用之争。

目录:《一个实例讲完23种设计模式》

当前:抽象工厂

需求:坦克大战

创建两种坦克

坦克类型 射程 速度
b70 70米 时/70公里
b50 50米 时/70公里

二 第一战

命令模式代码

import java.util.ArrayList;
class Function{
	final static String mShot = "射击:";
	static void shot70() {
		System.out.println(mShot+"70");
	}
	static void shot50() {
		System.out.println(mShot+"50");
	}
}
interface ICommand{
	void execute();
}
interface Itank{
	void exe();
}
class B70Command implements ICommand{
	public void execute() {
		Function.shot70();
	}
}
class B50Command implements ICommand{
	public void execute() {
		Function.shot50();
	}
}
abstract class Tank implements Itank{
	ICommand mCommand; 
	public void exe() {
		mCommand.execute();
	}
}
class B70Tank extends Tank{
	public B70Tank() {
		mCommand = new B70Command();
	}
}
class B50Tank extends Tank{
	public B50Tank() {
		mCommand = new B70Command();
	}
}

public class Client {
	public static void main(String[] args) {
		System.out.println("hello world !");
		B70Tank b70 = new B70Tank();
		b70.exe();
	}
}

运行结果

策略模式

代码

import java.util.ArrayList;
class Function{
	final static String mShot = "射击:";
	static void shot70() {
		System.out.println(mShot+"70");
	}
	static void shot50() {
		System.out.println(mShot+"50");
	}
}
// interface
interface IStrategy{
	void execute();
}
interface Itank{
	void exe();
}
// abstract
abstract class Tank implements Itank{
	IStrategy mStrategy; 
	public void exe() {
		mStrategy.execute();
	}
}
// Concrete 具体
class B70Strategy implements IStrategy{
	public void execute() {
		Function.shot70();
	}
}
class B50Strategy implements IStrategy{
	public void execute() {
		Function.shot50();
	}
}
class B70Tank extends Tank{
	public B70Tank() {
		mStrategy = new B70Strategy();
	}
}
class B50Tank extends Tank{
	public B50Tank() {
		mStrategy = new B50Strategy();
	}
}
// Client
public class Client {
	public static void main(String[] args) {
		System.out.println("hello world !");
		B70Tank b70 = new B70Tank();
		b70.exe();
	}
}

评判结果:完全看不出差别。

看来是我的实力有问题,开始第二回合吧

二 第二战(用多线程,看看怎么样这应该是命令模式的优势项目

命令模式代码

import java.util.ArrayList;
class Function{
	final static String mShot = "射击:";
	static void shot70() {
		System.out.println(mShot+"70");
	}
	static void shot50() {
		System.out.println(mShot+"50");
	}
}
interface ICommand{
	void execute();
}
interface Itank{
	void exe();
}
class B70Command implements ICommand{
	public void execute() {
		Function.shot70();
	}
}
class B50Command implements ICommand{
	public void execute() {
		Function.shot50();
	}
}
abstract class Tank implements Itank{
	ICommand mCommand; 
	ArrayList<ICommand> mList = new ArrayList<ICommand>();
	public ArrayList<ICommand> getmList() {
		return mList;
	}
	public void exe() {
		//mCommand.execute();
		mList.add(mCommand);
	}
}
class B70Tank extends Tank{
	public B70Tank() {
		mCommand = new B70Command();
	}
}
class B50Tank extends Tank{
	public B50Tank() {
		mCommand = new B70Command();
	}
}
class MyThread extends Thread{
	ArrayList<ICommand> mList;
	public MyThread(ArrayList<ICommand> list) {
		mList = list;
	}
	public void run() {
		System.out.println("MyThread run");
		while(true) {
			for(ICommand com:mList) {
				com.execute();
				mList.remove(com);
				break;
			}
		}
	}
}

public class Client {
	public static void main(String[] args) {
		System.out.println("hello world !");
		B70Tank b70 = new B70Tank();
		MyThread t = new MyThread(b70.getmList());
		t.start();
		b70.exe();
		try {
			t.sleep(500);
		}catch(Exception e) {
			
		}
		t.stop();
	}
}

运行结果

策略模式代码

import java.util.ArrayList;
class Function{
	final static String mShot = "射击:";
	static void shot70() {
		System.out.println(mShot+"70");
	}
	static void shot50() {
		System.out.println(mShot+"50");
	}
}
interface IStrategy{
	void execute();
}
interface Itank{
	void exe();
}
class B70Strategy implements IStrategy{
	public void execute() {
		Function.shot70();
	}
}
class B50Strategy implements IStrategy{
	public void execute() {
		Function.shot50();
	}
}
abstract class Tank implements Itank{
	IStrategy mStrategy; 
	ArrayList<IStrategy> mList = new ArrayList<IStrategy>();
	public ArrayList<IStrategy> getmList() {
		return mList;
	}
	public void exe() {
		//mCommand.execute();
		mList.add(mStrategy);
	}
}
class B70Tank extends Tank{
	public B70Tank() {
		mStrategy = new B70Strategy();
	}
}
class B50Tank extends Tank{
	public B50Tank() {
		mStrategy = new B50Strategy();
	}
}
class MyThread extends Thread{
	ArrayList<IStrategy> mList;
	public MyThread(ArrayList<IStrategy> list) {
		mList = list;
	}
	public void run() {
		System.out.println("MyThread run");
		while(true) {
			for(IStrategy com:mList) {
				com.execute();
				mList.remove(com);
				break;
			}
		}
	}
}

public class Client {
	public static void main(String[] args) {
		System.out.println("hello world !");
		B70Tank b70 = new B70Tank();
		MyThread t = new MyThread(b70.getmList());
		t.start();
		b70.exe();
		try {
			t.sleep(500);
		}catch(Exception e) {
			
		}
		t.stop();
	}
}

运行结果

第二战 评判结果

又没分除胜负,为什么呢?

因为在坦克看来,无论桥接的是命令还是策略。都是一样的。

而他们俩的真正差别在于命令和策略的来源。

在坦克看来,都是策略。

差别在于,命令模式,是把一个Service类变成了策略。

这才是他们真正的差别。

不争了,命令本事就是一种特殊的策略。

命令是把一个Service的接口,适配成了策略。

策略是啥,是一个函数的多态。

命令呢也是,只不过他是吧本来不是的一些接口,变了策略的方式提供给了调用端。

命令就是一种特殊的策略。

命令=策略+适配器

猜你喜欢

转载自blog.csdn.net/xie__jin__cheng/article/details/88863162