適配器模式


一、生活中的扳手

  假設我們在平時的工作中一直用12mm的扳手,如下圖所示:

  

突然有一天,我們要操作24mm的螺絲....

這時,我們會想到三種解決方案:

1,再重新采購一個24mm的扳手,以適應新的需求

2,讓對方的廠家螺絲變小,由24mm變為12mm以適應我們的扳手....這個解決方案看起來相當扯淡...

3,增加一個12mm與24mm的“扳手適配器”..把這個適配器“套在”我們已有的12mm扳手上,以使用這個適配器的另一端的24mm的接口。

基於我們可控制的條件來考慮,讓產商把所有的24mm螺絲改成12mm的螺絲是不可能的,所以我們只能在第一種和第二種方案中來選擇解決方案,然后我們再從成本上分析[在軟件中主要指人力成本,應對需求變化時所花費的成本],方案一固然也可以解決問題,但是一個新的扳手價格在45元左右,同樣,如果采用了方案3,一個“扳手適配器”也能解決我們的問題,但成本只有10元左右,從倍數的角度來看,我們解決同樣的問題,方案3相比方案1節省了3倍左右的金錢。

二、程序中的扳手

 1,12mm扳手正常工作的情況下:

 1     /// <summary>
 2     /// 12mm的螺絲
 3     /// </summary>
 4     public class Screws_12mm
 5     {
 6         public string Turn()
 7         {
 8             return "12mm的螺絲在轉動...";
 9         }
10     }
11     /// <summary>
12     /// 12mm的扳手
13     /// </summary>
14     public class Wrench_12mm
15     {
16         Screws_12mm screwms;
17 
18         public string Work()
19         {
20             screwms = new Screws_12mm();
21             return screwms.Turn();
22         }
23     }
24     /// <summary>
25     /// 使用
26     /// </summary>
27     class Program
28     {
29         static void Main(string[] args)
30         {
31             //使用12mm的扳手
32             Wrench_12mm wrench = new Wrench_12mm();
33             Console.WriteLine(wrench.Work());
34             Console.Read();
35         }
36     }

類圖:

2,接口有變化,突然來了個24mm的螺絲,我們此時采用第三種解決方案,引入“扳手適配器”,

代碼:

 1     /// <summary>
 2     /// 24mm的螺絲
 3     /// </summary>
 4     public class Screws_24mm
 5     {
 6         public string Turn()
 7         {
 8             return "24mm的螺絲在轉動...";
 9         }
10     }
11     /// <summary>
12     /// 12mm的扳手
13     /// </summary>
14     public class Wrench_12mm
15     {
16         Screws_12mm screwms;
17 
18         public virtual string Work()
19         {
20             screwms = new Screws_12mm();
21             return screwms.Turn();
22         }
23     }
24     /// <summary>
25     /// 適配器
26     /// </summary>
27     public class Adapter : Wrench_12mm
28     {
29         Screws_24mm screws;
30         public override string Work()
31         {
32             screws = new Screws_24mm();
33             return screws.Turn();
34         }
35     }
36     /// <summary>
37     /// 使用
38     /// </summary>
39     class Program
40     {
41         static void Main(string[] args)
42         {
43             //使用12mm的扳手和適配器
44             Wrench_12mm wrench = new Adapter();
45             Console.WriteLine(wrench.Work());
46             Console.Read();
47         }
48     }

 

類圖:

三、適配器模式

適配器模式(英語:adapter pattern)有時候也稱包裝樣式或者包裝。將一個類的接口轉接成用戶所期待的。一個適配使得因接口不兼容而不能在一起工作的類工作在一起,做法是將類別自己的接口包裹在另一個類中。

在系統的“數據”與“行為”都正確,但是接口不同時,我們應該考慮使用適配器模式。

四、應用場景

“亡羊補牢”:像上面的例子一樣,本來我們一直對應的是12mm螺絲的工作,在設計之初並沒有想到我們會使用到24mm螺絲。此時,我們會使用適配器模式以補充不足。

在軟件維護的過程中,有時出現了新的接口,但是修改已往的代碼風險又很大,又不能要求接口改變,此時我們考慮應用"Adapter模式"。

“預先設計”:在設計之初,就有明顯的需求於預視到“要應對於不同的接口”,我們仍然以扳手為例,如下圖所示:

除非有明確的需求,否則不建議預先使用適配器模式,如上圖,我們買了個大包裝的“扳手套裝”,在其中我們能到幾個呢?到目前我們可能只用到了12mm與24mm這兩個,同時在設計之初,我們並不確定是否可以用到24mm的扳手,謹防“過渡設計”。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM