这一篇主要是对上一篇的内容进行了一下优化。
当初只是想,体现策略模式和职责链的结合,后来把桥接,命令和观察者也加了进去,且代码更简单清晰了。所以有了这篇文章。没完全替换上一篇的意图是,体现模式的一个优化过程,且但理解策略和职责链看上一篇更容易些。
与上一篇相比,这篇明显消除“射击”和“跑”在不同的坦克型号中的冗余。
但是该篇也还有没有处理的冗余:创建多个坦克的时候继承机能还是重复的,因为都是那两句话,所以“射击”和“跑”分别用一个实例就够了,该实现明显是多了
需求:坦克大战
创建两种坦克
坦克类型 | 射程 | 速度 |
b70 | 70米 | 时/70公里 |
b50 | 50米 | 时/70公里 |
简单说明一下:
用坦克大战的需求,实现了如下5种模式(关于坦克大战我再多种模式中都用过,目的:希望需求对模式理解的消耗尽量小)
- 策略
- 职责链
- 观察者
- 命令模式
- 桥接模式
类图
简单说明:
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();
}
}
运行结果