博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式之观察者模式
阅读量:5973 次
发布时间:2019-06-19

本文共 4850 字,大约阅读时间需要 16 分钟。

  红色警戒--间谍

  间谍是个神奇的角色,可以偷到敌人的矿厂、军营、坦克厂。偷到敌人军营的时,所有的一级兵都能升级成二级,爽歪了。

  所以跟哥们打仗的时候就使劲造狗,狗能识别出间谍,主动出击。

  有时忘了造狗,眼瞅着敌人的间谍大摇大摆地进入军营,着实郁闷。

  间谍进入军营做了什么呢?

 

  假设现在有一个两级的美国大兵、一个伞兵那这个间谍应该怎么做呢。

public void interAnBarracks(){        System.out.println("间谍进入了军营");        footSolider1.partrol();        footSolider2.partrol();        liberationArmy1.partrol();    }

  傻子都能看出来,这有问题啊,如果间谍进入军营之前有早出一个兵来怎么办?改代码么?

  显然不行。

  那我在间谍这里维护一个SoliderList   然后游戏中维护这个List,新造出一个兵来就加入到List中,兵升级了就从List中移除,怎么样?

  累不累啊,游戏要时刻关心着当前有多少兵,有一个兵升级了,就赶紧去移除一下。真是操碎了心啊。

  那到底该怎么办呢,别急,我们先把观察者模式的概念提出来。

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

  观察者模式的目的是提供一种对象设计,让主题和观察者之间松耦合,使得对象之间的互相依赖降到最低。

  这又是一条设计原则:

找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。

   现在我们得出设计方法:在间谍那里维护一份名单,大兵可以注册进这个名单(新来的大兵),也可以从名单中申请退出(大兵升级了)。间谍偷兵营成功后,就通知名单的人,让他们升级。

 

package com.zzl.designpattern.strategy;import com.zzl.designpattern.observer.Sky;public abstract class Solider {    /**    * 行为类    */    IFireable fireable;    /**     * 间谍     */    Sky sky;        /**    * 冲刺    */    public void rush(String direction){        System.out.println("向 " + direction + " 冲刺");    }    /**     * 从间谍那里除名     */    public void unregisteSelf(){        sky.removeSolider(this);    }    /**    * 升级    */    public abstract void  partrol();    /**    * 开火    */    public void fire(){        fireable.fire();    }    /**    * setFireable    */    public void setFireable(IFireable fireable){        this.fireable = fireable;    }        public Sky getSky() {        return sky;    }    public void setSky(Sky sky) {        this.sky = sky;    }    }
Solider.java

 

package com.zzl.designpattern.strategy;import com.zzl.designpattern.observer.Sky;public class FootSolider extends Solider {    public FootSolider(Sky sky){                fireable = new FireWithGun();        System.out.println("新建一个一级美国大兵");        this.sky = sky;        sky.registerSolider(this);    }    @Override    public void partrol() {        System.out.println("美国大兵升级了!");        this.setFireable(new FireWithAK47());        unregisteSelf();    }}
FootSolider.java

 

package com.zzl.designpattern.strategy;import com.zzl.designpattern.observer.Sky;public class LiberationArmy extends Solider {    public LiberationArmy(Sky sky){        fireable = new FireWithGun();        System.out.println("新建一个一级伞兵");        this.sky = sky;        sky.registerSolider(this);    }    @Override    public void partrol() {        System.out.println("伞兵升级了!");        this.setFireable(new FireWithAK47());        unregisteSelf();    }            }
LiberationArmy.java

 

package com.zzl.designpattern.observer;import java.util.ArrayList;import java.util.List;import com.zzl.designpattern.strategy.Solider;public class Sky {    private List
soliderList; public Sky(){ soliderList = new ArrayList
(); System.out.println("新建一个间谍"); } public void interAnBarracks(){ System.out.println("间谍进入了军营"); notifyObservers(); } public void notifyObservers(){ for(Solider solider : soliderList){ solider.partrol(); } } public void registerSolider(Solider solider){ soliderList.add(solider); System.out.println("间谍的名单中新增了一名大兵"); } public void removeSolider(Solider solider){ int i = soliderList.indexOf(solider); if(i > 0){ soliderList.remove(i); System.out.println("间谍的名单中移除了一名大兵"); } } }
Sky.java
package com.zzl.designpattern.main;import com.zzl.designpattern.observer.Sky;import com.zzl.designpattern.strategy.FootSolider;import com.zzl.designpattern.strategy.LiberationArmy;import com.zzl.designpattern.strategy.Solider;public class Game {    public static void main(String[] args) {        Sky sky = new Sky();        Solider footSolider1 = new FootSolider(sky);        Solider footSolider2 = new FootSolider(sky);        Solider liberationArmy1 = new LiberationArmy(sky);        Solider liberationArmy2 = new LiberationArmy(sky);        liberationArmy2.fire();        liberationArmy2.partrol();        liberationArmy2.fire();        sky.interAnBarracks();        footSolider1.fire();        footSolider2.fire();        liberationArmy1.fire();            }}
Game.java

 

   故事是这样的,美国大兵1、美国大兵2走出兵营,伞兵1、伞兵2也都从天而降,他们出来的时候都在间谍那里注册了名字,伞兵2运气比较好,出来以后打死了一个敌人,于是荣升为二级兵,于是换了AK47,就从间谍那退出名单了。这会儿间谍偷了对方的兵营,于是全民狂欢,一级兵都升级为二级兵用上了AK47了,也都从间谍那除名了。输出是这样的:

新建一个间谍新建一个一级美国大兵间谍的名单中新增了一名大兵新建一个一级美国大兵间谍的名单中新增了一名大兵新建一个一级伞兵间谍的名单中新增了一名大兵新建一个一级伞兵间谍的名单中新增了一名大兵使用普通枪攻击伞兵升级了!间谍的名单中移除了一名大兵使用AK47攻击!间谍进入了军营美国大兵升级了!美国大兵升级了!间谍的名单中移除了一名大兵使用AK47攻击!使用AK47攻击!使用普通枪攻击
result

 

   

  在JDK库中提供了一个观察者模式的内置支持,java.utl包中的Observer接口和Observable类,遗憾的是,被观察者是个抽象类,我们的间谍只能继承这个类,那就不能继承别的类了,那么根据我们的设计原则优先用组合怎么样呢,也不行,因为Observable将关键的方法保护起来了,别人用不着。那我们就只能自己实现这个模式了。有兴趣的可以去看看这两了支持类的源码。

 

 

  

转载于:https://www.cnblogs.com/liangflying521/p/5015607.html

你可能感兴趣的文章
Linux vmstat命令实战详解
查看>>
我的友情链接
查看>>
替换k个字符后最长重复子串
查看>>
讲解sed用法入门帖子
查看>>
Java异常学习心得
查看>>
Scala学习之类和属性篇(一):定义类的主构造方法
查看>>
使用阿里云CentOS安装LAMP时,安装PHP扩展需要注意的事情
查看>>
Linux 内核已支持苹果
查看>>
shell脚本逻辑判断,文件目录属性判断,if,case用法
查看>>
【二叉树系列】二叉树课程大作业
查看>>
JAVA spring配置文件总结
查看>>
Java5的 线程并发库
查看>>
HDOJ 1036 输入输出 水
查看>>
Java 安装后的检测是否安装成功
查看>>
设备及分辨率
查看>>
mybatis拦截器
查看>>
App重新启动
查看>>
矩阵乘法
查看>>
得到目标元素距离视口的距离以及元素自身的宽度与高度(用于浮层位置的动态改变)...
查看>>
安装和配置Tomcat
查看>>