美文网首页
设计模式-装饰设计模式

设计模式-装饰设计模式

作者: woochen123 | 来源:发表于2017-10-01 12:39 被阅读0次

    1.定义

    在不使用的继承的方式下,采用装饰设计模式可以扩展一个对象的功能,可以使一个对象变得越来越强大。(通常做法是将需要扩展的对象作为参数传入新类中进行功能的扩展)

    2.示例

    recycleview默认不支持头部和底部的添加,使用装饰模式进行功能扩展

    /**
     * 项目名称:joke
     * 类描述:可以添加头部和底部的RecyclerView.Adapter
     * 创建人:woochen123
     * 创建时间:2017/10/1 10:52
     */
    public class WrapRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
        //原来的adapter
        private RecyclerView.Adapter mRealAdapter;
        //头部
        private ArrayList<View> mHeaderViews;
        //底部
        private ArrayList<View> mFooterViews;
    
        public WrapRecyclerAdapter(RecyclerView.Adapter realAdapter) {
            this.mRealAdapter = realAdapter;
            mHeaderViews = new ArrayList<>();
            mFooterViews = new ArrayList<>();
            //当真正的适配器数据改变时,通知包裹后的适配器进行数据的更新
            mRealAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
                @Override
                public void onChanged() {
                    notifyDataSetChanged();
                }
            });
        }
    
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
            int numHeader = mHeaderViews.size();
            if (position < numHeader) {
                return new ExtraViewViewHolder(mHeaderViews.get(position));
            }
            int realAdapterPosition = position - numHeader;
            int realAdapterCount = 0;
            if (mRealAdapter != null) {
                realAdapterCount = mRealAdapter.getItemCount();
                if (realAdapterPosition < realAdapterCount) {
                    return mRealAdapter.onCreateViewHolder(parent, mRealAdapter.getItemViewType(realAdapterPosition));
                }
            }
            return new ExtraViewViewHolder(mHeaderViews.get(realAdapterPosition - realAdapterCount));
        }
    
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            int numHeader = mHeaderViews.size();
            if (position < numHeader) {
                return;
            }
            int realAdapterPosition = position - numHeader;
            int realAdapterCount = 0;
            if (mRealAdapter != null) {
                realAdapterCount = mRealAdapter.getItemCount();
                if (realAdapterPosition < realAdapterCount) {
                    mRealAdapter.onBindViewHolder(holder, realAdapterPosition);
                }
            }
        }
    
        @Override
        public int getItemViewType(int position) {
            return position;
        }
    
        @Override
        public int getItemCount() {
            return mHeaderViews.size() + mRealAdapter.getItemCount() + mFooterViews.size();
        }
    
        static class ExtraViewViewHolder extends RecyclerView.ViewHolder {
    
            public ExtraViewViewHolder(View itemView) {
                super(itemView);
            }
        }
    
    
        /**
         * 添加底部View
         * @param view
         */
        public void addFooterView(View view) {
            if (!mFooterViews.contains(view)) {
                mFooterViews.add(view);
                notifyDataSetChanged();
            }
        }
    
        /**
         * 添加头部View
         * @param view
         */
        public void addHeaderView(View view) {
            if (!mHeaderViews.contains(view)) {
                mHeaderViews.add(view);
                notifyDataSetChanged();
            }
        }
    
        /**
         * 移除底部View
         * @param view
         */
        public void removeFooterView(View view) {
            if (!mFooterViews.contains(view)) {
                mFooterViews.remove(view);
                notifyDataSetChanged();
            }
        }
    
        /**
         * 移除头部View
         * @param view
         */
        public void removeHeaderView(View view) {
            if (!mHeaderViews.contains(view)) {
                mHeaderViews.remove(view);
                notifyDataSetChanged();
            }
        }
    
    

    3.源码中的应用

    ListView的adapter,ContextWrapper,io的输入输出流

    4.总结

    1. 装饰者模式是继承的一种替代方案
    2. 代理模式是对一个或一组对象进行控制,而装饰者模式是对原有对象的功能进行增强
    3. 代理模式和装饰者模式都会持有原有对象的引用

    相关文章

      网友评论

          本文标题:设计模式-装饰设计模式

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