擴充卡模式
智者千慮必有一失,愚者千慮必有一得
在我們開發過程中也會經常碰到一些給原有的系統加一些功能,是以不管前期我們呢可行性、需求分析和系統設計處理的多好,随着時間的推移,總會出一些“意外”。是以我們該如何處理掉這些“意外”呢?聰明的程式員們就想到了許多的補救模式,其中擴充卡模式就是補救模式中的一種。這種模式可以能夠讓你從因為業務的快速疊代而引發代碼改變的煩惱中解脫出來。
适配模式的定義
将一個類的接口變換成用戶端所期待的另一種接口,進而使原本因為接口不比對而無法在一起工作的兩個類能夠一起工作
擴充卡模式有三個角色
- Source:需要被适配的接口或者對象,你想把誰轉換成目标角色,那麼這個“誰”就是Source角色
- Target:需要得到的接口或者對象,即适配完Source得到的接口或者對象,我們所期望的接口
- Adapter:擴充卡,協調Source和Target使兩個能夠一起工作。通過繼承或者是類關聯的方式
繼承擴充卡
擴充卡模式有兩種展現形式,一種是通過繼承來表現,一種是通過關聯對象來表現,下面給示範下繼承表現的擴充卡。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcucjZ4EDNidTOiRTNmhTMwIWZ1UmY0EGMjhTMhdDOiZTZfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
擴充卡模式類圖
下面我們寫一個簡單的擴充卡模式的例子,如下所示
Target
接口代碼
interface Target{
public void request();
}
實作了
Target
接口的類
class RealTarget implements Target{
@Override
public void request() {
System.out.println("I am Target");
}
}
Source
源目标類
class Source{
public void doSomething(){
System.out.println("I am Source");
}
}
接下來核心的角色要出現了就是
Adapter
類
class Adapter extends Source implements Target{
@Override
public void request() {
super.doSomething();
}
}
接下來我們可以進行調用試試
public class AdapterTest {
public static void main(String[] args) {
Target target = new RealTarget();
target.request();
Target target2 = new Adapter();
target2.request();
}
}
列印如下
I am Target
I am Source
對象擴充卡
我們上面使用的是通過繼承來使用擴充卡模式,還有一種做法就是将原有的繼承關系變更為關聯關系就可以了。
對象擴充卡和類擴充卡的差別在于:類擴充卡是通過繼承來表現的,而對象擴充卡是對象的合成關系,也可以說是類的關聯關系,這是兩者的根本差別。兩個都會在項目中用到,由于對象擴充卡是通過類間的關聯關系進行耦合的,是以在設計的時候就比較靈活。而類擴充卡隻能通過覆寫源角色的方法進行擴充。是以在實際項目中,對象擴充卡的使用場景比較多。
我們還是先來看一下對象擴充卡的類圖如下
對象擴充卡類圖
然後寫一個通用的例子
現在接口
Target
interface Target2{
public void printSource1();
public void printSource2();
}
然後有
Adapter
class Adapter implements Target{
private Source1 source1;
private Source2 source2;
public Adapter(){
source1 = new Source1();
source2 = new Source2();
}
@Override
public void printSource1() {
source1.print();
}
@Override
public void printSource2() {
source2.print();
}
}
然後兩個
Source
class Source1{
public void print(){
System.out.println("I am Source1");
}
}
class Source2{
public void print(){
System.out.println("I am Source2");
}
}
然後進行調用如下
public static void main(String[] args) {
Target2 target2 = new Adapter2();
target2.printSource1();
target2.printSource2();
}
I am Source1
I am Source2
這樣在以後增加了需求以後,隻需要重新寫擴充卡即可,上層代碼不用動。
擴充卡的優點
- 擴充卡模式可以讓兩個沒有任何關系的類在一起運作,隻要擴充卡這個角色即可。
- 增加了類的透明性:我們通路的是Target目标角色,但是具體的實作都是委托給了源角色,而這些對高層次的子產品是透明的,也是它不需要關心的。
- 提高了類的複用:源角色在原有的系統中還是能夠繼續使用,而在目标角色中也可以充當新的角色。
- 靈活性好:如果某一天突然一個擴充卡不需要了,那麼隻要删除即可,基本上就類似于一個靈活的構件,想用就用。
擴充卡模式的使用場景
擴充卡應用的場景隻需要記住一點就夠了:當你有動機修改一個已經投産中的接口時,擴充卡模式是最适合你的模式。比如系統擴充了,需要使用一個已有或者是建立的類,但是這個類又不符合系統的接口,怎麼辦?這時候就可以使用擴充卡模式。