说起设计模式,个人觉得他是建立在面向对象设计原则之上的。但是我们懂得面向对象设计原则却并不能立刻变成一个好的设计者。需要再不断的实践中进行总结才行。所以想要更好的掌握设计模式,首先我们需要熟练掌握:继承、封装、抽象和多态。
首先我们引入一个场景,然后分别使用普通的实现和设计模式实现。
现在我们准备攻打米国,我们有很多的战士(soldier) ,比如说陆战军、炮兵、狙击手等等
有一个战士的超类,里面有一个消灭敌人的方法:
public abstract class Soldier {
public abstract void destroy();
}
现在有装甲兵:
public class Troops extends Soldier {
public void destroy() {
System.out.println("我是装甲兵,盘他。。。");
};
}
现在有炮兵:
public class Artillerymen extends Soldier {
public void destroy() {
System.out.println("我是炮兵,盘他。。。");
};
}
当然还有总司令:
public class Commander extends Soldier {
public void destroy() {
System.out.println("我是总司令,盘他。。。");
};
}
米国太不行,一打就撤退了,我们要乘胜追击,这个时候这些步兵就要开我们的装甲车飙车啦。好了,常规的做法应该是在超类中加一个开车的方法。但是这样会有问题:
- 海军这个时候就懵逼了,我靠我怎么在水里飙车,我全靠浪的
- 总司令不能去,得守着大本营,这个时候我不需要飙车方法
- 车子毁了,我想换成坐船怎么办?
好了,这个时候我们设计模式中的策略模式终于上场了。一代军神开始运筹帷幄。。。
首先给出定义:
- 个人理解版本:
策略模式:将系统中经常需要变化的东西(追击米国的方式)抠出来封装起来,让他们可以相互替换使用。(个人理解主要使用的是多态)- 官方版本:
策略模式:定义算法族,分别封装起来,让他们之间可以相互替换,此模式让算法(追击米国的方式)的变化独立于使用算法的客户(士兵)
使用方法:
需要一个抽象类(战士)、一个接口(追击的方式)和接口的实现(追击方式实现)
战士的超类,其中包含追击的方式接口:
public abstract class Soldier {
public AttackBehavior attackBehavior;
public Soldier(){};
public void setAttackBehavior(AttackBehavior attackBehavior) {
this.attackBehavior = attackBehavior;
}
/**
* 追击的方法
*/
public void attack(){
attackBehavior.attack();
}
public abstract void destroy();
}
追击的方式接口以及实现类:
/**
* 追击方式接口
*/
public interface AttackBehavior {
public void attack();
}
/**
* 开车追击方式
*/
public class DriveCarAttack implements AttackBehavior {
@Override
public void attack() {
System.out.println("开车追击");
}
}
/**
* 开船追击方式
*/
public class DriverShipAttack implements AttackBehavior {
@Override
public void attack() {
System.out.println("开船追击");
}
}
/**
* 开坦克击方式
*/
public class DriverTankAttack implements AttackBehavior{
@Override
public void attack() {
System.out.println("开坦克追击");
}
}
兵种
/**
* 装甲兵
*/
public class Troops extends Soldier {
public Troops(){
attackBehavior = new DriverTankAttack();//装甲兵使用开坦克的方式实现类 (多态+继承知识点)
}
public void destroy() {
System.out.println("我是装甲兵,盘他。。。");
};
}
/**
* 海军
*/
public class Navy extends Soldier {
public Navy(){
attackBehavior = new DriverShipAttack();
}
public void destroy() {
System.out.println("我是海军,盘他。。。");
};
}
测试类:
public class StrategyTest {
public static void main(String[] args) {
Commander commander = new Commander();
commander.destroy();//总司令发号施令
//装甲兵共计并且追击
Troops troops = new Troops();
troops.destroy();
troops.attack();
System.out.println("坦克坏了,想要乘船去");
troops.setAttackBehavior(new DriverShipAttack());//中途可以更换交通工具
troops.attack();
//海军追击
Navy navy = new Navy();
navy.attack();
}
}
测试结果:
好了,上面就是策略模式的整体实现,例子举得可能不恰当,不喜勿喷哈。
总结一下策略模式:
- 将变化的部分(追击的方式)单独抠出来进行封装。---算法族
- 抽象类中加入方式的接口类 。 ---运用了多态 让算法之间可以相互替换
当然这种模式也有缺点,就是如果变化的部分太多,可能会导致类特别多
如果有说的不对的地方,欢迎留言指正,多谢 !!!