多线程下的观察者模式--Java实现

来源:互联网 发布:质量好的淘宝店推荐 编辑:程序博客网 时间:2024/06/05 04:18

按照我的理解,观察者模式使用的场景:假如现在有一个土匪,绑架了一名重要人质,目前躲在一个楼房里,楼房四周已经被警察包围,还有特种部队,狙击手。观察者模式是这样运作的:目前场景中的观察者是:警察、防暴队人员、狙击手,被观察者是土匪。一旦土匪现身,各个观察者都要采取相应的措施,比如,当土匪挟持着人质现身,警察警告土匪,狙击手瞄准土匪,特种部队人员悄悄靠近。这就是观察者模式。观察者监听被观察人员的行动,当目标行动出现的时候,观察者开始采取相应的措施。

       实现注意:观察者、被观察者实现各自的接口。注意,被观察者维护一个观察者队列,当被观察者开启线程并且完成相应的工作后,notifyAllWatcher()来让各个观察者采取相应的措施。

       代码如下:

 两个接口设计如下     

package entity;//抽象主题角色,watched:被观察public interface Watched{  //添加观察者  public void addWatcher(Watcher watcher);  //移除观察者  public void removeWatcher(Watcher watcher);  //提醒  public void notifyWatchers();}

package entity;public interface Watcher{ public void takeAction();}

实体类继承这两个接口,enemy还要继承Thread类。

package entity;import java.util.ArrayList;import java.util.List;public class enemy extends Thread implements Watched{// 存放观察者    private List<Watcher> list = new ArrayList<Watcher>();        @Override    public void run()    {    System.out.println("出现");    notifyWatchers();    }        @Override    public void addWatcher(Watcher watcher)    {        list.add(watcher);    }    @Override    public void removeWatcher(Watcher watcher)    {        list.remove(watcher);    }    @Override    public void notifyWatchers()    {        for (Watcher watcher : list)        {            watcher.takeAction();        }    }}

package entity;public class police implements Watcher{@Overridepublic void takeAction(){System.out.println("警察:枪口对准土匪,原地不动");}}

package entity;public class shooter implements Watcher{@Overridepublic void takeAction(){System.out.println("狙击手:开镜-瞄准土匪头部");}}

package entity;public class spy implements Watcher{@Overridepublic void takeAction(){System.out.println("间谍:悄悄潜入,靠近目标");}}

main函数

package testmain;import entity.enemy;import entity.police;import entity.shooter;import entity.spy;public class testmain{public static void main(String args[]){shooter st = new shooter();police pt = new police();spy sp = new spy();enemy ey = new enemy();ey.addWatcher(st);ey.addWatcher(pt);ey.addWatcher(sp);ey.start();}}