通俗易懂設計模式解析——介面卡模式
前言
前面完成了建立型的設計模式的分享,建立型的設計模式解決的是物件建立的問題。今天開始介紹結構型的設計模式,其中結構型設計模式包括:介面卡模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。結構型設計模式解決的是類與物件的組合關係。今天講結構型物件中的第一個——介面卡模式。介面卡模式——顧名思義嘛。在我們平常的理解中,介面卡是幹啥用的呢?不就是將兩個原本不匹配的東西轉換為匹配罷了。介面卡是介面轉換器,比如電源介面卡,USB介面轉換器等等。
介面卡模式介紹
一、來由
在系統程式中,我們可能會面臨需求的增加或者改變,或者是應用環境的改變。常常需要將一些已經存在的類放在新的需求或者新的環境中應用。但是新的環境要求使用到的介面與現在存在的類或物件不完全匹配。那麼如何去面對這樣的遷移變化呢?
二、意圖
將一個類的介面轉換成客戶希望的另一個介面。Adapter模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。
三、案例圖
四、介面卡模式程式碼示例
在介面卡模式中一般包含以下部分的存在:
客戶端:與目標介面配合協同使用
目標介面:與客戶端協同使用
被適配角色:表示一個已經存在了並使用的介面
介面卡:整個模式核心存在,將被適配角色轉換為目標需要的介面。
接下來我們看下這個示例,前段時間筆記本那個耳機圓孔介面壞掉了。這個時候我只有手機那種圓孔耳機。但是我也需要在電腦上面使用,那怎麼辦呢?我不想多花錢去買一個usb耳機,也沒有時間去把電腦修好。簡單、我去網上買一個耳機的Usb轉換器。然後就可以在電腦上使用了。在這事例中,目標介面是電腦USB耳機,被適配角色是手機圓孔耳機,介面卡就是圓孔耳機轉換為USB的過程、電腦則是客戶端:
namespace Adapter_Pattern { class AdapterPattern { } #region 目標角色——需要電腦usb耳機========================= /// <summary> /// 客戶端需要的介面 /// </summary> interface ComputerHeadsetTarget { void GetComputerHeadset(); } #endregion #region 被適配角色——現在存在的手機耳機===================== /// <summary> /// 目前已經存在的介面 /// </summary> public class Adaptee { public void PhoneHeadset() { Console.WriteLine("我現在擁有的是手機耳機。"); } } #endregion #region 物件介面卡——將手機耳機轉換成電腦需要的usb耳機========== /// <summary> /// 物件介面卡實現 /// </summary> public class ObjectAdapter : ComputerHeadsetTarget { Adaptee Adaptee = new Adaptee(); public void GetComputerHeadset() { Adaptee.PhoneHeadset(); Console.WriteLine("現在加入耳機Usb轉換器"); Console.WriteLine("輸出:電腦使用的usb耳機"); } } #endregion #region 類介面卡——將手機耳機轉換成電腦需要的usb耳機=========== /// <summary> /// 類介面卡的實現 /// </summary> public class ClassAdapter : Adaptee,ComputerHeadsetTarget { public void GetComputerHeadset() { this.PhoneHeadset(); Console.WriteLine("現在加入耳機Usb轉換器"); Console.WriteLine("輸出:電腦使用的usb耳機"); } } #endregion }
class Program { static void Main(string[] args) { Console.WriteLine("我現在需要電腦usb耳機"); ///物件介面卡 ObjectAdapter objectAdapter = new ObjectAdapter(); objectAdapter.GetComputerHeadset(); Console.WriteLine("我現在需要電腦usb耳機"); ///類介面卡 ClassAdapter classAdapter = new ClassAdapter(); classAdapter.GetComputerHeadset(); Console.ReadLine(); } }
使用場景及優缺點
這介面卡模式主要用於一些希望被複用的類,但是這些類中的介面又與新的環境不完全匹配的情況下。老程式碼遺留修改中、類庫遷移中用處較多。
在上面示例中寫了介面卡的兩種實現方式,物件介面卡和類介面卡。對於類介面卡來說既繼承了目標介面類又繼承了已存在介面類。在C#程式設計中儘量採用多組合少繼承的形式進行程式碼編寫。多繼承提高了類之間的耦合性。所以對於類介面卡一般情況儘量少使用。而對於物件介面卡來說採用的是物件組合的方式。
一、使用場景
1、系統需要複用現在的類,但是類中介面與現在環境不完全匹配
2、想要建立一個可以複用的類,用於彼此之間沒有太大關聯的一些類。
二、優點
物件介面卡:
1、可以再不修改原來的類的基礎上覆用原來的類,符合開閉原則
2、採用的”物件組合”,降低類之間的耦合性
類介面卡:
1、可以再不修改原來的類的基礎上覆用原來的類,符合開閉原則
2、可以重新定義被適配角色類中一部分行為,在類介面卡中被適配角色類為基類
3、僅是引用一個物件,不需要額外的欄位引用例項
三、缺點
物件介面卡:
1、重新定義被適配角色類中部分行為困難
類介面卡:
1、對於被適配角色類的子類中的一些方法就不能進行轉換了,因為沒有引用其例項,僅繼承基類。所以只能呼叫基類中的方法。
2、採用了多繼承的方式。提高了類之間的耦合性
總結
大家會不會覺得Adapter這個單詞這麼熟悉呢?我剛看的時候也覺得蠻熟悉的樣子。應該大多數人都寫過DBHelper這個資料庫輔助類吧,在資料庫連線操作過程中存在著DataSet物件和DataAdaper物件。DataAdaper也就是資料介面卡,負責把DataSet與真實資料來源連線起來。DataAdaper獲得資料,然後將資料填充到DataSet物件中。針對於資料庫與DataSet之間的一種適配。這也是.NET中一種介面卡模式的實現。
天再高又怎樣,踮起腳尖就更接近陽光。
C#設計模式系列目錄
歡迎大家掃描下方二維碼,和我一起踏上設計模式的闖關之路吧!