生活随笔
收集整理的這篇文章主要介紹了
装饰者模式及其应用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
我的公眾號程序員徐公,四年中大廠工作經驗,回復黑馬,領取 Android 學習視頻一份,回復徐公666,可以獲得我精心整理的簡歷模板,帶你走近大廠。
前言
前幾天看了鴻洋大神的 Android 優雅的為RecyclerView添加HeaderView和FooterView,發現裝飾者模式 在某些情況下是設計得如此優雅,現在總結如下:
本篇博客主要講解一下幾個問題
什么 是裝飾者模式怎樣實現裝飾者模式裝飾者模式的優缺點裝飾者模式在Android中的應用
關于觀察者設計模式的,可以參考我的這篇博客 觀察者設計模式 Vs 事件委托(java)
轉載請注明原博客地址: http://blog.csdn.net/gdutxiaoxu/article/details/51885105
Demo下載地址:https://github.com/gdutxiaoxu/Sample_BaseRecyclerAdapter.git
覺得不錯的可以關注一下我的微信公眾號哦,定時發布干貨
什么是裝飾者模式
應用場景
咖啡店里咖啡中可以加不同的配料–摩卡、牛奶、糖、奶泡;不同的飲品加上不同的配料有不同的價錢,怎樣實現呢?
可能你的第一印象會想到使用繼承,
首先定義一個咖啡基類對于加糖的,加牛奶的,加摩卡的 ,加奶泡的,分別寫一個子類繼承對于加糖,又加奶的寫一個類,對于對于加糖,又摩卡的寫一個類,對于對于加糖、又奶泡的寫一個類,對于加糖,又加奶、摩卡的寫一個類----
說到這里,你會發現這里四種配料就要寫十幾種實現類了,那如果我們的配料是二十幾種或者三十幾種呢,那么使用繼承這種 方式肯定會使我們的子類爆炸,那要怎樣解決你,答案就是使用裝飾者模式
定義
我覺得裝飾者模式是在已有功能的基礎之上,動態地添加更多 功能的一種方式,這些新加的代碼裝飾了原有類的 核心職責或主要行為。
類UML圖
效果圖
怎樣實現裝飾者模式呢?
首先我們先來看一下我們的設計類圖
public abstract class Coffee {public abstract int getPrice();public abstract String getName();
}
- 2) 接著 我們定義一個Decorator類繼承 我們的Coffice基類
public abstract class Decorator extends Coffee{protected Coffee mCoffee
;public Decorator(Coffee coffee
){mCoffee
=coffee
;}
}
public class MilkDecorator extends Decorator {public MilkDecorator(Coffee coffee
) {super(coffee
);}@Overridepublic int getPrice() {return mCoffee
.getPrice()+10;}@Overridepublic String getName() {return "addMilk";}
}
其實核心代碼就下面一行,在原來的價格加上 加牛奶的價格
return mCoffee
.getPrice()+10
- 4)接下來不難想象加糖,就奶泡。就摩卡的操作,都是在原來的之上加上配料的價格
return mCoffee
.getPrice()+2;
return mCoffee
.getPrice()+15;
return mCoffee
.getPrice()+20;
總結
以后你想要計算加糖,就牛奶,加奶泡的咖啡的價格,只需要這樣
mCoffee
= new SimpleCoffee();
mCoffee
= new SugarDecorator(mCoffee
);
mCoffee
= new MilkDecorator(mCoffee
);
mCoffee
= new MilkFoamDecorator(mCoffee
);
int price1
= mCoffee
.getPrice();
System.out
.println("price1="+price1
);
以后你想要計算加糖,就牛奶咖啡的價格,只需要這樣
mCoffee
= new SimpleCoffee();
mCoffee
= new SugarDecorator(mCoffee
);
mCoffee
= new MilkDecorator(mCoffee
);int price1
= mCoffee
.getPrice();
System.out
.println("price1="+price1
);
裝飾者模式的優缺點
優點
- 把類中的裝飾功能從類中搬除,可以簡化原來的類
- 可以把類的 核心職責和裝飾功能區分開來,結構清晰 明了并且可以去除相關類的重復的裝飾邏輯。
裝飾者模式在Android中的應用
效果圖
前面已經說到,之所以學習裝飾者設計模式,是因為看到 鴻洋大神的 博客Android 優雅的為RecyclerView添加HeaderView和FooterView
- 下面我們來看一下我們是如何 優雅的為RecyclerView添加HeaderView和FooterView
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();}}
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
相關推薦
Android 啟動優化(一) - 有向無環圖
Android 啟動優化(二) - 拓撲排序的原理以及解題思路
Android 啟動優化(三)- AnchorTask 開源了
Android 啟動優化(四)- AnchorTask 是怎么實現的
Android 啟動優化(五)- AnchorTask 1.0.0 版本正式發布了
Android 啟動優化(六)- 深入理解布局優化
這篇文章,加上一些 Demo,足足花了我幾個晚上的時間,覺得不錯的話可以關注一下我的微信公眾號程序員徐公,小弟在此感謝各位大佬們。主要分享
Android 開發相關的知識,包括 java,kotlin, Android 技術面試相關的東西,包括常見的面試題目,面試經驗分享算法相關的知識,比如怎么學習算法,leetcode 常見算法總結一些時事點評,主要是關于互聯網的,比如小米高管屌絲事件,拼多多女員工猝死事件等
源碼地址:https://github.com/gdutxiaoxu/AnchorTask
總結
以上是生活随笔為你收集整理的装饰者模式及其应用的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。