@xujun94
2016-07-11T16:05:19.000000Z
字数 6263
阅读 1876
设计模式 在java及Android的 应用
前几天看了鸿洋大神的 Android 优雅的为RecyclerView添加HeaderView和FooterView,发现装饰者模式 在某些情况下是设计得如此 优雅,现在总结如下:
关于观察者设计模式的,可以参考我的这篇博客 观察者设计模式 Vs 事件委托(java)
转载请注明原博客地址: http://blog.csdn.net/gdutxiaoxu/article/details/51885105
Demo下载地址:https://github.com/gdutxiaoxu/Sample_BaseRecyclerAdapter.git
咖啡店里咖啡中可以加不同的配料--摩卡、牛奶、糖、奶泡;不同的饮品加上不同的配料有不同的价钱,怎样实现呢?
可能你的第一印象会想到使用继承,
1. 首先定义一个咖啡基类
2. 对于加糖的,加牛奶的,加摩卡的 ,加奶泡的,分别写一个子类继承
3. 对于加糖,又加奶的写一个类,对于对于加糖,又摩卡的写一个类,对于对于加糖、又奶泡的写一个类,对于加糖,又加奶、摩卡的写一个类----
说到这里,你会发现这里四种配料就要写十几种实现类了,那如果我们的配料是二十几种或者三十几种呢,那么使用继承这种 方式肯定会使我们的子类爆炸,那要怎样解决你,答案就是使用装饰者模式
我觉得装饰者模式是在已有功能的基础之上,动态地添加更多 功能的一种方式,这些新加的代码装饰了原有类的 核心职责或主要行为。


* 1. 首先我们定义一个Coffce基类
/*** @ explain:这里Coffee相当于我们的Component,* 是要装饰的类** @ author:xujun on 2016/7/10 23:16* @ email:gdutxiaoxu@163.com*/public abstract class Coffee {/**** @return 返回价格*/public abstract int getPrice();/*** 返回名字* @return*/public abstract String getName();}
/*** @ explain:* @ author:xujun on 2016/7/10 23:21* @ email:gdutxiaoxu@163.com*/public abstract class Decorator extends Coffee{protected Coffee mCoffee;/*** 通过组合的方式把Coffee对象传递进来* @param coffee*/public Decorator(Coffee coffee){mCoffee=coffee;}}
```* 3. 接下来我们来看我们的子类是怎样实现的```javapublic class MilkDecorator extends Decorator {/*** 通过组合的方式把Coffee对象传递进来** @param coffee*/public MilkDecorator(Coffee coffee) {super(coffee);}@Overridepublic int getPrice() {return mCoffee.getPrice()+10;}@Overridepublic String getName() {return "addMilk";}}<div class="md-section-divider"></div>
其实核心代码就下面一行,在原来的价格加上 加牛奶的价格
return mCoffee.getPrice()+10<div class="md-section-divider"></div>
return mCoffee.getPrice()+2;return mCoffee.getPrice()+15;return mCoffee.getPrice()+20;<div class="md-section-divider"></div>
以后你想要计算加糖,就牛奶,加奶泡的咖啡的价格,只需要这样
mCoffee = new SimpleCoffee();mCoffee = new SugarDecorator(mCoffee);mCoffee = new MilkDecorator(mCoffee);mCoffee = new MilkFoamDecorator(mCoffee);int price1 = mCoffee.getPrice();System.out.println("price1="+price1);<div class="md-section-divider"></div>
以后你想要计算加糖,就牛奶咖啡的价格,只需要这样
mCoffee = new SimpleCoffee();mCoffee = new SugarDecorator(mCoffee);mCoffee = new MilkDecorator(mCoffee);int price1 = mCoffee.getPrice();System.out.println("price1="+price1);<div class="md-section-divider"></div>
前面已经说到,之所以学习装饰者设计模式,是因为看到 鸿洋大神的 博客Android 优雅的为RecyclerView添加HeaderView和FooterView
/*** 博客地址:http://blog.csdn.net/gdutxiaoxu* @author xujun* @time 2016/7/7 17:29.*/public class HeaderAndFooterWrapper<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {private static final int BASE_ITEM_TYPE_HEADER = 100000;private static final int BASE_ITEM_TYPE_FOOTER = 200000;private SparseArrayCompat<View> mHeaderViews = new SparseArrayCompat<>();private SparseArrayCompat<View> mFootViews = new SparseArrayCompat<>();private RecyclerView.Adapter mInnerAdapter;public HeaderAndFooterWrapper(RecyclerView.Adapter adapter) {mInnerAdapter = adapter;}@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {if (mHeaderViews.get(viewType) != null) {ViewHolder holder = ViewHolder.createViewHolder(parent.getContext(), mHeaderViews.get(viewType));return holder;} else if (mFootViews.get(viewType) != null) {ViewHolder holder = ViewHolder.createViewHolder(parent.getContext(), mFootViews.get(viewType));return holder;}return mInnerAdapter.onCreateViewHolder(parent, viewType);}@Overridepublic int getItemViewType(int position) {if (isHeaderViewPos(position)) {return mHeaderViews.keyAt(position);} else if (isFooterViewPos(position)) {return mFootViews.keyAt(position - getHeadersCount() - getRealItemCount());}return mInnerAdapter.getItemViewType(position - getHeadersCount());}private int getRealItemCount() {return mInnerAdapter.getItemCount();}@Overridepublic void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {if (isHeaderViewPos(position)) {return;}if (isFooterViewPos(position)) {return;}mInnerAdapter.onBindViewHolder(holder, position - getHeadersCount());}@Overridepublic int getItemCount() {return getHeadersCount() + getFootersCount() + getRealItemCount();}@Overridepublic void onAttachedToRecyclerView(RecyclerView recyclerView) {WrapperUtils.onAttachedToRecyclerView(mInnerAdapter, recyclerView, new WrapperUtils.SpanSizeCallback() {@Overridepublic int getSpanSize(GridLayoutManager layoutManager, GridLayoutManager.SpanSizeLookup oldLookup, int position) {int viewType = getItemViewType(position);if (mHeaderViews.get(viewType) != null) {return layoutManager.getSpanCount();} else if (mFootViews.get(viewType) != null) {return layoutManager.getSpanCount();}if (oldLookup != null)return oldLookup.getSpanSize(position);return 1;}});}@Overridepublic void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {mInnerAdapter.onViewAttachedToWindow(holder);int position = holder.getLayoutPosition();if (isHeaderViewPos(position) || isFooterViewPos(position)) {WrapperUtils.setFullSpan(holder);}}private boolean isHeaderViewPos(int position) {return position < getHeadersCount();}private boolean isFooterViewPos(int position) {return position >= getHeadersCount() + getRealItemCount();}public void addHeaderView(View view) {mHeaderViews.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER, view);}public void addFootView(View view) {mFootViews.put(mFootViews.size() + BASE_ITEM_TYPE_FOOTER, view);}public int getHeadersCount() {return mHeaderViews.size();}public int getFootersCount() {return mFootViews.size();}}<div class="md-section-divider"></div>
mAdapter = new SinglePersonAdapter(this, mDatas, R.layout.main_chat_from_msg);mHeaderAndFooterWrapper=new HeaderAndFooterWrapper(mAdapter);TextView t1 = new TextView(this);t1.setPadding(10,10,10,10);t1.setBackgroundColor(Color.GRAY);t1.setText("Header 1");TextView t2 = new TextView(this);t2.setText("Header 2");t2.setPadding(10,10,10,10);t2.setBackgroundColor(Color.GRAY);mHeaderAndFooterWrapper.addHeaderView(t1);mHeaderAndFooterWrapper.addHeaderView(t2);mRecyclerView.setAdapter(mHeaderAndFooterWrapper);
是不是很简单,只需要简单的几行代码,就能在原有Adapter的基础之上添加headerView或者Foot而View,具体的代码分析请见鸿洋大神的 博客Android 优雅的为RecyclerView添加HeaderView和FooterView
参考文章Android 优雅的为RecyclerView添加HeaderView和FooterView
关于观察者设计模式的,可以参考我的这篇博客 观察者设计模式 Vs 事件委托(java)
转载请注明原博客地址: http://blog.csdn.net/gdutxiaoxu/article/details/51885105
Demo下载地址:https://github.com/gdutxiaoxu/Sample_BaseRecyclerAdapter.git