一山卦,裝飾者模式
總結:裝飾者模式哮独,就是對于父類A(Component)烟央,子類 B(ConcreteComponent)和C(Decorator)分別重新A中的方法,B中對方法進行實現(xiàn)瞒渠,C及其子類可以調用B中實現(xiàn)的方法良蒸,也可以進行方法的拓展
二,代理模式
可以查看這篇文章伍玖,http://blog.csdn.net/luanlouis/article/details/24589193
https://www.zhihu.com/question/20794107
作者:雨夜偷牛的人
鏈接:https://www.zhihu.com/question/20794107/answer/23330381
來源:知乎
著作權歸作者所有嫩痰,轉載請聯(lián)系作者獲得授權。
最近正好在看窍箍,特來挖墳串纺。
關于動態(tài)代理設計模式很可能題主就在不知不覺中使用了丽旅,例如Spring中的AOP,Struts2中的攔截器等造垛。
先來看靜態(tài)代理模式代碼:
package test;
public interface Subject
{
public void doSomething();
}
package test;
public class RealSubject implements Subject
{
public void doSomething()
{
System.out.println( "call doSomething()" );
}
}
package test;
public class SubjectProxy implements Subject
{
Subject subimpl = new RealSubject();
public void doSomething()
{
subimpl.doSomething();
}
}
package test;
public class TestProxy
{
public static void main(String args[])
{
Subject sub = new SubjectProxy();
sub.doSomething();
}
}
剛開始我會覺得SubjectProxy定義出來純屬多余,直接實例化實現(xiàn)類完成操作不就結了嗎晰搀?后來隨著業(yè)務龐大五辽,你就會知道,實現(xiàn)proxy類對真實類的封裝對于粒度的控制有著重要的意義外恕。但是靜態(tài)代理這個模式本身有個大問題杆逗,如果類方法數量越來越多的時候,代理類的代碼量是十分龐大的鳞疲。所以引入動態(tài)代理來解決此類問題罪郊。
先看代碼:
package test;
public interface Subject
{
public void doSomething();
}
package test;
public class RealSubject implements Subject
{
public void doSomething()
{
System.out.println( "call doSomething()" );
}
}
package test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyHandler implements InvocationHandler
{
private Object tar;
//綁定委托對象,并返回代理類
public Object bind(Object tar)
{
this.tar = tar;
//綁定該類實現(xiàn)的所有接口尚洽,取得代理類
return Proxy.newProxyInstance(tar.getClass().getClassLoader(),
tar.getClass().getInterfaces(),
this);
}
public Object invoke(Object proxy , Method method , Object[] args)throws Throwable
{
Object result = null;
//這里就可以進行所謂的AOP編程了
//在調用具體函數方法前悔橄,執(zhí)行功能處理
result = method.invoke(tar,args);
//在調用具體函數方法后,執(zhí)行功能處理
return result;
}
}
public class TestProxy
{
public static void main(String args[])
{
ProxyHandler proxy = new ProxyHandler();
//綁定該類實現(xiàn)的所有接口
Subject sub = (Subject) proxy.bind(new RealSubject());
sub.doSomething();
}
}
看完代碼腺毫,現(xiàn)在我來回答癣疟,動態(tài)代理的作用是什么:
- Proxy類的代碼量被固定下來,不會因為業(yè)務的逐漸龐大而龐大潮酒;
- 可以實現(xiàn)AOP編程睛挚,實際上靜態(tài)代理也可以實現(xiàn),總的來說急黎,AOP可以算作是代理模式的一個典型應用扎狱;
- 解耦,通過參數就可以判斷真實類勃教,不需要事先實例化淤击,更加靈活多變。
三故源,工廠模式
http://blog.csdn.net/jason0539/article/details/23020989
工廠模式分為簡單工廠模式遭贸,工廠方法模式和抽象工廠模式
簡單工廠就是利用factory類創(chuàng)建對象,
抽象工廠是用多個factory創(chuàng)建對象心软,
四壕吹,原型模式
http://blog.csdn.net/sbsujjbcy/article/details/49302717
五,模板方法模式
在Android源碼中删铃,View中的Draw()方法就是一個“模板方法”耳贬。它定義了一系列“Draw”過程,主要包括這幾個步驟(截取自源代碼):
/*
* Draw traversal performs several drawing steps which must be executed
* in the appropriate order:
*
* 1. Draw the background
* 2. If necessary, save the canvas' layers to prepare for fading
* 3. Draw view's content
* 4. Draw children
* 5. If necessary, draw the fading edges and restore layers
* 6. Draw decorations (scrollbars for instance)
*/
在view類的draw()函數中調用了onDraw和dispatchDraw函數猎唁,當繼承View子類中咒劲,如果要重寫或者擴展這個方法時,整個方法流程和基本內容不能夠修改,子類只能通過擴展onDraw(Canvas canvas)和dispatchDraw(Canvas canvas)兩個函數腐魂,使子類自己的View顯示效果和別的具體子類的不同≌寿耍現(xiàn)在來看看繼承自View類的具體子類如何擴展Draw()模板方法顯示自己的與眾不同:
TextView類中重寫了OnDraw函數,SurfaceView重寫了dispatchDraw()函數蛔屹,ViewGroup類重寫了dispatchDraw()函數削樊。
根據模版方法中的方法,可以分為兩大類:模版方法(Template Method)和基本方法(Primitive Method)兔毒。其中我們這里的例子Draw()函數就是一個“模板方法”漫贞。
而基本方法又可以分為三種:抽象方法(Abstract Method)、具體方法(Concrete Method)和鉤子方法(Hook Method):
抽象方法:一個抽象方法由抽象類聲明育叁,由具體子類實現(xiàn)迅脐。
具體方法:一個具體方法由抽象類聲明并實現(xiàn),而子類并不實現(xiàn)或置換豪嗽。
鉤子方法:一個鉤子方法由抽象類聲明并實現(xiàn)谴蔑,而子類會加以擴展。我們這里的onDraw()函數就是一個鉤子方法龟梦。
六树碱,外觀模式
就是多了層封裝,SDK常用到
七变秦,build模式
建造(Builder)模式是一種對象構建的設計模式成榜,它可以將復雜對象的建造過程抽象出來(抽象類別),使這個抽象過程的不同實現(xiàn)方法可以構造出不同表現(xiàn)(屬性)的對象蹦玫。
在沒有運用構造模式之前赎婚,我們可能會使用構造方法還設置初始化對象時候的參數,但是有了build模式樱溉,就可以通過build來進行選擇性的傳參并實例化對象挣输。例如,Android常用的第三方請求網絡庫okhttp福贞,
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.build();
OkHttpClient類中該方法如下撩嚼,
public Builder() {
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
connectionSpecs = DEFAULT_CONNECTION_SPECS;
proxySelector = ProxySelector.getDefault();
cookieJar = CookieJar.NO_COOKIES;
socketFactory = SocketFactory.getDefault();
hostnameVerifier = OkHostnameVerifier.INSTANCE;
certificatePinner = CertificatePinner.DEFAULT;
proxyAuthenticator = Authenticator.NONE;
authenticator = Authenticator.NONE;
connectionPool = new ConnectionPool();
dns = Dns.SYSTEM;
followSslRedirects = true;
followRedirects = true;
retryOnConnectionFailure = true;
connectTimeout = 10_000;
readTimeout = 10_000;
writeTimeout = 10_000;
}
八 ,觀察者模式
觀察者模式的底層其實是回調挖帘,Java中一般可以繼承Observable 和Observer來實現(xiàn)被觀察者和觀察者完丽,在安卓中,更是運用大量的觀察者模式拇舀,例如逻族,BaseAdapter關聯(lián)了一個DataSetObservable對象,并實現(xiàn)registerDataSetObserver和unregisterDataSetObserver兩個方法實現(xiàn)注冊和撤銷Observer骄崩,方法notifyDataSetChanged間接調用Observer的實現(xiàn)者的onChange()方法聘鳞,以達到通知數據改變的作用薄辅。使用ListView和BaseAdapter組合時,當BaseAdapter的item改變時抠璃,我們經常會調用notifyDataSetChanged()站楚,通知Listview刷新。
public abstract class DataSetObserver {
/**
* This method is called when the entire data set has changed,
* most likely through a call to {@link Cursor#requery()} on a {@link Cursor}.
*/
public void onChanged() {
// Do nothing
}
/**
* This method is called when the entire data becomes invalid,
* most likely through a call to {@link Cursor#deactivate()} or {@link Cursor#close()} on a
* {@link Cursor}.
*/
public void onInvalidated() {
// Do nothing
}
}
public abstract class Observable<T> {
/**
* The list of observers. An observer can be in the list at most
* once and will never be null.
*/
protected final ArrayList<T> mObservers = new ArrayList<T>();
/**
* Adds an observer to the list. The observer cannot be null and it must not already
* be registered.
* @param observer the observer to register
* @throws IllegalArgumentException the observer is null
* @throws IllegalStateException the observer is already registered
*/
public void registerObserver(T observer) {
if (observer == null) {
throw new IllegalArgumentException("The observer is null.");
}
synchronized(mObservers) {
if (mObservers.contains(observer)) {
throw new IllegalStateException("Observer " + observer + " is already registered.");
}
mObservers.add(observer);
}
}
/**
* Removes a previously registered observer. The observer must not be null and it
* must already have been registered.
* @param observer the observer to unregister
* @throws IllegalArgumentException the observer is null
* @throws IllegalStateException the observer is not yet registered
*/
public void unregisterObserver(T observer) {
if (observer == null) {
throw new IllegalArgumentException("The observer is null.");
}
synchronized(mObservers) {
int index = mObservers.indexOf(observer);
if (index == -1) {
throw new IllegalStateException("Observer " + observer + " was not registered.");
}
mObservers.remove(index);
}
}
/**
* Remove all registered observers.
*/
public void unregisterAll() {
synchronized(mObservers) {
mObservers.clear();
}
}
}
可以看出搏嗡,觀察者并不一定要繼承JDK中的Observable 和Observer窿春。