一 概要说明
命令模式
意图(Intent):
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;
对请求排队或记录请求日志,以及支持可撤消的操作。
个人观点:把函数用一个对象封装起来,使其可被别人拿走,想什么时候用就上面时候用。
策略模式
意图:
定义一系统的算法,把它们一个个封装起来,并且使它们可相互替换。
本模式使得算法可独立于使用它的客户而变化。
个人观点:把函数用一个对象封装起来,可以通过换这个封装的不同状态换算法。
总结
通过上面的定义可以看出来吧,他俩的共性都是把,函数变成了对象。
一个侧重点在时间维度上,一个侧重可多态的换算法。
我的理解:就是把函数封装成对象的目的不同。做法一样,目的不同。
下面我用坦克大战颜色一下他们的作用之争。
当前:抽象工厂
需求:坦克大战
创建两种坦克
坦克类型 | 射程 | 速度 |
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的接口,适配成了策略。
策略是啥,是一个函数的多态。
命令呢也是,只不过他是吧本来不是的一些接口,变了策略的方式提供给了调用端。
命令就是一种特殊的策略。
命令=策略+适配器