设计模式-状态模式-以NPC好感度为例

介绍

状态模式定义:

对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

用自己的理解解释一下,就例如人存在多种情绪一样,人类似于对象,情绪就是内部状态,人处于不同情绪时的行为可能是不一样的。如果站在程序的角度,如果我们需要根据内部状态来决定具体对象的行为逻辑,那么一种状态我们就需要加一种判断,状态彼此间过于耦合。所以状态模式将状态也抽象成对象,将状态可能导致的行为放在状态类中去实现,符合迪米特原则。

案例

在一些游戏中商人存在好感度系统,好感度达到一定程度就可以购买一些新的商品,我们可以将商人的好感度阶段看作一种状态,其中状态中变化的方法有购买商品变化,商人对话文案变化,商人好感度提升方式变化。在这里我们将商人好感度分为3个阶段,陌生,熟悉,挚友。接下来看代码实现

NPC类(对象类)

@Data
public class NPC {
    AbstractOpinion opinion;

    public NPC() {
        this.opinion = new StrangeOpinion(this);
    }
    public void receiveGift(int gift){
        opinion.addOpinion(gift);
    }
}

好感度抽象类(状态抽象类)

public abstract class AbstractOpinion {
    //npc对象
    protected NPC npc;
    //好感度值
    protected int goodOpinion=0;
    //加好感方法,我这里简单化处理,就是送礼加好感,实际中业务逻辑会更加复杂一些
    public abstract void addOpinion(int gift);
    //好感度阶段转换,检查好感度是否变化到超过阶段临界值,超过则进行状态变化
    public abstract void changeOpinion();
    //出售商品
    public abstract void sold();
    //对话
    public abstract void talk();
}

陌生阶段好感度类

//70以下好感度为熟悉
public class FamiliarOpinion extends AbstractOpinion{

    public FamiliarOpinion(AbstractOpinion abstractOpinion) {
        goodOpinion=abstractOpinion.goodOpinion;
        this.npc=abstractOpinion.npc;
    }



    @Override
    public void addOpinion(int gift) {
        goodOpinion+=gift;
        System.out.println("熟悉阶段好感度增加"+gift);
        System.out.println("当前好感度:"+goodOpinion);
        changeOpinion();
    }

    @Override
    public void changeOpinion() {
        if(goodOpinion>70){
            System.out.println("好感度超过70,npc现在认为你是他的挚友");
            npc.setOpinion(new IntimateOpinion(this));
        }
    }

    //这里不同好感度可能会出售不同的商品
    @Override
    public void sold() {
        System.out.println("熟悉阶段NPC出售商品");
    }
    //这里不同好感度可能会有不同的对话
    @Override
    public void talk() {
        System.out.println("熟悉阶段NPC对话");
    }

}

熟悉阶段好感度

//好感度0-30为陌生阶段
public class StrangeOpinion extends AbstractOpinion{
    public StrangeOpinion(NPC npc) {
        goodOpinion=0;
        this.npc=npc;
    }
    public StrangeOpinion(AbstractOpinion abstractOpinion) {
        goodOpinion=abstractOpinion.goodOpinion;
        this.npc=abstractOpinion.npc;
    }
    @Override
    public void addOpinion(int gift) {
        goodOpinion+=gift;
        System.out.println("陌生阶段好感度增加"+gift);
        System.out.println("当前好感度:"+goodOpinion);
        changeOpinion();
    }
    @Override
    public void changeOpinion() {
        if(goodOpinion>30){
            System.out.println("好感度超过30,npc现在认为你是熟悉的朋友");
            npc.setOpinion(new FamiliarOpinion(this));
        }
    }
    //这里不同好感度可能会出售不同的商品
    @Override
    public void sold() {
        System.out.println("陌生阶段NPC出售商品");
    }
    //这里不同好感度可能会有不同的对话
    @Override
    public void talk() {
        System.out.println("陌生阶段NPC对话");
    }
}

挚友阶段

public class IntimateOpinion  extends AbstractOpinion{

    public IntimateOpinion(AbstractOpinion abstractOpinion) {
        goodOpinion=abstractOpinion.goodOpinion;
        this.npc=abstractOpinion.npc;
    }
    @Override
    public void addOpinion(int gift) {
        if(goodOpinion>=100) {
            System.out.println("好感度已达上线,请不要再送礼物");
            return;
        }
        goodOpinion+=gift;
        if(goodOpinion>=100) {
            goodOpinion=100;
            System.out.println("好感度达到100,已达到上线");
            return;
        }
        System.out.println("挚友阶段好感度增加"+gift);
        System.out.println("当前好感度:"+goodOpinion);
        changeOpinion();
    }
    //最高好感度不需要改变状态
    @Override
    public void changeOpinion() {

    }

    //这里不同好感度可能会出售不同的商品
    @Override
    public void sold() {
        System.out.println("挚友阶段NPC出售商品");
    }
    //这里不同好感度可能会有不同的对话
    @Override
    public void talk() {
        System.out.println("挚友阶段NPC对话");
    }
}

测试

   @Test
    public void test()
    {
        NPC SaiLiYa = new NPC();
        SaiLiYa.receiveGift(20);
        SaiLiYa.receiveGift(20);
        SaiLiYa.receiveGift(20);
        SaiLiYa.receiveGift(20);
        SaiLiYa.receiveGift(20);
        SaiLiYa.receiveGift(20);
    }

测试结果

陌生阶段好感度增加20
当前好感度:20
陌生阶段好感度增加20
当前好感度:40
好感度超过30,npc现在认为你是熟悉的朋友
熟悉阶段好感度增加20
当前好感度:60
熟悉阶段好感度增加20
当前好感度:80
好感度超过70,npc现在认为你是他的挚友
好感度达到100,已达到上线
好感度已达上线,请不要再送礼物

总结

可以看到,当一个对象的行为取决于它的状态并且状态会在程序运行中改变时适合用状态模式,其实每个状态具有的方法不一定一样,虽然本文案例是基本一样,但是其实每个状态具有的方法可以完全不一样,当然,这样就需要在状态转变时需要更加注意相应方法的调用设计。需要注意的是,状态模式的结构本身并不简单,使用时需要注意状态模式的设计。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值