TWT Studio - Android 组培训 & 技术分享

Observer模式

2018-07-16  本文已影响117人  吃啥呀

java的设计模式


作用 当观察对象的状态发生变化时,通知给观察者(观察者订阅被观察者的状态)
应用 需要根据对象状态进行相应处理的场景

Observer.png

创建Subject类

package com.company;

import javax.swing.text.html.HTMLDocument;
import java.util.ArrayList;
import java.util.Iterator;

public abstract class Subject{

    private ArrayList observers = new ArrayList();//保存Observer们
    public void addObserver(Observer observer){
        observers.add(observer);
    };//注册Obeserver
    public void notifyObservers(){
        //向Observer发送通知
        Iterator it = observers.iterator();
        while (it.hasNext()){
            Observer observer = (Observer)it.next();
            observer.update();
        }
    }
    public abstract int getState();
    public abstract void setState();\\写成抽象方法,便于拓展
}

Subject的子类

package com.company;

import java.util.Random;

public class Subjecta extends Subject{
    private int number;
    private Random random = new Random();

    @Override
    public int getState() {
        return number;
    }

    @Override
    public void setState() {
        for(int i = 0 ;i < 10 ;i++){
            number = random.nextInt(48);
            notifyObservers();
        }
    }
}

创建抽象Observer类

package com.company;

public abstract class Observer {
    protected Subject subject;\\有Subject类的实例化对象,便于获取被观察者的信息
    public abstract void update();\\在子类中实现更新的具体操作
}

创建实体观察类

package com.company;

public class Observera extends Observer{
    public Observera(Subject subject){
        this.subject = subject;
        this.subject.addObserver(this);
    }

    @Override
    public void update() {
        System.out.println( "Observera : " + subject.getState());
    }
}

public class Observerb extends Observer{
    public Observerb(Subject subject){
        this.subject = subject;
        this.subject.addObserver(this);
    }

    @Override
    public void update() {
        System.out.print("Observerb : ");
        for(int i = 0 ;i< subject.getState();i++) {
            System.out.print('-');
        }
        System.out.println();
    }
}

在客户端(Main)使用

package com.company;

public class Main {

    public static void main(String[] args) {
        Subject subject = new Subjecta();
        new Observera(subject);
        new Observerb(subject);\\创建观察者

        subject.setState();\\设置状态(改变状态)
    }
}

另一种实现方法

package com.company;

public interface ObserverI {
    public abstract void update(Subject subject);
}
public abstract class Subject{

    private ArrayList observers = new ArrayList();//保存Observer们
    public void addObserver(Observer observer){
        observers.add(observer);
    };//第一种,注册obeserver

    public void addObserver(ObserverI observer){
        observers.add(observer);
    };//第二种方法,注册Obeserver的方式

    public void notifyObservers(){
        //向Observer发送通知
        Iterator it = observers.iterator();
        while (it.hasNext()){
            Observer observer = (Observer)it.next();
            observer.update();
        }
    }//第一种

    public void notifyObservers2(){
        //向Observer发送通知
        Iterator it = observers.iterator();
        while (it.hasNext()){
            ObserverI observer = (ObserverI)it.next();
            observer.update(this);//改变后的update方法需要传入一个subject进去
        }
    }//第二种方法
//注意:在状态改变后(setState)应当调用的发送通知的方法也应当换成第二种对应的
}

package com.company;

public class ObserverI1 implements ObserverI{
    @Override
    public void update(Subject subject) {
        System.out.println( "Observera : " + subject.getState());
    }
}

public class ObserverI2 implements ObserverI{
    @Override
    public void update(Subject subject) {
        System.out.print("Observerb : ");
        for(int i = 0 ;i< subject.getState();i++) {
            System.out.print('-');
        }
        System.out.println();
    }
}

//第一种注册observer的方式
public class Observerb extends Observer{
    public Observerb(Subject subject){
        this.subject = subject;
        this.subject.addObserver(this);//改变后
    }
}//第一种只要创建了Subject具体实现类的实例化对象,就在被观察者中添加了观察者,

//第二种方法,注册Observer的方式
public class Main {

    public static void main(String[] args) {
        Subject subject = new Subjecta();
        Observer observer1 = new Observera();
        Observer observer2 = new Observerb();//创建观察者
            subject.addObserver(observer1);
            subject.addObserver(observer2);
        subject.setState();\\设置状态(改变状态)
    }
}//现在,创建观察者后,还需调用被观察者中添加观察者的方法)

注意点

Observer的顺序

Subject角色中有多个Observer角色,在示例代码中是先注册的Observer的update方法先被调用

Observer的行为对Subject的影响

Subject的状态变化 ---> 通知Observer ---> Observer调用Subject的方法 ---> 导致Subject的状态发生变化 ---> 通知Observer
导致方法被循环调用

update方法传入的参数

void update(Subject subject); 
void update(int number);  
void update(Subject subject,int number); 

可以传入Subject实例对象,也可以传入该实例中的某些数据,第一种更加灵活

拓展
java.utill.Observer 接口
java.utill.Observable 类 ——被观察的Subject角色

 public void update(Observable obj,Object arg)//Object类的实例是附加信息

缺陷Subject角色必须是java.utill.Observable 类的子类,但是java是单一继承

以上完整的代码上传到了github仓库
https://github.com/chenshuyuhhh/DesignPatternDemo.git

上一篇下一篇

猜你喜欢

热点阅读