策略模式和职责链模式实现坦克大战2

上一篇《策略模式和职责链模式实现坦克大战》

这一篇主要是对上一篇的内容进行了一下优化。

当初只是想,体现策略模式和职责链的结合,后来把桥接,命令和观察者也加了进去,且代码更简单清晰了。所以有了这篇文章。没完全替换上一篇的意图是,体现模式的一个优化过程,且但理解策略和职责链看上一篇更容易些。

与上一篇相比,这篇明显消除“射击”和“跑”在不同的坦克型号中的冗余。

但是该篇也还有没有处理的冗余:创建多个坦克的时候继承机能还是重复的,因为都是那两句话,所以“射击”和“跑”分别用一个实例就够了,该实现明显是多了

需求:坦克大战

创建两种坦克

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

简单说明一下

用坦克大战的需求,实现了如下5种模式(关于坦克大战我再多种模式中都用过,目的:希望需求对模式理解的消耗尽量小)

  1. 策略
  2. 职责链
  3. 观察者
  4. 命令模式
  5. 桥接模式

类图

策略模式和职责链模式实现坦克大战2_第1张图片

简单说明

1.策略模式
这里的策略是“IStrategy”接口。
他的价值是为Client类提供创建不同坦克的策略(创建“B500坦克”或者“B70坦克”)
2.职责链模式
这里的职责链是“IHandler”接口。
他的价值是,为“IStrategy”接口提供创建坦克的一个链条。
即:“IStrategy”只需告诉“HandlerSort”开始创建坦克,“HandlerSort”就把创建的命令依次传递下去,直到创建完成。
虽然,这里只有两个对象的传递,但中间无论中间经历多少个对象,都是一样的,最终一步步的传递,一步步的创建,最终把坦克创建完。
3.命令模式
这里的命令是“IFun”接口。
他的价值是,将exe命令封装成对象,等到坦克运行的时候在运行。
如果你要对标准类图的话
Command(命令) = IFun
invoker(调用) = Tank
Receiver(接收器) = Function(这是我定义的一个机能类,类图里没体现,但是代码中有)
4.桥接模式
ConcreteFun和ISpecificationOfTank之间的桥接
机能(发射和跑)和机能规格(B50和B70坦克)之间的桥接
5.观察者
这里的观察者是“Strategy”
策略者(Strategy)让IHandler创建坦克后,要等待IHandler创建完了的通知。
Observer(观察者) = Strategy
Subject(目标对象) = IHandler
那么观察者观察的是啥呢:就是坦克是否创建完成。
创建完成后,IHandler(目标对象)把创建完成的消息高速Strategy(观察者),Strategy自动通知客户端运行坦克。

代码

class Function{
	public String mStr;
	Function(String str){
		mStr = str;
		exe();
	}
	public void exe() {
		System.out.println(mStr);
	}
};
// Strategy Pattern
interface IFun{
	void exe();
}

interface IHandler{
	void create(Tank t);
}
interface IStrategy{
	//algorithm
	void create();
	void update(Tank t);
}
interface ISpecificationOfTank{
	int getSpecification();
}

//Concrete
abstract class ConcreteFun implements IFun{
	public ConcreteFun(ISpecificationOfTank s) {
		mSpecificationOfTank = s;
	}
	protected ISpecificationOfTank mSpecificationOfTank;
}
class ConcreteSpecification implements ISpecificationOfTank{
	int mSpecification;
	public ConcreteSpecification(int value) {
		mSpecification = value;
	}
	public int getSpecification() {
		return mSpecification;
	}
}
class Shot extends ConcreteFun{
	public Shot(ISpecificationOfTank s) {
		super(s);
	}
	public void exe() {
		Function f = new Function("发射距离"+mSpecificationOfTank.getSpecification()+"米");
	}
}
class Run extends ConcreteFun{
	public Run(ISpecificationOfTank s) {
		super(s);
	}
	public void exe() {
		Function f = new Function("速度"+mSpecificationOfTank.getSpecification()+"公里");
	}
}
class Tank{
	Shot mShot;
	Run mRun;
	public void exe() {
		mShot.exe();
		mRun.exe();
	}
}

abstract class Handler implements IHandler{
	protected ISpecificationOfTank mSpecificationOfTank;
	public Handler(ISpecificationOfTank s) {
		mSpecificationOfTank = s;
	}
}

class HandlerRun extends Handler{
	IStrategy mStrategy;
	public HandlerRun(IStrategy stragegy,ISpecificationOfTank s) {
		super(s);
		mStrategy = stragegy;
	}
	public void create(Tank t) {
		t.mRun = new Run(mSpecificationOfTank);
		mStrategy.update(t);
	}
}

class HandlerSort extends Handler{
	HandlerRun mNextHandler;
	public HandlerSort(HandlerRun h,ISpecificationOfTank s){
		super(s);
		mNextHandler = h;
	}
	public void create(Tank t) {
		t.mShot = new Shot(mSpecificationOfTank);
		mNextHandler.create(t);
	}
}

class Strategy implements IStrategy{
	HandlerSort mStartChain;
	ISpecificationOfTank mSpecificationOfTank;
	Client mClient;
	public Strategy(Client c) {
		mClient = c;
	}
	protected void myinit() {
		HandlerRun endChain  = new HandlerRun(this,mSpecificationOfTank);
		mStartChain = new HandlerSort(endChain,mSpecificationOfTank);
	}
	public void create() {
		Tank t = new Tank();
		mStartChain.create(t);
	} 
	public void update(Tank t) {
		mClient.ceateTankFinish(t);
	}
}
class B70Strategy extends Strategy{
	public B70Strategy(Client c) {
		super(c);
		mSpecificationOfTank = new ConcreteSpecification(70);
		myinit();
	}
}

class B50Strategy extends Strategy{
	public B50Strategy(Client c) {
		super(c);
		mSpecificationOfTank = new ConcreteSpecification(70);
		myinit();
	}
}

public class Client {
	public static void main(String[] args) {
		System.out.println("hello worldff !");
		Client c = new Client();
		IStrategy strategy = new B70Strategy(c);
		strategy.create();
	}
	public void ceateTankFinish(Tank t) {
		System.out.println("ceateTankFinish");
		t.exe();
	}
}

 运行结果

下一篇:《策略模式和职责链模式实现坦克大战3-享元模式的加入》

你可能感兴趣的:(spring学习,设计模式-坦克大战-java)