天天看點

【愚公系列】2021年12月 二十三種設計模式(六)-擴充卡模式(Adapter Pattern)

文章目錄

前言

一、擴充卡模式(Adapter Pattern)

二、使用步驟

角色

示例

類的擴充卡模式

對象的擴充卡模式

總結

優點

缺點

使用場景

設計模式(Design pattern)是一套被反複使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是為了可重用代碼、讓代碼更容易被他人了解、保證代碼可靠性。 毫無疑問,設計模式于己于他人于系統都是多赢的,設計模式使代碼編制真正工程化,設計模式是軟體工程的基石,如同大廈的一塊塊磚石一樣。項目中合理的運用設計模式可以完美的解決很多問題,每種模式在現在中都有相應的原理來與之對應,每一個模式描述了一個在我們周圍不斷重複發生的問題,以及該問題的核心解決方案,這也是它能被廣泛應用的原因。

提示:以下是本篇文章正文内容,下面案例可供參考

擴充卡模式屬于結構型模式,把一個類的接口變成用戶端所期待的另一種接口,進而使原本接口不比對而無法一起工作的兩個類能夠在一起工作。

擴充卡模式又可以分為4種類型,類擴充卡模式、對象擴充卡模式、單接口擴充卡模式(預設擴充卡模式)和雙向擴充卡模式。後2種模式的實作比較複雜并且在實際開發過程中很少使用,故本博文隻讨論前2種模式。

1、抽象目标(Target)

抽象目标類定義客戶所需的接口,可以是一個抽象類或接口,也可以是具體類。在類擴充卡中,由于C#語言不支援多重繼承,是以它隻能是接口;

2、擴充卡(Adapter)

它可以調用另一個接口,作為一個轉換器,對Adaptee和Target進行适配,它是擴充卡模式的核心;

3、适配者(Adaptee)

适配者即被适配的角色,它定義了一個已經存在的接口,這個接口需要适配,适配者類包好了客戶希望的業務方法。

【愚公系列】2021年12月 二十三種設計模式(六)-擴充卡模式(Adapter Pattern)
命名空間AdapterPattern包含ClassBased和ObjectBased子命名空間,分别表示基于類的擴充卡模式和基于對象的擴充卡模式。類的擴充卡中包含家用電器類、電壓類、目标動作接口和手機擴充卡類。對象的擴充卡中包含适配者、擴充卡、目标接口和目标基類。本案例嘗試使用手機擴充卡将家用電器的電壓從220V适配至3V。

namespace AdapterPattern      
namespace AdapterPattern.ClassBased      
public class Voltage {

    public uint Value { get; set; }

}      

電壓Voltage類,包含一個無符号int類型的電壓值。

public class Appliance {

    public Voltage GetVoltage() {
        return new Voltage { Value = 220 };
    }

}      

家用電器Appliance類,包含一個擷取電壓的GetVoltage方法。

public interface ITarget {

    Voltage GetMobileVoltage();

}      

目标接口ITarget,包含一個擷取手機電壓的GetMobileVoltage方法。這是我們要适配的目标動作。

public class MobileAdapter : Appliance, ITarget {
 
    public Voltage GetMobileVoltage() {
        var voltage = GetVoltage();
        Console.WriteLine($"Appliance voltage is {voltage.Value}V!");
 
        voltage.Value = 3;
        Console.WriteLine($"After adapted,it becomes {voltage.Value}V!");
 
        return voltage;
    }
 
}      

手機擴充卡MobileAdapter類,繼承自Applicance家用電器并實作ITarget接口。

namespace AdapterPattern.ObjectBased      
public class Adaptee {

    public void OriginalMethod() {
        Console.WriteLine("Original Method is being called!");
    }

}      

适配者Adaptee類,這是将要被我們适配的類。

public interface ITarget {

    void TargetMethod();

}      

目标接口ITarget,定義我們的目标動作。

public class Target : ITarget {

    public virtual void TargetMethod() {
        Console.WriteLine("Target Method is being called!");
    }

}      

目标Target類,實作目标接口以實作動作。

public class Adapter : Target {

    private Adaptee _adaptee = new Adaptee();

    public override void TargetMethod() {
        _adaptee.OriginalMethod();
    }

}      

擴充卡Adapter類,繼承自Target類。内部維持對适配者的引用并實作一個目标動作。

public class Program {

    private static ClassBased.ITarget _targetClass = null;
    private static ObjectBased.ITarget _targetObject = null;

    public static void Main(string[] args) {
        //Class Pattern
        _targetClass = new ClassBased.MobileAdapter();
        var voltage = _targetClass.GetMobileVoltage();

        Console.WriteLine("-----------------------------");

        //Object Pattern
        _targetObject = new ObjectBased.Adapter();
        _targetObject.TargetMethod();

        Console.ReadKey();
    }

}      

以上是調用方的代碼,分别示範了類的擴充卡模式和對象的擴充卡模式的用法。以下是這2個案例的輸出結果:

Appliance voltage is 220V!
After adapted,it becomes 3V!
-----------------------------
Original Method is being called!      

1、可以讓任何兩個沒有關聯的類一起運作;

2、可以在不修改原有代碼的基礎上來複用現有類,很好地符合 “開閉原則”;

3、增加了類的透明度和更好的靈活性。

1、由于C#不支援多重繼承,是以最多隻能适配一個适配者類,而且目标類必須是抽象類;

2、采用了類和接口的“雙繼承”實作方式,帶來了不良的高耦合。

1、系統需要複用現有類,而該類的接口不符合系統的需求;

2、想要建立一個可重複使用的類,用于與一些彼此之間沒有太大關聯的一些類,包括一些可能在将來引進的類一起工作;

3、對于對象擴充卡模式,在設計裡需要改變多個已有子類的接口,如果使用類的擴充卡模式,就要針對每一個子類做一個擴充卡,而這不太實際。

繼續閱讀