设计模式-装饰设计模式

1.定义

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

2.示例

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

/**
 * 项目名称:joke
 * 类描述:可以添加头部和底部的RecyclerView.Adapter
 * 创建人:woochen123
 * 创建时间:2017/10/1 10:52
 */
public class WrapRecyclerAdapter extends RecyclerView.Adapter {
    //原来的adapter
    private RecyclerView.Adapter mRealAdapter;
    //头部
    private ArrayList mHeaderViews;
    //底部
    private ArrayList 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. 代理模式和装饰者模式都会持有原有对象的引用

你可能感兴趣的:(设计模式-装饰设计模式)