游戏里的设计模式之观察者模式

游戏里的设计模式之观察者模式

观察者模式

观察这样一来,当一个对象改变状态时,它的所有依赖者都会收到通 知自动更新。 ---------《head first 设计模式》

者模式定义了对象之间的一对多依赖,


观察者模式的优缺点以及解决方案和思想

优点:

  1. 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
  2. 目标与观察者之间建立了一套触发机制。

缺点:

  1. 目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。
  2. 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。

理解:

  1. 关于低耦合的情况,就是观察者都需要实现Observer这个接口,其实可以通过自定义注解加反射来解决这个问题,具体可以参考EventBus的@Subscribe注解
  2. 关于观察多对象过多的情况,一般可以通过异步的方法来解决,但是在操作的时候,如果只是单纯的通知问题不大,但是如果要修改数据之类的,就要注意线程的问题了
  3. 其实在实际场景中,观察者模式进场会变种使用,比如一些模式中都设计到观察者模式的思想,比如事件驱动模式,生产消费模式,通知订阅模型等等,在实际中使用,要学会变种,但是oop的原则不变,保持高内聚,低耦合的设计思想。
  4. 其实观察者模式很好的阐述了 oop原则的 为交互对象之间的松耦合设计而努力

游戏场景中应用

​ 话不多说,观察者模式我就简单的介绍下,接下来主要想表达这个模式在游戏中的应用。其实在游戏中,观察者模式用到的地方真的很多,比如:交易行的关注模块(你关注了哪些商品,商品上架需要通知你),竞价模块(当你竞价的商品价格变高了,需要通知你), 游戏的任务模块(爬塔任务完成需要通知接了爬塔任务的模块,充值任务完成需要通知等等)… 下面我介绍下我们游戏中任务模块的观察者使用具体使用


我大概画了下类图

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

我一个个来解释

​ GameEvent 作为看成观察者模式中的 1主题,比如killMonsterEvent杀怪事件,假如任务A:完成杀一百只怪,成长目标:完成杀怪二百只,那这两个都是监听杀怪事件。并且killMonsterEvent可以传递需要的变量比如怪物数量。

你肯定会好奇:为什么接口下实现了3个event?

​ 其实主要是数据一致性的问题。大概说下我们游戏的线程模型,我们游戏的分为 玩家线程,公共线程,场景线程等,不同的线程消费对应的消息,比如玩家升级自己的装备,完成杀怪任务等都是改变自己的数据该行为消息由玩家线程消费,而交易行购买商品,所有玩家共有的商品,所以购买,上架等操作都是走公共线程。还有一个Absevet是代表同线程执行,就是抛出事件的线程。 所以说在实际场景中使用,会经常操作数据库

下面直接上代码

public interface GameEventListener<T extends GameEvent> {

    /**
     * 事件处理的方法
     */
    void handleEvent(T event) throws Exception;
}


@ListenerEvent(CommonAbandonGuildTaskEvent.class)
public class GiveUpGuildSTaskListener implements GameEventListener<CommonAbandonGuildTaskEvent> {

    @Override
    public void handleEvent(CommonAbandonGuildTaskEvent event) throws Exception {
        
    }
}


public class EventCommandModular implements EventModular {
    private static Logger logger = LoggerFactory.getLogger(EventCommandModular.class);

    private static final EventCommandModular EVENT_COMMAND_MODULAR = new EventCommandModular();

    private static Map<Class<? extends GameEvent>, Set<GameEventListener>> listenersMap = new LinkedHashMap<>();

    public static EventCommandModular getInstance() {
        return EVENT_COMMAND_MODULAR;
    }

    /**
     * 扫描指定包下面的事件; 并将其注册  通过自定义注解@ListenerEvent 
     */
    public void scanRegisterListeners(String packageName) {
        
    }
    

    /**
     * 发布事件
     *
     * @param event 事件
     */
    public void publishEvent(GameEvent event) {
       //这里可以优化
        if (event instanceof RoleEvent) {
            processRoleEvent(event);
            return;
        }
        
        if (event instanceof CommonEvent) {
            processCommonEvent(event);
            return;
        }
       
       //同线程消费
       
            Set<GameEventListener> listeners = listenersMap.get(event.getClass());
            if (listeners == null) {
                return;
            }
            for (GameEventListener listener : listeners) {
                try {
                    listener.handleEvent(event);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值