java 设计模式 策略模式 以英雄联盟为背景

继续java设计模式学习之旅,
策略模式(Strategy Pattern):定义了算法族,分别封装起来,让它们之间可相互替换,此模式让算法的变化独立于使用算法的客户。
可能看完之后还是很迷糊,但是有一个印象,方便阅读下面代码时候的思路理解。(本人是一名android讲师,这个也是很多学员喜欢犯的错误,不愿意看定义理论介绍,这样理解和统一思路就很难了)
话不多说,开始我们的游戏:
游戏设定角色有:Q、W、E、R和两个被动技能。
定义抽象父类Role:

package role;

public abstract class Role {


    public abstract void q();
    public abstract void w();
    public abstract void e();
    public abstract void r();
    public abstract void d();

}

现在有一个角色A,q技能眩晕效果,w技能加速效果,e技能减速效果,r技能击飞效果,d是闪现
角色A代码

package role;

public class RoleA extends Role{

    @Override
    public void q() {
        System.out.println("眩晕效果");

    }

    @Override
    public void w() {
        System.out.println("加速效果");

    }

    @Override
    public void e() {
        System.out.println("减速效果");

    }

    @Override
    public void r() {
        System.out.println("击飞效果");
    }

    @Override
    public void d() {
        System.out.println("闪现效果");

    }

}

我们利用面向对象的思想设计了角色A,这个时候如果添加了新的角色呢?
RoleB:q眩晕、w伤害、e、减速、r击飞、d闪现
RoleC::q眩晕、w伤害、e、护盾、r击飞、d闪现

package role;

public class RoleB extends Role{

    @Override
    public void q() {
        System.out.println("眩晕效果");

    }

    @Override
    public void w() {//和A的不一样
        System.out.println("伤害效果");

    }

    @Override
    public void e() {
        System.out.println("减速效果");

    }

    @Override
    public void r() {
        System.out.println("击飞效果");
    }

    @Override
    public void d() {
        System.out.println("闪现效果");

    }

}
package role;

public class RoleC extends Role{

    @Override
    public void q() {
        System.out.println("眩晕效果");

    }

    @Override
    public void w() {
        System.out.println("加速效果");

    }

    @Override
    public void e() {//和A的不一样
        System.out.println("护盾效果");

    }

    @Override
    public void r() {
        System.out.println("击飞效果");
    }

    @Override
    public void d() {
        System.out.println("闪现效果");

    }

}

有创建了两个角色,但是发现很多重复的代码在里面,那么就要重新设计一下架构了,首先想到的就是使用接口,每个角色实现接口去实现不同的技能,但是接口不能实现代码复用,所以此路不同。于是你会想一下设计原则:遵循设计的原则,找出应用中可能需要变化的部分,把它们独立出来,不要和那些不需要变化的代码混在一起。这边改变的就是各种技能。再根据另一个设计原则:针对接口(超类型)编程,而不是针对实现编程,于是我们把代码改造成这样:

package skill;

public interface SkillQ {

    void q();
}
package skill;

public interface SkillW {

    void w();
}
package skill;

public interface SkillE {

    void e();
}
package skill;

public interface SkillR {

    void r();
}
package skill;

public interface SkillD {

    void d();
}

定义了不同技能的接口,接下来去实现不同的技能

package bean;

import skill.SkillQ;

public class QXY implements SkillQ{

    public void q() {
        System.out.println("眩晕效果");

    }

}
package bean;

import skill.SkillW;

public class WJiaS implements SkillW{

    public void w() {
        System.out.println("加速效果");

    }

}
package bean;

import skill.SkillW;

public class WSS implements SkillW{

    public void w() {
        System.out.println("伤害效果");

    }

}

不同的接口和技能实现类都写好了,需要重构Role父类

package role;

import skill.SkillD;
import skill.SkillE;
import skill.SkillQ;
import skill.SkillR;
import skill.SkillW;

public abstract class Role {
    private SkillQ skillQ;
    private SkillW skillW;
    private SkillE skillE;
    private SkillR skillR;
    private SkillD skillD;

    public Role setSkillQ(SkillQ skillQ) {
        this.skillQ = skillQ;
        return this;
    }
    public Role setSkillW(SkillW skillW) {
        this.skillW = skillW;
        return this;
    }
    public Role setSkillE(SkillE skillE) {
        this.skillE = skillE;
        return this;
    }
    public Role setSkillR(SkillR skillR) {
        this.skillR = skillR;
        return this;
    }
    public Role setSkillD(SkillD skillD) {
        this.skillD = skillD;
        return this;
    }

    public void q(){
        skillQ.q();
    }
    public void w(){
        skillW.w();
    }
    public void e(){
        skillE.e();
    }
    public void r(){
        skillR.r();
    }
    public void d(){
        skillD.d();
    }

}

重构RoleA:

package role;

public class RoleA extends Role{

}

测试类:

package test;

import role.RoleA;
import bean.DShanXian;
import bean.EJianSu;
import bean.QXY;
import bean.RJiFei;
import bean.WJiaS;

public class Test {

    public static void main(String[] args) {
        RoleA roleA=new RoleA();
        roleA.setSkillQ(new QXY())
        .setSkillW(new WJiaS())
        .setSkillE(new EJianSu())
        .setSkillR(new RJiFei())
        .setSkillD(new DShanXian());

        roleA.q();
        roleA.w();
        roleA.e();
        roleA.r();
        roleA.d();

    }
}

结果:

眩晕效果
加速效果
减速效果
击飞效果
闪现效果

看着创建了很多的java文件,其实每个技能我们都去单独管理。
我们已经定义了一个算法族(各种技能),且根据需求可以进行相互替换,算法(各种技能)的实现独立于客户(角色)。现在是不是很好理解策略模式的定义了。
这里写图片描述

java的面向对象的设计思想,每种功能的独立面向接口的设计,不同功能不同实现,相互独立。

一边学习,一边记录。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值