1. 寫在前面
在前面的2-6小節(jié)中,我們學(xué)習(xí)了設(shè)計(jì)模式中的創(chuàng)建型模式。其中包括了以下幾種:
-
工廠模式 FactoryMethod:用工廠接口 & 工廠實(shí)現(xiàn)類的方式,將類的實(shí)例化放在子類(工廠實(shí)現(xiàn)類)中完成 -
原型 Sterotype: 用已有的實(shí)例對(duì)象去創(chuàng)建新的對(duì)象。這里涉及到了 deep copy -
生成器 Builder:即分步去組裝。 -
單例 sinlgeton:即一個(gè)類只能有一個(gè)實(shí)例對(duì)象,并且有一個(gè)訪問(wèn)節(jié)點(diǎn)。
整體來(lái)說(shuō),這里的創(chuàng)建型模式還是比較 simple 的。
下面我們來(lái)看一下結(jié)構(gòu)性設(shè)計(jì)模式。
2. 結(jié)構(gòu)類設(shè)計(jì)模式
所謂 結(jié)構(gòu)類設(shè)計(jì)模式 是指通過(guò)各種組合,獲得更靈活的性能、更穩(wěn)定的表現(xiàn)。
盡管
java本身提供了繼承等一些列模式,用以靈活的開發(fā)。但是事實(shí)上還是不夠。
因此,這里有了一系列的結(jié)構(gòu)類設(shè)計(jì)模式
3. 適配器 Adapter
適配器 Adapter 的概念很好理解,生活中也經(jīng)常使用。
本科的時(shí)候玩的單片機(jī)大都是 5V 直流電,而我們的電網(wǎng)都給的是220V交流電,因此我們需要一個(gè)充電器將二者進(jìn)行轉(zhuǎn)換。這個(gè)充電器就叫做 Adapter。
在 java 的世界中也是如此,當(dāng)我們有一個(gè)場(chǎng)景,需要將某一類對(duì)象 統(tǒng)一轉(zhuǎn)成其他類的對(duì)象時(shí),就需要一個(gè) Adapter。
4. 用法
考慮如下一個(gè) case :
我們有一個(gè)實(shí)現(xiàn) Callable 接口的 Task 類:
public class Task implements Callable<Long> {
private long num;
public Task(long num) {
this.num = num;
}
public Long call() throws Exception {
long r = 0;
for (long n = 1; n <= this.num; n++) {
r = r + n;
}
System.out.println("Result: " + r);
return r;
}
}
現(xiàn)在我們想要使用 Thread 的方式開啟一個(gè)線程來(lái)做這個(gè)事情:
Callable<Long> callable = new Task(123450000L);
Thread thread = new Thread(callable); // compile error!
thread.start();
可以看到第二行是編譯不通過(guò)的。因?yàn)?Thread 的方式只接受實(shí)現(xiàn)了 Runnable 接口的類。
這時(shí)候我們就可以整一個(gè) RunnableAdapter, 這個(gè) Adapter 就負(fù)接受一個(gè) callable ,輸出一個(gè) runnable。
這里使用
Adapter而不是直接改寫原來(lái)的Task類,因?yàn)?Task類可能在別的地方使用
這個(gè) RunnableAdapter 接受一個(gè) callable , 返回一個(gè) runnable。
public class RunnableAdapter implements Runnable{
// 引用待轉(zhuǎn)換接口
private Callable<?> callable;
public RunnableAdpater(Callable<> callable){
this.callable = callable;
}
// 實(shí)現(xiàn)指定接口
public void run(){
try{
callable.call();
}catch (Exception e){
throw new RuntimeException(e);
}
}
}
可以看到,這里的適配器其實(shí)做了一層封裝,適配器接收了一個(gè)實(shí)現(xiàn)
Callable的callable對(duì)象,然后自己實(shí)現(xiàn)了Runnable接口,重寫了run()方法,在該方法里實(shí)現(xiàn)了callable對(duì)象的業(yè)務(wù)邏輯。
下面就可以用之前的方式來(lái)做這個(gè)事情了。
Callable<Long> callable = new Task(123450000L);
Thread thread = new Thread(new RunnableAdapter(callable));
thread.start();
5. 總結(jié)
-
Adapter用于將一類對(duì)象轉(zhuǎn)換成為符合某個(gè)標(biāo)準(zhǔn)的另一類對(duì)象 - 實(shí)現(xiàn)分為3步:
(1)接受 A 類對(duì)象
(2)實(shí)現(xiàn)A類對(duì)象的業(yè)務(wù)邏輯
(3)輸出符合某個(gè)標(biāo)準(zhǔn)的B類對(duì)象