概述
一般的,当我们需要实现某个可能存在「未完待续」,也就是更多的「模型」之时,一定会导致我们的代码造成极大的耦合。如,我们在玩「植物大战僵尸」的游戏。一般最基础的僵尸如下图所示。
我们可以得知,僵尸具备四中行为,即:外观、移动方式、攻击方式。很显然,如果我们需要设计这样一个模型,按照昨天学习的模板方法模式的理解,我们可以直接创建一个「僵尸抽象类」,将三种方式以抽象方法的形式实现,不过我们可以以「普通僵尸」提供一个默认的实现,这样以增加复用性。
那么,如果我们现在需要添加一个「大头僵尸」,就是直接继承与「僵尸抽象类」然后直接实现「攻击方式」,将其实现成「头撞」就好了。
那么问题来了,如果未来的某一天被提出增加一个「大大头僵尸」,它的技能也是「头撞」呢?好,你可以直接继承于「大头僵尸」,然后再重写它的独特实现即可。
那么... 如果又有一个基于「大大头僵尸」僵尸的呢... 好吧,继续继承.. 这样的代码结构,相信你已经看出来了,当业务日渐增多,整个结构极其复杂,不管是对自己还是对别人,都是极其恶心的。
所以,我们就需要对其进行抽离,如何解决?这便是「策略模式」的应用场景。
整体
首先明确我们的任务,我们要将做到「抽离存在变化的状态的事物」。即,将上述的「外观、移动方式、攻击方式」三种状态抽离出来。
interface Attack{
void attack();
}
interface Move{
void move();
}
interface Display{
void display();
}
当我们需要某种形式的状态时,去实现对应的接口。
class Bump implements Attack{
@Override
public void attack() {
System.out.println("用头撞击的对方");
}
}
然后我们去设计「僵尸类」。我们创建了两个构造方法,其中的无参数方法我们可以在其中编写默认的实现,即如果不自定义实现方式就使用默认的。
因此,当想要「增加新的僵尸」的时候,如果它的攻击形式、显示形式、移动形式之前已经实现了,我们就不需要再次实现
class Zombie {
private Attack attackable;
private Move moveable;
private Display displayable;
public Zombie() {
/**
* 如果调用无参数构造方法,则提供默认实现。
*/
}
public Zombie(Attack attackable, Move moveable, Display display) {
this.attackable = attackable;
this.moveable = moveable;
this.displayable = display;
}
public void attack() {
attackable.attack();
}
public void move() {
moveable.move();
}
public void dispaly() {
displayable.display();
}
}
当然,这个代码还有一定的优化空间,便不再撰述。
本页的评论功能已关闭