Android设计模式-观察者模式-行为型-(1)

创建型模式 (3)

简单工厂、工厂法、抽象工厂模式单例模式建造者模式

行为型模式 (2)

观察者模式策略模式

结构型模式 (3)

适配器模式代理模式装饰模式


0. 什么是观察者模式?

当对象间存在一种对应多种依赖关系的,以便与当被依赖对象的状态发生改变时,所有依赖与它的对象都能得到通知,并作出反应。
当对象A、B 都注册到了对象C。AB为依赖对象,C为被依赖对象。
被依赖对象:我们称其为 被观察对象Observable
依赖对象:我们称其为 观察者Observer

被观察者需要具备的特性:
1.容器Container - 例如一个ArrayList集合类,用于保存所有的已注册过的观察者
2.自定义抽象类,提供容器的注册、删除方法
3.自定义抽象类,提供更新(通知)容器内所有观察者的方法

观察者需要具备的特性:
1.自定义抽象类,并实现其方法(从被观察的对象收到更新通知后需要做的方法)
2.将自己注册到 被观察对象 中


1. 优缺点

优点:

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

缺点:

如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

使用场景:

一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
.
一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
.
一个对象必须通知其他对象,而并不知道这些对象是谁。
需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

注意事项:

1、JAVA 中已经有了对观察者模式的支持类。
2、避免循环引用。
3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

2. 哪些库或方法使用观察者模式来实现的?

监听器、点击事件、滚动事件
rxjava、eventbus、广播 架构组件Livedata


3. 举例说明-学生-老师

对象:老师(被观察者)、普通学生、班长(观察者)
事件:老师去开会了,班内的所有学生得到通知。普通学生和班长分别作出不同反应

  • 1.学生自定义抽象方法
/**
 * 创建抽象观察者,定义接收到通知
 * Observer
 */
public interface StudentObserverInterface {
    void receivedNotifyFromTeacher(String msg);
}
  • 2.学生类实现自定义的抽象方法
/**
 * 创建具体观察者,实现抽象方法,并对收到的通知作出反应
 * Concrete
 */
public class StudentObserver implements StudentObserverInterface {
    private String studentName; //学生名字
    private boolean isMonitor; //是否是班长

    public StudentObserver (String studentName,boolean isMonitor){
        this.studentName = studentName;
        this.isMonitor = isMonitor;
    }
    @Override
    public void receivedNotifyFromTeacher(String msg) {
        if(isMonitor){ //如果是班长
            Log.d(ObserverPatternActivity.TAG, studentName+":>> 好的老师!我会维持班级秩序");
        }else {  //普通学生
            Log.d(ObserverPatternActivity.TAG, studentName+":>> 太好了,老师去开会了");
        }
    }
}
  • 3.老师自定义抽象方法(注册添加,删除,更新)
/**
 * 创建抽象(被观察者)主题,定义添加,删除,通知等方法:
 * Subject
 */
public interface TeacherObservableInterface {
    void addStudent(StudentObserverInterface observer);//添加观察者 (添加学生)

    void removeStudent(StudentObserverInterface observer);//删除观察者 (删除学生)

    void notifyToStudent(String message);//通知观察者 (通知学生)
}
  • 4.老师类实现自定义的抽象方法
/**
 * 创建具体(被观察者)主题,实现抽象方法。
 * ConcreteSubject
 */
public class TeacherObservable implements TeacherObservableInterface {
    //Container容器
    private ArrayList<StudentObserverInterface> studentList = new ArrayList<StudentObserverInterface>();//保存收件人(观察者)的信息

    @Override
    public void addStudent(StudentObserverInterface observer) {
        studentList.add(observer);
    }

    @Override
    public void removeStudent(StudentObserverInterface observer) {
        studentList.remove(observer);
    }

    @Override
    public void notifyToStudent(String message) {
        for(int i = 0; i< studentList.size(); i++){ //逐个通知所有的观察者(这里指的是逐个通知所有的学生)
            studentList.get(i).receivedNotifyFromTeacher(message);
        }
    }
    public ArrayList<StudentObserverInterface> getStudentList(){
        return studentList;
    }
}
  • 5.activity
public class ObserverPatternActivity extends AppCompatActivity {
    private TeacherObservable mTeacherObservable = new TeacherObservable();
    public static String TAG ="观察者模式:>> ";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_observer_pattern);
        addStudent();
        teacherNotify();
    }

    private void addStudent(){
        StudentObserver studentObserver1 = new StudentObserver("小红",true);
        mTeacherObservable.addStudent(studentObserver1);
        StudentObserver studentObserver2 = new StudentObserver("李明",false);
        mTeacherObservable.addStudent(studentObserver2);
        StudentObserver studentObserver3 = new StudentObserver("张三",false);
        mTeacherObservable.addStudent(studentObserver3);
    }
    private void teacherNotify(){
        Log.d(TAG, "老师开会,并发布通知到所有学生: ");
        mTeacherObservable.notifyToStudent("老师去开会了,班长管一下班级");
    }

}

运行后的结果是:
在这里插入图片描述


那么假设场景张三退学了,那么我们就需要将张三从老师的容器内删除,这样张三就收不到通知事件了。

public class ObserverPatternActivity extends AppCompatActivity {
    private TeacherObservable mTeacherObservable = new TeacherObservable();
    public static String TAG ="观察者模式:>> ";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_observer_pattern);
        addStudent();
        removeStudent();
        teacherNotify();
    }

    private void addStudent(){
        StudentObserver studentObserver1 = new StudentObserver("小红",true);
        mTeacherObservable.addStudent(studentObserver1);
        StudentObserver studentObserver2 = new StudentObserver("李明",false);
        mTeacherObservable.addStudent(studentObserver2);
        StudentObserver studentObserver3 = new StudentObserver("张三",false);
        mTeacherObservable.addStudent(studentObserver3);
    }
    private void teacherNotify(){
        Log.d(TAG, "老师开会,并发布通知到所有学生: ");
        mTeacherObservable.notifyToStudent("老师去开会了,班长管一下班级");
    }
    private void removeStudent(){
        mTeacherObservable.removeStudent(mTeacherObservable.getStudentList().get(0));
    }
}

运行后的结果是:

在这里插入图片描述


4. Android技术生活交流

微信



[1]* 参考文章1
[2]* 参考文章2
[3]* 参考文章3
[4]* 参考文章4
[5]* 参考文章5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值