2017年9月26日 星期二

C# : 購物車多樣付款機制(使用介面 Interface 來抽象化需求)

在這裡,將說明一個大家經常會遇到的一個情境,那就是在開發專案的時候,隨著時間變化,需求也有了變化,因此,我們要如何針對需求來調整我們的類別設計呢?
例如,你開發了一個購物網站,僅僅提供了兩種付款機制,例如:銀行轉帳、信用卡付款,不過,此時,客戶希望能夠追加某家的第三方支付系統,到我們家的專案內,讓客戶進行付款的時候,有著更多樣性的選擇。
之前,公司同事面臨到這樣的情境,若想要追加第二家的第三方支付系統到我們家的專案內,這樣又該如何處理呢?
在這裡,我們需要將這些付款機制抽象化出來,使用介面 Interface 制定出這些付款機制需要用到的相關屬性與方法等成員 Member;之後,就可以在不同的具體類別中,實作這個介面,在這些具體實作類別中,會根據每個付款機制進行不同的處理流程。
當這個專案系統的使用者需要進行付款作業的時候,我們在程式裡面,僅需要針對這個介面物件變數進行處理,而實際的具體實作物件,會根據使用者選擇的機制,實際產生或者注入到我們的系統內。
現在,讓我們來看看這個練習的類別與介面宣告。我們宣告一個介面 I付款方法,他如同一個合約,每個要進行付款動作的類別,都需要實作出這個介面 I付款方法。而這個介面裡面,僅有宣告一個方法 void 付款(int Money);
另外,我們建立了三個類別,轉帳付款 / 信用卡付款 / 第三方支付付款,這三個類別都有實作出 I付款方法這個介面合約內容,也就是都有自行設計出每個付款機制的 付款 方法。
public interface I付款方法
{
    void 付款(int Money);
}

public class 轉帳付款 : I付款方法
{
    public void 付款(int Money)
    {
        Console.WriteLine($"正在使用 轉帳方式 進行付款 ${Money}");
    }
}

public class 信用卡付款 : I付款方法
{
    public void 付款(int Money)
    {
        Console.WriteLine($"正在使用 信用卡方式 進行付款 ${Money}");
    }
}

public class 第三方支付付款 : I付款方法
{
    public void 付款(int Money)
    {
        Console.WriteLine($"正在使用 第三方支付方式 進行付款 ${Money}");
    }
}

進行測試

現在讓我們來進行完成類似購物車的付款機制,在實際進行專案設計的時候,我們需要宣告一個物件變數,他的型別為 I付款方法,而我們針對這個物件變數會依據當時的需求,實例化所需要型別的執行個體;這裡,你可以選擇使用不同的設計模式 (Design Pattern) ,例如 Service, Factory, 或者 相依性注入 Dependency Injection等模式來幫助你有系統的設計這樣的需求。
不過,在這裡,我們簡化這樣的需求,我們直接建立這三個具體類別的物件到 I付款方法 型別變數內。
接著,我們就可以直接使用 I付款方法 物件變數的 付款 方法,進行付款動作。
由執行結果,我們可以看到,雖然物件變數的型別都是 I付款方法,不過,實際執行付款的方法,卻是相對應的具體實作的類別內定義的方法。
I付款方法 foo轉帳付款付款 = new 轉帳付款();
I付款方法 foo信用卡付款 = new 信用卡付款();
I付款方法 foo第三方支付付款 = new 第三方支付付款();

foo轉帳付款付款.付款(111);
foo信用卡付款.付款(222);
foo第三方支付付款.付款(333);
Console.WriteLine($"Press any key for continuing...{Environment.NewLine}");
Console.ReadKey();
這是執行後的結果輸出內容
正在使用 轉帳方式 進行付款 $111
正在使用 信用卡方式 進行付款 $222
正在使用 第三方支付方式 進行付款 $333
Press any key for continuing...

沒有留言:

張貼留言