一,裝飾者模式
總結(jié):裝飾者模式,就是對(duì)于父類A(Component),子類 B(ConcreteComponent)和C(Decorator)分別重新A中的方法,B中對(duì)方法進(jìn)行實(shí)現(xiàn),C及其子類可以調(diào)用B中實(shí)現(xiàn)的方法,也可以進(jìn)行方法的拓展
二,代理模式
可以查看這篇文章,http://blog.csdn.net/luanlouis/article/details/24589193
https://www.zhihu.com/question/20794107
作者:雨夜偷牛的人
鏈接:https://www.zhihu.com/question/20794107/answer/23330381
來源:知乎
著作權(quán)歸作者所有,轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)。
最近正好在看,特來挖墳。
關(guān)于動(dòng)態(tài)代理設(shè)計(jì)模式很可能題主就在不知不覺中使用了,例如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();
}
}
剛開始我會(huì)覺得SubjectProxy定義出來純屬多余,直接實(shí)例化實(shí)現(xiàn)類完成操作不就結(jié)了嗎?后來隨著業(yè)務(wù)龐大,你就會(huì)知道,實(shí)現(xiàn)proxy類對(duì)真實(shí)類的封裝對(duì)于粒度的控制有著重要的意義。但是靜態(tài)代理這個(gè)模式本身有個(gè)大問題,如果類方法數(shù)量越來越多的時(shí)候,代理類的代碼量是十分龐大的。所以引入動(dòng)態(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;
//綁定委托對(duì)象,并返回代理類
public Object bind(Object tar)
{
this.tar = tar;
//綁定該類實(shí)現(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;
//這里就可以進(jìn)行所謂的AOP編程了
//在調(diào)用具體函數(shù)方法前,執(zhí)行功能處理
result = method.invoke(tar,args);
//在調(diào)用具體函數(shù)方法后,執(zhí)行功能處理
return result;
}
}
public class TestProxy
{
public static void main(String args[])
{
ProxyHandler proxy = new ProxyHandler();
//綁定該類實(shí)現(xiàn)的所有接口
Subject sub = (Subject) proxy.bind(new RealSubject());
sub.doSomething();
}
}
看完代碼,現(xiàn)在我來回答,動(dòng)態(tài)代理的作用是什么:
- Proxy類的代碼量被固定下來,不會(huì)因?yàn)闃I(yè)務(wù)的逐漸龐大而龐大;
- 可以實(shí)現(xiàn)AOP編程,實(shí)際上靜態(tài)代理也可以實(shí)現(xiàn),總的來說,AOP可以算作是代理模式的一個(gè)典型應(yīng)用;
- 解耦,通過參數(shù)就可以判斷真實(shí)類,不需要事先實(shí)例化,更加靈活多變。
三,工廠模式
http://blog.csdn.net/jason0539/article/details/23020989
工廠模式分為簡單工廠模式,工廠方法模式和抽象工廠模式
簡單工廠就是利用factory類創(chuàng)建對(duì)象,
抽象工廠是用多個(gè)factory創(chuàng)建對(duì)象,
四,原型模式
http://blog.csdn.net/sbsujjbcy/article/details/49302717
五,模板方法模式
在Android源碼中,View中的Draw()方法就是一個(gè)“模板方法”。它定義了一系列“Draw”過程,主要包括這幾個(gè)步驟(截取自源代碼):
/*
* 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()函數(shù)中調(diào)用了onDraw和dispatchDraw函數(shù),當(dāng)繼承View子類中,如果要重寫或者擴(kuò)展這個(gè)方法時(shí),整個(gè)方法流程和基本內(nèi)容不能夠修改,子類只能通過擴(kuò)展onDraw(Canvas canvas)和dispatchDraw(Canvas canvas)兩個(gè)函數(shù),使子類自己的View顯示效果和別的具體子類的不同。現(xiàn)在來看看繼承自View類的具體子類如何擴(kuò)展Draw()模板方法顯示自己的與眾不同:
TextView類中重寫了OnDraw函數(shù),SurfaceView重寫了dispatchDraw()函數(shù),ViewGroup類重寫了dispatchDraw()函數(shù)。
根據(jù)模版方法中的方法,可以分為兩大類:模版方法(Template Method)和基本方法(Primitive Method)。其中我們這里的例子Draw()函數(shù)就是一個(gè)“模板方法”。
而基本方法又可以分為三種:抽象方法(Abstract Method)、具體方法(Concrete Method)和鉤子方法(Hook Method):
抽象方法:一個(gè)抽象方法由抽象類聲明,由具體子類實(shí)現(xiàn)。
具體方法:一個(gè)具體方法由抽象類聲明并實(shí)現(xiàn),而子類并不實(shí)現(xiàn)或置換。
鉤子方法:一個(gè)鉤子方法由抽象類聲明并實(shí)現(xiàn),而子類會(huì)加以擴(kuò)展。我們這里的onDraw()函數(shù)就是一個(gè)鉤子方法。
六,外觀模式
就是多了層封裝,SDK常用到
七,build模式
建造(Builder)模式是一種對(duì)象構(gòu)建的設(shè)計(jì)模式,它可以將復(fù)雜對(duì)象的建造過程抽象出來(抽象類別),使這個(gè)抽象過程的不同實(shí)現(xiàn)方法可以構(gòu)造出不同表現(xiàn)(屬性)的對(duì)象。
在沒有運(yùn)用構(gòu)造模式之前,我們可能會(huì)使用構(gòu)造方法還設(shè)置初始化對(duì)象時(shí)候的參數(shù),但是有了build模式,就可以通過build來進(jìn)行選擇性的傳參并實(shí)例化對(duì)象。例如,Android常用的第三方請(qǐng)求網(wǎng)絡(luò)庫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;
}
八 ,觀察者模式
觀察者模式的底層其實(shí)是回調(diào),Java中一般可以繼承Observable 和Observer來實(shí)現(xiàn)被觀察者和觀察者,在安卓中,更是運(yùn)用大量的觀察者模式,例如,BaseAdapter關(guān)聯(lián)了一個(gè)DataSetObservable對(duì)象,并實(shí)現(xiàn)registerDataSetObserver和unregisterDataSetObserver兩個(gè)方法實(shí)現(xiàn)注冊(cè)和撤銷Observer,方法notifyDataSetChanged間接調(diào)用Observer的實(shí)現(xiàn)者的onChange()方法,以達(dá)到通知數(shù)據(jù)改變的作用。使用ListView和BaseAdapter組合時(shí),當(dāng)BaseAdapter的item改變時(shí),我們經(jīng)常會(huì)調(diào)用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。