23种设计模式之-观察者模式(Android应用场景介绍)

最近买了一本设计模式的书,于是就边看边记录一下,然后把它变成实际生产中应用。

所谓观察者模式,简单来说就由观察者和被观察者组成,观察者订阅被观察者,只有订阅了观察者才能收到被观察者的动态信息。

咱们就用生活中简单的例子来说明,如:咱们现在刷的抖音,比如你非常喜欢一个小姐姐的抖音,所以小手一抖点了关注,然后后面这个小姐姐一有动态,你就收到了她的抖音短视频。这里面小姐姐就是那个被观察的对象,而你就是那个观察者,当你点击关注的时候就相当于你订阅了她的抖音动态。

下面咱们上一个非常常见的Android应用场景,咱们在应用市场的时候点击安装一个应用,就会显示进度条,当你点击进去看详情的时候发现进度条也在更新,并且跟外面列表更新一致。这里咱们就可以用到这个观察者模式来实现。

首先咱们先定一个被观察者的接口,如下代码:

package com.app.mode.observer;

public interface Subject<T> {
    void registerObserver(Observer<T> observer);

    void removeObserver(Observer<T> observer);


    void notifyObservers();
}

这个接口就是定义注册,删除和更新的方法,咱们要用它的时候先实现这个接口。如下随意写了一个下载类,这个是伪下载类就是个倒计时显示进度条。如下代码:

package com.app.mode.observer;

import android.os.CountDownTimer;

import java.util.ArrayList;
import java.util.List;

/*
下载任务,观察者
 */
public class DownLoadSubject implements Subject<Integer> {
    private List<Observer<Integer>> observers;
    private int currentProgress = 0;
    private static DownLoadSubject instance;
    private CountDownTimer mTimer;

    private DownLoadSubject() {
        observers = new ArrayList<>();
        mTimer = new CountDownTimer(100 * 1000, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                currentProgress += 1;
                notifyObservers();//进度改变通知更新
            }

            @Override
            public void onFinish() {
            }
        };
        mTimer.start();
    }

    public static DownLoadSubject getInstance() {
        if (instance == null)
            instance = new DownLoadSubject();
        return instance;
    }

    @Override
    public void registerObserver(Observer<Integer> observer) {
        if (observers.indexOf(observer) == -1) {//注册观察者,判断当前观察者对象中有没有被添加,没有添加就添加到队列中
            observers.add(observer);
        }
    }

    @Override
    public void removeObserver(Observer<Integer> observer) {
        if (observers.indexOf(observer) != -1) {//注册观察者,判断当前观察者对象中有没有被添加
            observers.remove(observer);
        }
    }


    @Override
    public void notifyObservers() {//遍历队列,通知观察者更新
        for (Observer<Integer> observer : observers) {
            observer.onUpdate(currentProgress);
        }
    }
}

这个类其实还用到了一个单例模式,并且这个单例模式是有问题的,特别是在多线程下操作的时候,这个后面会详细介绍,这里只要记得一定要单例模式确保咱们进度条一致性。

接下来就是观察者了,咱们先定义一个接口,如下:

package com.app.mode.observer;

public interface Observer<T> {
    void onUpdate(T t);
}

这里其实就是一个更新的方法,接下来就是是实现该方法了。如下:

package com.app.mode.observer.activity;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.SeekBar;

import com.app.mode.R;
import com.app.mode.observer.DownLoadSubject;
import com.app.mode.observer.Observer;

//这里相当于应用商城的列表页,点击下载的时候出现进度条,点击详情页就显示应用详情进度条也会更新到当前进度
public class ObserverActivity extends AppCompatActivity implements Observer<Integer> {//这里也是观察者
    private SeekBar seekBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_observer);
        DownLoadSubject.getInstance().registerObserver(this);
        seekBar = findViewById(R.id.seekBar);
    }

    @Override
    public void onUpdate(Integer integer) {
        seekBar.setProgress(integer);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        DownLoadSubject.getInstance().removeObserver(this);//这里记得删除当前观察者,不然会报异常
    }

    public void startDetail(View view) {
        startActivity(new Intent(getApplicationContext(), ObserverActivityDetail.class));
    }
}

这是外面一个列表的显示,就是一个activity然后实现观察者接口。然后这个activity就变成了观察者了,下面详情页实现这个观察者接口,如下:

package com.app.mode.observer.activity;

import android.os.Bundle;
import android.widget.SeekBar;

import androidx.appcompat.app.AppCompatActivity;

import com.app.mode.R;
import com.app.mode.observer.DownLoadSubject;
import com.app.mode.observer.Observer;

public class ObserverActivityDetail extends AppCompatActivity implements Observer<Integer> {
    private SeekBar seekBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.acitivity_observer_detail);
        DownLoadSubject.getInstance().registerObserver(this);
        seekBar = findViewById(R.id.seekBar);
    }

    @Override
    public void onUpdate(Integer integer) {
        seekBar.setProgress(integer);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        DownLoadSubject.getInstance().removeObserver(this);
    }
}

ok,观察者这样就实现了。

其实这个观察者模式在java代码中早已实现,如下:

这里只是比我那里多了一个参数,然后被观察者是Observable这里就不贴出来了,这类中实现方法差不多,但是它这里功能比较全然后观察者用的是Vector集合。

Vector 类实现了一个动态数组。和 ArrayList 很相似,但是两者是不同的:

  • Vector 是同步访问的。
  • Vector 包含了许多传统的方法,这些方法不属于集合框架。

 这个大家可以自己去看源码,加深理解。

至于实现效果,想看的直接代码跑起来就可以看到了,这里就不做gif动图显示了。

后续把所有学习到的模式全部介绍一下,跟大家一起学习加深理解

代码地址:GitHub

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值