设计模式-观察者模式

1.什么是观察者模式

观察者模式(Observer Pattern)又称为发布/订阅模式,  属于行为型模式。

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

自己理解 一个事情随着另一件事情发生变化 , 两个事情存在内在联系  ,一个是观察者 , 另一个是被观察者。

 

2.为什么要用观察者模式

一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知,而不用一个个的进行通知,达到对象依赖关系弱化。

 

3.怎么用观察者模式

例子1

    用户收到人民日报公众号发布房价上涨的消息的不同反应

被观察者  人民日报公众号

观察者   用户

public class ObserverPatternTest {

    public static void main(String[] args) {

            //开始运营订阅号
            WeChatSubscribe subject = new PeopleDaily();
            //用户都已经注册
            AbstractUser obs1 = new ZhangSan();
            AbstractUser obs2 = new LiSi();
            //用户陆续关注
            subject.add(obs1);
            subject.add(obs2);
            //通知已经关注的用户
            subject.notifyObserver();
        }

}

/***
 *功能描述  观察者-----------抽象观察者
 */
abstract class AbstractUser {
    /***
     *  抽象反应,每个人反应不一样,有的吃惊,有的高兴
     */
    abstract void response();
}

/***
 *功能描述  观察者-----------具体观察者---张三
 */
class ZhangSan extends AbstractUser {
    @Override
    public void response() {
        System.out.println("张三作为具体观察者,听了很伤心");
    }
}

/***
 *功能描述  被观察者-----------具体观察者---李四
 */
class LiSi extends AbstractUser {
    @Override
    public void response() {
        System.out.println("李四作为具体观察者,听了很高兴");
    }
}





/***
 *功能描述  被观察者-----------抽象目标,微信订阅号
 */
abstract class WeChatSubscribe {
    /***
     *  定义观察者集合,用于增加、删除订阅者(观察者),可被覆写延迟到子类中实现
     */
    protected List<AbstractUser> observers = new ArrayList<AbstractUser>();

    /***
     *  增加观察者方法,可进行抽象,延迟到子类中实现
     */

    public void add(AbstractUser observer) {
        observers.add(observer);
    }

    /***
     *  删除观察者方法,可进行抽象,延迟到子类中实现
     */
    public void remove(AbstractUser observer) {
        observers.remove(observer);
    }

    /***
     *  通知观察者方法
     */
    public abstract void notifyObserver();
}


/***
 *功能描述  被观察者-----------具体目标 人民日报是具体目标
 */
class PeopleDaily extends WeChatSubscribe {

    @Override
    public void notifyObserver() {
        System.out.println("具体目标发生改变...");
        System.out.println("人民日报发送了房价上涨的消息...");
        System.out.println("--------------");
        for (AbstractUser users : observers) {
            users.response();
        }
    }
}
View Code

结果如下

 

 

例子2 

    用户收到微信服务号的推送消息,若取消关注就收不到推送

被观察者 微信公众号

观察者   用户

public class ObserverPatternTest2 {

    public static void main(String[] args) {
        WechatServer server = new WechatServer();

        Observer userZhang = new User("ZhangSan");
        Observer userLi = new User("LiSi");
        Observer userWang = new User("WangWu");

        server.registerObserver(userZhang);
        server.registerObserver(userLi);
        server.registerObserver(userWang);
        server.setInfomation("第一次推送!");

        System.out.println("----------------------------------------------");
        server.removeObserver(userZhang);
        server.setInfomation("第二次推送!");

    }
}



/**
 *功能描述  观察者接口
 */
interface Observer {
    /**
     *
     */
    public void update(String message);
}

/**
 * 功能描述  观察者接口子类
 */
class User implements Observer {

    private String name;
    private String message;

    public User(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        this.message = message;
        read();
    }

    public void read() {
        System.out.println(name + " 收到推送消息: " + message);
    }

}

/**
 * 功能描述  被观察者接口
 */
interface Observerable {

    /**
     * 注册观察者
     */
    public void registerObserver(Observer o);

    /**
     * 删除观察者
     */
    public void removeObserver(Observer o);

    /**
     * 通知观察者
     */
    public void notifyObserver();

}

/**
 * 功能描述  被观察者子类
 */
class WechatServer implements Observerable {

    /***
     * 注意到这个List集合的泛型参数为Observer接口,设计原则:面向接口编程而不是面向实现编程
     */
    private List<Observer> list;
    private String message;

    public WechatServer() {
        list = new ArrayList<Observer>();
    }

    @Override
    public void registerObserver(Observer o) {
        list.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        if (!list.isEmpty()) {
            list.remove(o);
        }
    }

    @Override
    public void notifyObserver() {
        for (int i = 0; i < list.size(); i++) {
            Observer oserver = list.get(i);
            oserver.update(message);
        }
    }

    public void setInfomation(String s) {
        this.message = s;
        System.out.println("微信服务更新消息: " + s);
        //消息更新,通知所有观察者
        notifyObserver();
    }

}
View Code

结果如下

 

 

例子3

    多方和空方收到原油期货上涨下跌不同反应

被观察者 原油期货

观察者  多方和空方

public class CrudeOilFutures {
    public static void main(String[] args) {
        OilFutures oil = new OilFutures();
        //多方
        Observer bull = new Bull();
        //空方
        Observer bear = new Bear();
        oil.addObserver(bull);
        oil.addObserver(bear);
        oil.setPrice(10);
        oil.setPrice(-8);
    }
}

/***
 *功能描述   被观察者----具体目标类:原油期货
 */
class OilFutures extends Observable {
    private float price;
    public float getPrice() {
        return this.price;
    }
    public void setPrice(float price) {
        //设置内部标志位,注明数据发生变化
        super.setChanged();
        //通知观察者价格改变了
        super.notifyObservers(price);
        this.price = price;
    }
}

/***
 *功能描述   观察者----具体观察者类:多方
 */
class Bull implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        Float price = ((Float) arg).floatValue();
        if (price > 0) {
            System.out.println("油价上涨" + price + "元,多方高兴了!");
        } else {
            System.out.println("油价下跌" + (-price) + "元,多方伤心了!");
        }
    }
}

/***
 *功能描述   观察者----具体观察者类:空方
 */
class Bear implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        Float price = ((Float) arg).floatValue();
        if (price > 0) {
            System.out.println("油价上涨" + price + "元,空方伤心了!");
        } else {
            System.out.println("油价下跌" + (-price) + "元,空方高兴了!");
        }
    }
}
View Code

结果如下

 

posted @ 2021-06-27 00:06  wf.zhang  阅读(90)  评论(0编辑  收藏  举报