策略模式
示例
飞机大战项目中UML类图
关键代码
具体策略
/**
* 直射策略
*/
public class Collineation implements Strategy{
@Override
public List<AbstractBaseBullet> shoot(AbstractAircraft abstractAircraft) {
List<AbstractBaseBullet> res = new LinkedList<>();
int direction = abstractAircraft.getDirection();
int power = abstractAircraft.getPower();
int x = abstractAircraft.getLocationX();
int y = abstractAircraft.getLocationY() + direction*2;
int speedX = 0;
int speedY = abstractAircraft.getSpeedY() + direction*5;
AbstractBaseBullet baseBullet;
if(abstractAircraft instanceof HeroAircraft) {
res.add(new HeroBullet(x, y, speedX, speedY, power));
return res;
}
res.add(new EnemyBullet( x , y, speedX, speedY, power));
return res;
}
}
/**
* 散射策略
*/
public class Scattering implements Strategy{
public List<AbstractBaseBullet> shoot(AbstractAircraft abstractAircraft) {
List<AbstractBaseBullet> res = new LinkedList<>();
int power = abstractAircraft.getPower();
int direction = abstractAircraft.getDirection();
int shootNum = abstractAircraft.getShootNum();
int x = abstractAircraft.getLocationX();
int y = abstractAircraft.getLocationY() + direction*2;
int speedX = 0;
int speedY = abstractAircraft.getSpeedY() + direction*5;
AbstractBaseBullet baseBullet;
if(abstractAircraft instanceof HeroAircraft) {
for (int i = 0; i < shootNum; i++) {
// 子弹发射位置相对飞机位置向前偏移
// 多个子弹横向分散
baseBullet = new HeroBullet(x + (i * 2 - shootNum + 1) * 10, y, speedX+(i * 2 * shootNum / (shootNum - 1) -shootNum) * 1, speedY, power);
res.add(baseBullet);
}
return res;
}
for (int i = 0; i < shootNum; i++) {
// 子弹发射位置相对飞机位置向前偏移
// 多个子弹横向分散
baseBullet = new EnemyBullet(x + (i * 2 - shootNum + 1) * 10, y, speedX+(i * 2 * shootNum / (shootNum - 1) -shootNum) * 1, speedY, power);
res.add(baseBullet);
}
return res;
}
}
传参时为了代码简洁与维护,同时更符合开闭原则,选择将整个飞机对象作为形参。
Context(本例即AbstractAircraft)中使用策略
AbstractAircraft作为抽象父类定义shoot()抽象方法,由其一般子类具体实现:
public class HeroAircraft extends AbstractAircraft {
protected Strategy shootMode;
/**
* 设置射击模式
* @param strategy
*/
public void setShootMode(Strategy strategy){
this.shootMode = strategy;
}
/**
* 实现射击
* @param strategy
*/
public List<AbstractBaseBullet> shoot() {
return this.shootMode.shoot(this);
}
}
}
总结
本例中,AbstractAircraft、HeroAircraft等对象中的shoot()负责扣动扳机,具体子弹是如何射出去的由具体实例中的shootMode成员决定。