java设计模式之观察者模式

103 阅读3分钟

创建产品对象,产品对象要继承Observable

package cn.quangaoleng;

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

public class ProductList extends Observable {

    private List<String> listProduct = null;
    private static ProductList instance;
    private ProductList(){
    }

    public static ProductList getInstance(){
        if(instance==null){
            instance= new ProductList();
            instance.listProduct = new ArrayList<>();
        }
        return instance;
    }

    @Override
    public synchronized void addObserver(Observer o) {
        super.addObserver(o);
    }

    public void addProduct(String newProduct){
        listProduct.add(newProduct);
        System.out.println("正在添加产品");
        this.setChanged();
        this.notifyObservers(newProduct);
    }
}


class  TaoBaoObserver implements Observer{

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("淘宝得到新产品"+(String)arg);
    }
}

class JingDongObserver implements  Observer{

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("京东得到新产品"+(String)arg);
    }
}

+创建观察者京东

package cn.quangaoleng;

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

public class ProductList extends Observable {

    private List<String> listProduct = null;
    private static ProductList instance;
    private ProductList(){
    }

    public static ProductList getInstance(){
        if(instance==null){
            instance= new ProductList();
            instance.listProduct = new ArrayList<>();
        }
        return instance;
    }

    @Override
    public synchronized void addObserver(Observer o) {
        super.addObserver(o);
    }

    public void addProduct(String newProduct){
        listProduct.add(newProduct);
        System.out.println("正在添加产品");
        this.setChanged();
        this.notifyObservers(newProduct);
    }
}


class  TaoBaoObserver implements Observer{

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("淘宝得到新产品"+(String)arg);
    }
}

class JingDongObserver implements  Observer{

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("京东得到新产品"+(String)arg);
    }
}

创建观察者淘宝

package cn.quangaoleng;

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

public class ProductList extends Observable {

    private List<String> listProduct = null;
    private static ProductList instance;
    private ProductList(){
    }

    public static ProductList getInstance(){
        if(instance==null){
            instance= new ProductList();
            instance.listProduct = new ArrayList<>();
        }
        return instance;
    }

    @Override
    public synchronized void addObserver(Observer o) {
        super.addObserver(o);
    }

    public void addProduct(String newProduct){
        listProduct.add(newProduct);
        System.out.println("正在添加产品");
        this.setChanged();
        this.notifyObservers(newProduct);
    }
}


class  TaoBaoObserver implements Observer{

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("淘宝得到新产品"+(String)arg);
    }
}

class JingDongObserver implements  Observer{

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("京东得到新产品"+(String)arg);
    }
}

这是一个观察者模式的代码。被观察的对象采用单例模式,继承observable,而观察者实现observer的接口,通过update方法得到observable 参数的通知

猜测:通过前面的代码,观察者模式应该也是通过反射去实现的, 在调用父类的addObserver方法时,将添加的实现了observer接口的对象存储下来,因为观察者对象是通过Observer的接口类型接收的,所以一定实现了update方法且参数固定, 在调用notifyObservers方法时,被观察者这个类去找add方法存储的的观察者对象,通过反射创建观察者的实例,再实现此实例的update方法 (这段代码只是一段猜测,或者说是自己实现观察者模式的一个思路,并不一定正确,内部也不一定这样实现)

在猜测后看了Observable的代码,内部的确是用一个 Vector obs去存储的,至于 boolean changed = false;应该是一个标志

     public void notifyObservers(Object arg) {
            Object[] arrLocal;

            synchronized (this) {
                if (!changed)
                    return;
                arrLocal = obs.toArray();
                clearChanged();
            }
            for (int i = arrLocal.length-1; i>=0; i--)
                        ((Observer)arrLocal[i]).update(this, arg);
      }

调用ontifyObservver方法时,一个个去调用存储的观察者的update方法,这里的changed标志,应该和

    public synchronized void addObserver(Observer o) {
              if (o == null)
                  throw new NullPointerException();
              if (!obs.contains(o)) {
                  obs.addElement(o);
              }
          }

这段代码中的如果已有则跳过一样,都是对于代码的优化,而且同步也避免了在添加时出现对已有的进行二次添加
如果思考一个场景,被观察者手中有产品,而观察者坐在被观察者家中的沙发上,当我们添加一个公 司的另一个业务员,他就会挡在门外,当把新产品放在被观察者模式手中, 对着被观察者喊一声:Hello,有新产品了;然后当调用notifyObserver方法时,被观察者判断你告诉你有新产品了吗,你告诉了我才做,如果你说了有新产品,好,被观察者将 手中的这款产品递给沙发上的每一个人,这个代码可能十分简单,但是一些优化的方法,例如同步,判断重复,标志变量来决定是否执行一个较为耗时的方法,还是值得学习的