栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

《设计模式入门》 16.观察者模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

《设计模式入门》 16.观察者模式

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。也就是就是当一个行为发生时传递信息给另外一个用户接收做出相应的处理,但是两者之间没有直接的耦合关联。

观察者模式一般分为4类:

    抽象被观察者角色:也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。抽象观察者角色:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。具体被观察者角色:也就是一个具体的主题,在集体主题的内部状态改变时,所有登记过的观察者发出通知。具体观察者角色:实现抽象观察者角色所需要的更新接口,一边使本身的状态与制图的状态相协调。

=========================================================================

我们实现一个例子:

我们在商店设置一个自动推送,当显卡补货了我们就给关注商店的人推送补货信息,卖出推送卖出信息,如果不关注了就不推送信息了。

首先我们创建一个抽象观测者的接口:

package ObserverPattern;


public interface Observer {
    
    public void update(String message);
}

我们观测到了被观测者有情况,就调用发送信息的方法。

然后创建一个具体的观测者的类,也就是我们需要发送信息的主体,订阅的用户:

package ObserverPattern;


public class User implements Observer{
    private String name;

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

    
    @Override
    public void update(String message) {
        System.out.println(name +"  收到信息:"+ message);
    }
}

创建抽象被观察者角色:

package ObserverPattern;


public interface Subject {
    
    public void subscribe(Observer observer);

    
    public void unSubscribe(Observer observer);

    
    public void notifyObserver(String message);
}

实现观察者的增减,以及推送信息。

具体被观察者角色:

package ObserverPattern;

import java.util.ArrayList;
import java.util.List;


public class OrderCenter implements Subject {

    private List list;
    private String message;

    public OrderCenter(){
        list = new ArrayList();
    }

    
    @Override
    public void subscribe(Observer observer) {
        list.add(observer);
        System.out.println("订阅成功");
    }

    
    @Override
    public void unSubscribe(Observer observer) {
        if(list.remove(observer)) {
            System.out.println("取消订阅成功");
        }else {
            System.out.println("取消订阅失败");
        }
    }

    
    @Override
    public void notifyObserver(String message) {
        System.out.println("开始发送信息:");
        for (Observer observer: list) {
            observer.update(message);
        }
    }

    
    public void setInformation(String message) {
        this.message = message;
        // 消息更新,通知所有观察者
        notifyObserver(message);
    }
}

我们把具体被观察者定义为一个订阅中心,内部状态改变时,所有登记过的观察者发出通知。

我们定义一个商店接口,被被观察者监控:

package ObserverPattern;


public interface Shop {
    
    public void addCards(Subject subject,int order);

    
    public void saleCards(Subject subject,int order);

}

实现商店为一个具体的显卡商店:

package ObserverPattern;


public class GraphicShop implements Shop{
    private int repertory;

    public GraphicShop(int repertory){
        this.repertory = repertory;
    }

    
    @Override
    public void addCards(Subject subject,int order) {
        repertory+=order;
        subject.notifyObserver("显卡补货了"+order+"张");
    }

    
    @Override
    public void saleCards(Subject subject,int order) {
        if (repertory>0){
            if (order>repertory){
                int sale = order-repertory;
                repertory = 0;
                subject.notifyObserver("显卡不足,售出"+sale+"张");
            }else {
                repertory -= order;
                subject.notifyObserver("出售了" + order + "张");
            }
        }else {
            subject.notifyObserver("显卡售空了");
        }
    }
}

每当我的显卡商店有任何的动作,我的被观测者就会被调用,与此同时观测者就会收到商店变化的消息。

测试一下:

package ObserverPattern;


public class ObserverTest {
    public static void main(String[] args) {
        //创建用户
        User user1 = new User("张三");
        User user2 = new User("李四");
        User user3 = new User("王五");

        //创建消息中心
        Subject subject = new OrderCenter();

        //用户订阅消息
        subject.subscribe(user1);
        subject.subscribe(user2);
        subject.subscribe(user3);

        //商店库存
        int repository = 50;

        //创建显卡商店
        Shop graphicShop = new GraphicShop(repository);

        //商店进货与卖卡
        graphicShop.addCards(subject,300);
        graphicShop.saleCards(subject,200);

        //取消关注
        subject.unSubscribe(user2);

        graphicShop.saleCards(subject,200);
        graphicShop.saleCards(subject,200);
    }
}

 

优点:

            1、观察者和被观察者是抽象耦合的。        2、建立一套触发机制。

缺点:

            1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。        2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。        3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/759969.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号