java 设计模式:观察者

1、概念

在对象之间定义了一对多的依赖,使得么当一个对象状态发生改变,其相关依赖对象会收到通知并自动更新。

2、场景

  1. 一个抽象模型有两个方面,其中一个方面依赖于另一个方面
  2. 一个对象的改变将导致一个或多个其他对象也发生改变
  3. 需要在系统中创建一个触发链

3、UML结构图分析

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

4、实际代码分析

实现观察者代码:


/**
 *
 * 创建观察者抽象类
 */
public interface Observer {

//更新方法
    void update(String newStatus);

}

/**
 * 创建观察者实现类
 */
public class ConcreteObserver implements Observer {

    /**
     * 观察者状态
     */
    private String observerState;

    @Override
    public void update(String newStatus) {
        observerState = newStatus;
        System.out.println(newStatus);
    }
}

/**
 * 创建抽象目标者
 * Created by shidawei on 2019/5/23.
 */
public abstract class Subject {

    private List<Observer> mObservers = new ArrayList<>();

    /**
     * 注册观察
     * @param observer
     */
    public void attach(Observer observer){
        mObservers.add(observer);
        System.out.println("注册观察");
    }

    /**
     * 移除观察者
     * @param observer
     */
    public void detach(Observer observer){
        mObservers.remove(observer);
    }

    /**
     * 通知观察者
     * @param newStatus
     */
    public void notifyObsercers(String newStatus){
        for(Observer observer:mObservers){
            observer.update(newStatus);
        }
    }
}

/**
 * 实现被观察者
 */
public class ConcreteSubject extends Subject {
    private String state;

    public String getState() {
        return state;
    }
    public void change(String newState){
        state = newState;
        System.out.println(newState);
        notifyObsercers(newState);
    }
}

//测试代码
ConcreteSubject concreteSubject = new ConcreteSubject();
        concreteSubject.attach(new ConcreteObsercer());
        concreteSubject.attach(new ConcreteObsercer());
        concreteSubject.attach(new ConcreteObsercer());
        concreteSubject.change("123");

java内部的接口实现:

/**
 * Observable 是被观察者对象接口,是对被观察者的实现
 */
public class TargetObervable extends Observable {

    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
        //被观察者数据发生改变的时候通过如下两行代码通知所有观察者
        this.setChanged();
        this.notifyObservers();
    }
}
/**
 * Observer 对象是观察者,实现Observer的对象就是实现观察者对象
 */
public class TargetOberver implements Observer {


    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void update(Observable o, Object arg) {
        System.out.println(name + "收到数据变更" + ((TargetObervable) o).getMessage());
    }
}

//测试代码

        TargetObervable targetObervable = new TargetObervable();
        targetObervable.addObserver(new TargetOberver());
        targetObervable.addObserver(new TargetOberver());
        targetObervable.addObserver(new TargetOberver());
        targetObervable.setMessage("1234");

两种观察者对比:

通过读源码Observable.class我们得知对Observer的集合为Vector

Vector为线程安全的,会保证线程安全,但是性能差。可以采用CopyOnWriteArrayList来代替Vector。

观察者设计模式在Android中的实际运用

回调模式:一对一的模式

实现了抽象类/接口的实例实现了负累的提供的抽象方法,然后将该方法还给父类来处理。

Fragment与activity通信的代码实例:

/**
*回调接口,与activity通信
**/

public interface ISwitchCaoZuoRecordFragment {
        void toSwitch(CaiZuoRecordFragFragment fragment, CaiZuoRecordFragPresenter presenterDecorator);
    }
/**
* activity实现该接口
**/
public class CaoZuoRecordActivity extends BaseActivity<CaoZuoRecordView, CaoZuoRecordPresenter> implements CaoZuoRecordView ,CaiZuoRecordFragFragment.ISwitchCaoZuoRecordFragment{
    @Override
    public void toSwitch(CaiZuoRecordFragFragment fragment, CaiZuoRecordFragPresenter presenterDecorator) {
        mPresenterDecorator = presenterDecorator;
        if(presenterDecorator.studentName!=null&&!presenterDecorator.studentName.equals("")){
            searchListTitleBar.getSearch().setText(presenterDecorator.studentName);
            searchListTitleBar.getClear().setVisibility(View.VISIBLE);
            searchListTitleBar.getSearch_layout().setVisibility(View.VISIBLE);
        }else{
            searchListTitleBar.getSearch().setText("");
            searchListTitleBar.getClear().setVisibility(View.GONE);
            searchListTitleBar.getSearch_layout().setVisibility(View.GONE);
        }

    }

/**
*fragment注册和取消
*/
    @Override
    public void onDetach() {
        super.onDetach();
        iSwitchCaoZuoRecordFragment = null;

    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof ISwitchCaoZuoRecordFragment) {
            iSwitchCaoZuoRecordFragment = (ISwitchCaoZuoRecordFragment) context;
        }else{
            throw new RuntimeException(context.toString()
                    + " 必须实现 ISwitchCaoZuoRecordFragment");
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二蛋和他的大花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值