首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 面向物件設計思想實戰:從 Switch 到工廠模式再到組態驅動

     編輯:關於C語言

前言

本文透過一個「媒體播放器」需求演進,展示如何應用 OOP 原則、重構技法與設計模式,將僵化的程式碼逐步轉化為靈活、可擴充、符合開放封閉原則 (OCP) 的架構。

階段 0:面向過程寫法(反面教材)

public class MediaPlayer
{
    public void Play(string audioType)
    {
        switch (audioType.ToLower())
        {
            case "mp3": PlayMp3(); break;
            case "wav": PlayWav(); break;
        }
    }
    private void PlayMp3() => MessageBox.Show("Play mp3");
    private void PlayWav() => MessageBox.Show("Play wav");
}

缺點:新增格式需修改核心類別、違反 OCP、測試困難、Switch 膨脹。

階段 1:引入繼承與多態

public abstract class AudioMedia { public abstract void Play(); }
public class Mp3 : AudioMedia { public override void Play() => ... }
public class Wav : AudioMedia { public override void Play() => ... }

public class MediaPlayer
{
    public void Play(AudioMedia media) => media.Play(); // 多態呼叫
}

進步:新增格式只需新增類別,MediaPlayer 不動。但僅支援音訊。

階段 2:擴充至視訊,引入介面統一

public interface IMedia { void Play(); }
public abstract class AudioMedia : IMedia { public abstract void Play(); }
public abstract class VideoMedia : IMedia { public abstract void Play(); }

public class Mp3 : AudioMedia { ... }
public class Rm : VideoMedia { ... }

public class MediaPlayer
{
    public void Play(IMedia media) => media.Play(); // 依賴抽象
}

階段 3:工廠模式封裝物件建立

public interface IMediaFactory { IMedia CreateMedia(); }

public class Mp3Factory : IMediaFactory { public IMedia CreateMedia() => new Mp3(); }
public class RmFactory : IMediaFactory { public IMedia CreateMedia() => new Rm(); }

// 呼叫端仍有 switch
IMediaFactory factory = type switch { "mp3" => new Mp3Factory(), "rm" => new RmFactory() };
IMedia media = factory.CreateMedia();
media.Play();

階段 4:組態檔 + 反射 徹底消除 Switch

App.config

<appSettings>
  <add key="mp3" value="MyApp.Media.Mp3Factory" />
  <add key="wav" value="MyApp.Media.WavFactory" />
  <add key="rm" value="MyApp.Media.RmFactory" />
</appSettings>

表單載入時動態填充下拉選單

private void Form_Load(object sender, EventArgs e)
{
    foreach (string key in ConfigurationManager.AppSettings.AllKeys)
        cboMediaType.Items.Add(key);
    cboMediaType.SelectedIndex = 0;
}

播放按鈕:純反射建立工廠

private void btnPlay_Click(object sender, EventArgs e)
{
    string type = cboMediaType.SelectedItem.ToString().ToLower();
    string factoryTypeName = ConfigurationManager.AppSettings[type];
    
    // 從 MediaLibrary 組件建立工廠實例
    IMediaFactory factory = (IMediaFactory)Activator.CreateInstance(
        "MediaLibrary", factoryTypeName).Unwrap();
    
    IMedia media = factory.CreateMedia();
    media.Play(); // MediaPlayer 類別已可移除
}

階段 5:新增格式零修改主程式

  1. 在 MediaLibrary 專案新增 Avi : VideoMedia 並實作 Play()。
  2. 新增 AviFactory : IMediaFactory 回傳 new Avi()。
  3. 在 App.config 新增 <add key="avi" value="MyApp.Media.AviFactory" />。
  4. 主程式專案完全不動,甚至不需重新編譯(若工廠在獨立組件)。

架構總結圖

+----------------+     +----------------+     +----------------+
|  UI (ComboBox) | --> |  App.config    | --> | Activator      |
+----------------+     +----------------+     +----------------+
                                                          |
                                                          v
+----------------+     +----------------+     +----------------+
|  IMedia        | <-- |  Factory       | <-- |  Concrete    |
|  (Interface)   |     |  (Interface)   |     |  Factory     |
+----------------+     +----------------+     +----------------+
        ^                        ^                        ^
        |                        |                        |
+----------------+     +----------------+     +----------------+
|  Mp3/Wav/Rm/.. |     |  Mp3Factory/.. |     |  new Mp3()   |
|  (Concrete)    |     |  (Concrete)    |     |              |
+----------------+     +----------------+     +----------------+

核心設計原則回顧

原則本例體現
單一職責 (SRP)播放邏輯、建立邏輯、組態讀取分離。
開放封閉 (OCP)新增格式擴充類別與組態,不修改既有程式碼。
里氏替換 (LSP)所有具體媒體可替換 IMedia 介面。
介面隔離 (ISP)IMedia 僅定義 Play(),精簡契約。
依賴反轉 (DIP)高層 UI 依賴抽象 IMediaFactory,不依賴具體類別。

結語

從 switch 到 App.config + 反射,我們見證了「給程式碼裝上翅膀」的過程。掌握 抽象介面、工廠模式、組態驅動、反射建立 四大關鍵,即能應對多變需求,享受「神清氣閒」的架構之美。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved