美文网首页
21_简单使用观察者模式进行值传递

21_简单使用观察者模式进行值传递

作者: Android_小生 | 来源:发表于2017-08-30 17:00 被阅读36次

    概念


    被观察者-观察者

    观察者模式是 23 种设计模式中的一种。它定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。

    观察者模式存在的意义就是「解耦」,它使观察者和被观察者的逻辑不再搅和在一起,而是彼此独立、互不依赖。

    观察者模式简单代码示例


    定义被观察者(Observable)接口

    public interface ObservableImpl {
        // 注册一个观察者
        void registerObserver(Observer observer);
    
        // 移除一个观察者
        void removeObserver(Observer observer);
    
        // 通知注册的观察者更新
        void notifyObserver();
    }
    

    实现具体的被观察者

    public class Observable  implements ObservableImpl{
    
        // 定义集合用来存放每一个注册进来的观察者
        private List<Observer> observers = null;
        // 被观察者当前状态
        public String ObservableState = "0";
        public Observable() {
            if (observers == null)
                observers = new ArrayList<>();
        }
    
        // 注册观察者
        @Override
        public void registerObserver(Observer observer) {
            if (observers != null)
                observers.add(observer);
        }
    
        // 移除观察者
        @Override
        public void removeObserver(Observer observer) {
            if (observers != null || observers.size() != 0)
                observers.remove(observer);
        }
    
        // 通知所有注册的观察者进行更新
        @Override
        public void notifyObserver() {
            if (observers == null || observers.size() == 0)
                return;
    
            for (Observer o: observers) {
                o.update();
            }
        }
    
        public void setObservableState(String observableState) {
            ObservableState = observableState;
            notifyObserver();
        }
    }
    

    定义观察者(Observer)接口

    public interface ObserverImpl {
        void update();
    }
    

    实现具体观察者类

    public class Observer implements ObserverImpl {
    
        private String observerState = "0"; // 观察者初始状态
        private String name; // 当前观察者名称
        private Observable observable;
    
        // 被观察者把自己传给观察者,当状态改变时,通知列表中的观察者
        public Observer(String name, Observable observable) {
            this.name = name;
            this.observable = observable;
            System.out.println("我是观察者" + name + "我的初始化状态是" + observerState);
        }
    
        // 当被观察者状态改变,观察者需要随之改变
        @Override
        public void update() {
            observerState = observable.ObservableState;
            System.out.println("我是观察者" + name + "我的初始化状态是" + observerState);
        }
    }
    

    前端调用打印

    public class Test {
    
        public static void main(String[] args) {
            Observable observable = new Observable();
            observable.registerObserver(new Observer("A", observable));
            observable.registerObserver(new Observer("B", observable));
            observable.registerObserver(new Observer("C", observable));
            observable.setObservableState("1");
        }
    }
    

    打印日志

    我是观察者A我的初始化状态是0
    我是观察者B我的初始化状态是0
    我是观察者C我的初始化状态是0
    我是观察者A我的初始化状态是1
    我是观察者B我的初始化状态是1
    我是观察者C我的初始化状态是1
    

    Android 中实现值传递


    在 Android 开发中,我们经常会遇到 Activity 与 Fragment 之间的传值,或者 Fragment 与 Fragment 之间的传值。我们会想到想到广播、接口回调等一些办法,下面会介绍通过观察者模式来实现值传递。具体实现步骤如下

    定义被观察者接口

    public interface ObservableImpl {
        void registerObserver(ObserverImpl observer);
        void removeObserver(ObserverImpl observer);
        void notifyObserver();
    }
    

    实现被观察者实现类

    public class Observable implements ObservableImpl {
        private List<ObserverImpl> observers = null;
        public String state = "";
        public Observable() {
            if (observers == null)
                observers = new ArrayList<>();
        }
    
        @Override
        public void registerObserver(ObserverImpl observer) {
            if (observers != null)
                observers.add(observer);
        }
    
        @Override
        public void removeObserver(ObserverImpl observer) {
            if (observer != null || observers.size() != 0)
                observers.remove(observer);
        }
    
        @Override
        public void notifyObserver() {
            if (observers == null || observers.size() == 0)
                return;
            for (ObserverImpl observer : observers) {
                observer.update(state);
            }
        }
    
        public void setState(String state) {
            this.state = state;
            notifyObserver();
        }
    }
    

    观察者接口,就是一个通知刷新的简单方法

    public interface ObserverImpl {
        void update(String title);
    }
    

    在 Fragment 中实现观察者接口

    public class MyFragment extends Fragment implements ObserverImpl{
    
        private View view;
        private TextView textView;
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                                 @Nullable Bundle savedInstanceState) {
            view = inflater.inflate(R.layout.fragment_view, container, false);
            textView = view.findViewById(R.id.title);
            return view;
        }
        // 当 Activity 中的数据发生变化时,被观察者会调用刷新通知 Fragment 刷新
        @Override
        public void update(String title) {
            textView.setText(title);
        }
    }
    

    在 Activity 中通过创建被观察者实例,注册添加观察者,当 Activity 中数据变化时,调用被观察者数据更新,被观察者会循环遍历注册的观察者进行刷新。

    public class MainActivity extends AppCompatActivity {
    
        private ViewPager viewPager;
        private int count = 0;
    
        private Observable observable;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
    
            viewPager = (ViewPager) findViewById(R.id.viewPager);
            List<Fragment> fragments = new ArrayList<>();
            MyFragment fragment1 = new MyFragment();
            final MyFragment fragment2 = new MyFragment();
            fragments.add(fragment1);
            fragments.add(fragment2);
            viewPager.setAdapter(new MyAdapter(getSupportFragmentManager(), fragments));
    
            // 创建被观察者实例
            observable = new Observable();
            // 注册观察者
            observable.registerObserver(fragment1);
            observable.registerObserver(fragment2);
    
            FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
            fab.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    count = count + 1;
                    if (count == 5) {
                        observable.removeObserver(fragment2);
                    }
                    // 这值传递太爽了,就这么简单,还使 Activity 和 Fragment 实现的高度解耦
                    observable.setState(String.valueOf(count));
                }
            });
        }
    
        class MyAdapter extends FragmentPagerAdapter {
            private List<Fragment> fragments;
            public MyAdapter(FragmentManager fm, List<Fragment> fragments) {
                super(fm);
                this.fragments = fragments;
            }
    
            @Override
            public Fragment getItem(int position) {
                return fragments.get(position);
            }
    
            @Override
            public int getCount() {
                return fragments.size();
            }
        }
    }
    

    总结


    在使用观察者模式中,每个观察者需要被保存到被观察者的集合中,被观察者通过注册添加或移除的方式操作观察者。当被观察者的状态发生改变,通过遍历或循环的方式通知列表中注册的观察者进行更新操作。该模式解耦了观察者和被观察者之间的依赖,使得各自的变化对另一方影响较小。

    相关文章

      网友评论

          本文标题:21_简单使用观察者模式进行值传递

          本文链接:https://www.haomeiwen.com/subject/owxxjxtx.html