设计模式_10:观察者模式

来源:互联网 发布:mac 印象笔记插件下载 编辑:程序博客网 时间:2024/05/22 10:58

观察者(Observer)模式又称为发布订阅模式(Publish/Subscribe),如果一个对象改变时需要通知其他对象,那么就可以用观察者模式解决。

一个简单的例子:顾客订阅了卖家,以后卖家有什么新消息(优惠活动、打折什么的)就可以找到并通知给顾客了:

import java.util.ArrayList;import java.util.List;public class Main {    public static void main(String[] args) {        Seller seller = new Seller();        Customer tony = new Customer("Tony", seller);        Customer lisa = new Customer("Lisa", seller);        seller.attach(tony);        seller.attach(lisa);        seller.setNotifyText("薯条、薯片半价");        seller.send_notify();    }}//卖家(消息通知者)class Seller {    private String notifyText;    private List<Customer> customerList = new ArrayList<>();    //添加顾客(消息订阅者)    public void attach(Customer customer){        customerList.add(customer);    }    //通知顾客最新消息    public void send_notify(){        for (Customer customer : customerList){            customer.update();        }    }    public String getNotifyText() {        return notifyText;    }    public void setNotifyText(String notifyText) {        this.notifyText = notifyText;    }}//顾客(消息订阅者)class Customer {    private String name;    private Seller seller;    public Customer(String name, Seller seller) {        this.name = name;        this.seller = seller;    }    //得到通知时所采取的行动(这里只是简单地输出一下通知内容)    public void update(){        System.out.println(name + "收到通知:" + seller.getNotifyText());    }}


运行结果:

Tony收到通知:薯条、薯片半价Lisa收到通知:薯条、薯片半价


基本的观察者模式是这样了,不过现在卖家和顾客相互紧紧的耦合在一起了,也就是说顾客依赖于具体的卖家,卖家也需要知道具体的顾客,不符合依赖倒转原则,并且如果老板(另一种订阅者)也需要订阅卖家的消息,那么原来卖家的代码就需要修改了,这样也不符合开放-闭合原则,所以需要改良 解耦:

import java.util.ArrayList;import java.util.List;public class Main {    public static void main(String[] args) {        Seller seller = new Seller();        Customer tony = new Customer("Tony", seller);        Customer lisa = new Customer("Lisa", seller);        seller.attach(tony);        seller.attach(lisa);        seller.setNotifyText("薯条、薯片半价");        seller.send_notify();    }}//卖家(消息通知者)class Seller {    private String notifyText;    //把Customer改成Observer    private List<Observer> observerList = new ArrayList<>();    //添加顾客(消息订阅者)    public void attach(Observer observer){        observerList.add(observer);    }    //去除顾客(以后不再通知该顾客)    public void detach(Observer observer){        observerList.remove(observer);    }    //通知顾客最新消息    public void send_notify(){        for (Observer observer : observerList){            observer.update();        }    }    public String getNotifyText() {        return notifyText;    }    public void setNotifyText(String notifyText) {        this.notifyText = notifyText;    }}//抽象出一个观察者类(抽象消息订阅者)abstract class Observer {    protected String name;    protected Seller seller;    public Observer(String name, Seller seller) {        this.name = name;        this.seller = seller;    }    abstract void update();}//顾客(具体消息订阅者)class Customer extends Observer{    public Customer(String name, Seller seller) {        super(name, seller);    }    //得到通知时所采取的行动(这里只是简单地输出一下通知内容)    @Override    public void update(){        System.out.println(name + "收到通知:" + seller.getNotifyText());    }}

通过依赖抽象类Observer,Seller类就不需要知道具体订阅消息的是谁了,但现在顾客依赖的仍然是具体的卖家,所以还需要改改:

import java.util.ArrayList;import java.util.List;public class Main {    public static void main(String[] args) {        Subject seller = new Seller();        Observer tony = new Customer("Tony", seller);        Observer lisa = new Customer("Lisa", seller);        seller.attach(tony);        seller.attach(lisa);        seller.setSubjectState("薯条、薯片半价");        seller.send_notify();    }}//把消息发布者抽象成接口interface Subject {    void attach(Observer observer);    void detach(Observer observer);    void send_notify();    String getSubjectState();    void setSubjectState(String subjectState);}//卖家(消息通知者)class Seller implements Subject{    private String notifyText;    //把Customer改成Observer    private List<Observer> observerList = new ArrayList<>();    //添加顾客(消息订阅者)    @Override    public void attach(Observer observer){        observerList.add(observer);    }    //去除顾客(以后不再通知该顾客)    @Override    public void detach(Observer observer){        observerList.remove(observer);    }    //通知顾客最新消息    @Override    public void send_notify(){        for (Observer observer : observerList){            observer.update();        }    }    @Override    public String getSubjectState() {        return this.notifyText;    }    @Override    public void setSubjectState(String subjectState) {        this.notifyText = subjectState;    }}//抽象出一个观察者类(抽象消息订阅者)abstract class Observer {    protected String name;    protected Subject subject;    public Observer(String name, Subject subject) {        this.name = name;        this.subject = subject;    }    abstract void update();}//顾客(具体消息订阅者)class Customer extends Observer{    public Customer(String name, Subject subject) {        super(name, subject);    }    //得到通知时所采取的行动(这里只是简单地输出一下通知内容)    @Override    public void update(){        System.out.println(name + "收到通知:" + subject.getSubjectState());    }}

最后,我把消息发布者也抽象成接口了



原创粉丝点击