java陷阱迷宫,漫画:设计模式中的 “观察者模式”

dc45cf79255a9e56c2cc2905042b6de8.png

7ee02321246da5b51d18988dd16b3e59.png

—————  第二天  —————

6a78f0356a8928ba8b096e6596b45cb5.png

c609d924606f9c21f341d6714d421683.png

76e5d18ab06477afb97b83ef856ef454.png

ffb5e9cf01abf4c5a6a1b139e1613eb8.png

620bbd7e862ea66860f2b03b274b73ec.png

950c9df9575b825e1106f5bcde6ec9fe.png

d656cc96a1542485c9f6cf0dd807936b.png

————————————

f4f18421e9ee5bdcc01c16001c9bc64f.png

6d0edbf7a92cc9aa39de93735dfeaad5.png

9bb03d02678ccc4cf80cf8c0f0a85e90.png

537b597fc99e66c4ccbb575084a03671.png

20094728a59dfa8a70b3fef90adb81e9.png

6cbac279ed9326d2cf9d5cba1bd405cb.png

67925ffb0d3675aa116c0372de88f286.png

场景1:游戏操作界面

在一个小游戏中,包含一个简单的操作界面,界面上有两个按钮:道具和魔法。

d2af269f1febcf2ed8ea7b848696c9c5.png

如果点击“道具”按钮,游戏里的主角会使用道具;如果点击“魔法”按钮,游戏里的主角会使用魔法。

21a53c790224b2692879d943e43be6b8.png

如何让主角实时接收到点击按钮的事件,并做出相应的行动呢?

场景2:游戏迷宫

同样在这个小游戏里,有一个迷宫,迷宫里有怪物、陷阱和宝物。

fea3bebc1e5a1d66f1c0b6ca3b3078d0.png

一旦主角移动到怪物的有效范围,怪物会袭击主角;主角移动到陷阱的有效范围,陷阱会困住主角;主角移动到宝物的有效范围,宝物会为主角加血。

d338198ac4ea07a1e85ac7baa21aa3f2.png

如何让主角移动的事件被怪物、陷阱、道具感知到,并做出正确的反应?

93a205bc7970ef6478c84cf394876cbd.png

d703386addc5fdbb19949813604341c5.png

73c9b53379c1d9421a454b9f7f3e8713.png

900504bc6d893beead52edb8c8c091e8.png

d6d05558fcaafb189449c7bfd7518ec3.png

c4509cff31145cad24b512deaa9024d2.png

3b85c8969cc3a9332871e640effe633b.png

5511ca57f4adf29edff4f434eb2b9fcc.png

bb3d93bb767363276d7cd4f55ec29989.png

public class Hero{    //怪物    Monster monster;    //陷阱    Trap trap;    //宝物    Treasure treasure;    public void move(){        System.out.println("主角向前移动");        //主角移动时,分别通知怪物、陷阱和宝物对象        monster.update();        trap.update();        treasure.update();    }}

673e545274beadb344b92704a4ca97f7.png

98114b355ab34b00641ad27c8671d502.png

6aaee3d5ab7e71a33fe73d6d5902f042.png

5afba8e12ad15b281646c039889873f6.png

a4c477e7326c289f41b3e3b7c7b9ca95.png

bc65c703d0ef341886e8da02b760bb0f.png

807de9feecce12716d2c5e71093a749e.png

3d58be026b12fd94d92d2ee6362b1837.png

c47cd5fcce10692f0e04a501b610d1ce.png

在上面的UML图中,主要有两组实体对象,一组是观察者,一组是被观察者。所有的观察者,都实现了Observer接口;所有的被观察者,都继承自Subject抽象类。

Subject类的成员OberverList,存储着已注册的观察者,当事件发生时,会通知列表中的所有观察者。需要注意的是,OberverList所依赖的是抽象的Observer接口,这样就避免了观察者与被观察者的紧耦合。

d73e890f5a990ba3e1cb0fb98f7c44dc.png

d221e36e575b334189341cb1c6e67463.png

//观察者public interface Observer{    public void update();}//被观察者abstract public class Subject{    private List observerList = new ArrayList();    public void attachObserver(Observer observer){        observerList.add(observer);    }    public void detachObserver(Observer observer){        observerList.remove(observer);    }    public void notifyObservers(){        for (Observer observer: observerList){            observer.update();        }    }}

6d4a1a3cb47fd80f6f13bc72da0a0ab0.png

//怪物public class Monster implements Observer{    @Override    public void update(){        if(inRange()){            System.out.println("怪物 对主角攻击!");        }    }    private boolean inRange(){        //判断主角是否在自己的影响范围内,这里忽略细节,直接返回true        return true;    }}//陷阱public class Trap implements Observer{    @Override    public void update(){        if(inRange()){            System.out.println("陷阱 困住主角!");        }    }    private boolean inRange(){        //判断主角是否在自己的影响范围内,这里忽略细节,直接返回true        return true;    }}//宝物public class Treasure implements Observer{    @Override    public void update(){        if(inRange()){            System.out.println("宝物 为主角加血!");        }    }    private boolean inRange(){        //判断主角是否在自己的影响范围内,这里忽略细节,直接返回true        return true;    }}

上面代码中,每一个具体观察者类都实现了update方法,这是事件触发的回调方法,包含了具体观察者对事件的不同反应。

0f4795bed2b2fd64ca45944337e162b1.png

public class Hero extends Subject{    void move(){        System.out.println("主角向前移动");        notifyObservers();    }}

当主角移动时,通知所有已注册的观察者,执行具体观察者各自的update方法。

e3d1e34108b237dab2c366797161e2db.png

public class Client{public static void main(String[] args){        //初始化对象        Hero hero = new Hero();        Monster monster = new Monster();        Trap trap = new Trap();        Treasure treasure = new Treasure();        //注册观察者        hero.attachObserver(monster);        hero.attachObserver(trap);        hero.attachObserver(treasure);        //移动事件        hero.move();    }}

代码输出如下:

主角向前移动

怪物 对主角攻击!

陷阱 困住主角!

宝物 为主角加血!

8fc3247c1b18bd0e2a92548ea0bd3856.png

3e06dbf4688629734c48ecce6b2f34a1.png

703700af70c9d20eb78a820a4682038f.png

08ec90464dec194cfe159373259584ec.png

END

如有收获,请您分享、点赞、在看

给铁子一个三连击,谢谢!

2c6fd45e85fe18c07d5badbe13cf6955.png

长按下图关注公众号Java学习指南

每天一个Java学习小技巧

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值