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

    xiaoxiao2023-03-24  4

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

    何为观察者模式?

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

    简单的抽象成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中。

    被观察者具体实现:

    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下载

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

    转载请注明原文地址: https://ju.6miu.com/read-1201275.html
    最新回复(0)