架构师之路--观察者模式

本文详细介绍了观察者模式,包括其在GUI系统、订阅-发布系统中的应用,以及如何通过观察者模式实现解耦。文章阐述了观察者模式的定义、使用场景,并提供了代码实现示例,特别是通过分析Android的RecyclerView如何使用观察者模式来处理数据更新,展示了观察者模式在实际开发中的应用。
摘要由CSDN通过智能技术生成

目录

介绍

定义

使用场景

代码实现


介绍

     观察者模式是一个使用率非常高的模式,它最常用的地方就是GUI系统、订阅-发布系统,因为这个模式的一个重要作用就是解耦,使得它们之间的依赖性更小,甚至作到毫无依赖,以GUI系统来说,应用的UI具有易变性,尤其是前期随着业务的改变或者产品需求的修改,应用界面也会经常发生变化,但是业务逻辑基本变化不大,此时GUI系统需要一套机制来应对这种情况,使得UI层与具体的业务逻辑解耦,观察者模式此时就派上用场了。

定义

     定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。

使用场景

     1、关联行为场景,需要注意的是,关联行为是可拆分的,而不是组合关系;

     2、事件多级触发场景;

     3、跨系统的消息交换场景,如消息队列、事件总线的处理机制;

代码实现

     在我们的日常工作中,产品需求经常发生变化,只要是合理的变更,我们就需要响应,伪代码模拟一下我们码农如下:

public class Coder implements Observer {

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("收到更新通知");
    }
}

     当我们收到产品的需求变更时,需要及时响应,伪代码模拟的产品如下:

public class Product extends Observable {

    public void change() {
        setChanged();
        notifyObservers();
    }
}

     产品定义的需求变更决策完成,需要打变量时,就需要通知码农去实现,码农和产品关联的过程如下:

public class Test {

    public static void main() {
        Product product = new Product();
        Coder coder1 = new Coder();
        Coder coder2 = new Coder();
        Coder coder3 = new Coder();
        product.addObserver(coder1);
        product.addObserver(coder2);
        product.addObserver(coder3);
        product.change();
    }
}

     当前有三个码农在实现这个需求,所以他们一开始会注册到该产品团队中,产品需求变更时,只需要执行product.change(),所有的码农都会收到变更通知了。

     Android源码中的也有很多地方使用观察者模式,我们来看看RecyclerView中是如何使用观察者模式的,当我们要给RecyclerView设置数据时,调用setAdapter传入一个RecyclerView.Adapter类型的变量,RecyclerView.Adapter类的源码如下:

public abstract static class Adapter<VH extends ViewHolder> {
        private final AdapterDataObservable mObservable = new AdapterDataObservable();
        private boolean mHasStableIds = false;
        private StateRestorationPolicy mStateRestorationPolicy = StateRestorationPolicy.ALLOW;

        /**
         * Called when RecyclerView needs a new {@link ViewHolder} of the given type to represent
         * an item.
         * <p>
         * This new ViewHolder should be constructed with a new View that can represent the items
         * of the given type. You can either create a new View manually or inflate it from an XML
         * layout file.
         * <p>
         * The new ViewHolder will be used to display items of the adapter using
         * {@link #onBindViewHolder(ViewHolder, int, List)}. Since it will be re-used to display
         * different items in the data set, it is a good idea to cache references to sub views of
         * the View to avoid unnecessary {@link View#findViewById(int)} calls.
         *
         * @param parent   The ViewGroup into which the new View will be added after it is bound to
         *                 an adapter position.
         * @param viewType The view type of the new View.
         * @return A new ViewHolder that holds a View of the given view type.
         * @see #getItemViewType(int)
         * @see #onBindViewHolder(ViewHolder, int)
         */
        @NonNull
        public abstract VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType);

        /**
         * Returns the total number of items in the data set held by the adapter.
         *
         * @return The total number of items in this adapter.
         */
        public abstract int getItemCount();

        /**
         * Returns true if this adapter publishes a unique <code>long</code> value that can
         * act as a key for the item at a given position in the data set. If that item is relocated
         * in the data set, the ID returned for that item should be the same.
         *
         * @return true if this adapter's items have stable IDs
         */
        public final boolean hasStableIds() {
            return mHasStableIds;
        }

        /**
         * Called when a view created by this adapter has been detached from its window.
         *
         * <p>Becoming detached from the window is not necessarily a permanent condition;
         * the consumer of an Adapter's views may choose to cache views offscreen while they
         * are not visible, attaching and detaching them as appropriate.</p>
         *
         * @param holder Holder of the view being detached
         */
        public void onViewDetachedFromWindow(@NonNull VH holder) {
        }

        /**
         * Returns true if one or more observers are attached to this adapter.
         *
         * @return true if this adapter has observers
         */
        public final boolean hasObservers() {
            return mObservable.hasObservers();
        }

        /**
         * Register a new observer to listen for data changes.
         *
         * <p>The adapter may publish a variety of events describing specific changes.
         * Not all adapters may support all change types and some may fall back to a generic
         * {@link RecyclerView.AdapterDataObserver#onChanged()
         * "something changed"} event if more specific data is not 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

红-旺永福

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值