个人理解的Android设计模式之观察者模式

接触安卓有一段时间了,之前一直都不懂什么设计模式之类的,
最近在做一个项目,从项目中理解到了一种观察者模式,个人
觉得这种观察者模式很好理解,也很好运用。

何为观察者模式?

观察者模式由 观察者被观察者 组成。

简单的抽象成2种角色:观察角色、被观察角色。

观察角色时刻关注着被观察角色的动态,被观察角色一有动向就会向
观察角色发出一个通知,告诉它“我变化了”,你该做出相应的动作了。

观察者模式的应用与好处

场景:

MainActivity 跳转至 SecondActivity中修改资料,然后返回MainActivity。

好处:

实时更新修改的状态。

观察者接口:

public interface Watcher {
    //被观察者改变通知更新
    void update(WatchEnum watchEnum);
}

被观察者接口:

public interface Watched {
    void addWatcher(Watcher watcher); // 添加观察者

    void removeWatcher(Watcher watcher); // 移除观察者

    void notifyWatchers(WatchEnum updateWatchEnum); // 通知观察者更新

    void remoteWatchers(); // 清除观察者
}

由于一个被观察者可以被多个观察者关注,因此将观察者保存在List中。

扫描二维码关注公众号,回复: 11473698 查看本文章

被观察者具体实现:

public class ConcreteWatched implements Watched {
    //存放观察者
    private List<Watcher> list = new ArrayList<>();
    private static ConcreteWatched concreteWatched;

    //获取被观察者具体实现的实例
    public static ConcreteWatched getInstance() {
        if (concreteWatched == null) {
            concreteWatched = new ConcreteWatched();
        }
        return concreteWatched;
    }

    @Override
    public void addWatcher(Watcher watcher) {
        list.add(watcher);
    }

    @Override
    public void removeWatcher(Watcher watcher) {
        list.remove(watcher);
    }

    @Override
    public void notifyWatchers(WatchEnum updateWatchEnum) {
        for (Watcher w : list) {
            if (w != null) {
                w.update(updateWatchEnum);
            }
        }
    }

    @Override
    public void remoteWatchers() {
        list.clear();
    }
}

上述代码 notifyWatchers(WatchEnum updateWatchEnum) 中
的 WatchEnum 是一个枚举类,通过这个枚举类参数让被观察者
知道通知哪个观察者改变状态。

public enum WatchEnum {
    TEXT1, TEXT2, TEXT3
}

此Demo中只列出了三个对象的改变,故枚举类中只有3个值。根据实际情况添加。

接下来说说Demo的具体实现:

在MainActivity中有3个TextView以及一个Button按钮,点击按钮跳转到
SecondActivity中,在SecondActivity中修改数据,点击返回键到MainActivity,可以看到MainActivity中三个TextView中显示数据发生了变化。

正常情况下,修改数据返回到ManActivity,数据显示是不会变化的。
以前还不懂观察者模式的时候,就只会利用Activity的生命周期,在
onResume方法中实现返回更新数据的效果,现在感觉这种方法实在
是太LOW。

注意:
1、由于是MainActivity的数据需要更新,因此需要实现 Watcher 接口,显示其 update 方法。
2、必须要将观察者添加到List中

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ConcreteWatched.getInstance().addWatcher(this); // important
    }

一开始通过读取保存在SharedPrefreences文件中的数据。

private void setValue() {
        String str1 = SPManager.getInstance().getString(this, SPManager.TXT1);
        String str2 = SPManager.getInstance().getString(this, SPManager.TXT2);
        String str3 = SPManager.getInstance().getString(this, SPManager.TXT3);

        txt1.setText(str1);
        txt2.setText(str2);
        txt3.setText(str3);
    }

当第一次为空的时候,默认显示“没有数据”。

public String getString(Context context, String key) {
        SharedPreferences sharedPreferences = context.getSharedPreferences(WATCH_TEST, Activity.MODE_PRIVATE);
        return sharedPreferences.getString(key, "没有数据");
    }

当在SecondActivity中修改数据并保存后,返回后则会显示最新保存的数据。

public void alter1(View view) {
        if (!TextUtils.isEmpty(edt1.getText().toString())) {
            SPManager.getInstance().saveString(this, SPManager.TXT1, edt1.getText().toString());
            ConcreteWatched.getInstance().notifyWatchers(WatchEnum.TEXT1); // 通知MainActivity中TextView1更新
            Toast.makeText(this, "修改成功,请看返回键查看", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, "不能为空", Toast.LENGTH_LONG).show();
        }
    }

以上是SecondActivity三个EditText中的一个修改方法。

ConcreteWatched.getInstance().notifyWatchers(WatchEnum.TEXT1);

这句代码起到通知观察者更新的作用。
还记得在MainActivity中实现的Watcher接口的实现方法update(WatchEnum)吗?

WatchEnum.TEXT1即为一个标志码,通知众多观察者具体的哪个。

再来看看MAinActivity中的代码:

    @Override
    public void update(WatchEnum watchEnum) {
        switch (watchEnum) {
            case TEXT1:
                String str1 = SPManager.getInstance().getString(this, SPManager.TXT1);
                txt1.setText(str1);
                break;
        }
    }

就这样简简单单的Demo就能实现观察者的效果。

最后最好在一个Activity销毁的时候移除当前观察者;

    @Override
    protected void onDestroy() {
        ConcreteWatched.getInstance().removeWatcher(this);
        super.onDestroy();
    }

完整代码:完整Demo下载

有不对的地方欢迎各位大神指出,必定虚心学习共同进步。

猜你喜欢

转载自blog.csdn.net/u014112893/article/details/52685112
今日推荐