基础教程中我们了解过单例、工厂、观察者等经典设计模式。在实际的 C# 项目中,这些模式有更地道的 .NET 实现方式,同时也需要理解模式之间的组合与演进。本文将探讨设计模式在 C# 中的最佳实践以及 .NET 生态中的模式变体。
单例模式 —— .NET 最佳实践 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public sealed class Singleton { private static readonly Singleton _instance = new (); static Singleton () { } private Singleton () { } public static Singleton Instance => _instance; } public sealed class LazySingleton { private static readonly Lazy<LazySingleton> _lazy = new (() => new LazySingleton(), LazyThreadSafetyMode.ExecutionAndPublication); private LazySingleton () { } public static LazySingleton Instance => _lazy.Value; } public abstract class SingletonBase <T > where T : class , new (){ private static readonly T _instance = new (); public static T Instance => _instance; }
工厂模式 —— 现代 C# 风格 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public interface IPaymentProvider { Task<PaymentResult> ProcessAsync (decimal amount ) ; string ProviderName { get ; } } public class AlipayProvider : IPaymentProvider { }public class WechatPayProvider : IPaymentProvider { }public class PaymentFactory { private readonly Dictionary<string , IPaymentProvider> _providers; public PaymentFactory (IEnumerable<IPaymentProvider> providers ) { _providers = providers.ToDictionary(p => p.ProviderName); } public IPaymentProvider GetProvider (string name ) => _providers.TryGetValue(name, out var provider) ? provider : throw new ArgumentException($"不支持的支付方式: {name} " ); } services.AddScoped<IPaymentProvider, AlipayProvider>(); services.AddScoped<IPaymentProvider, WechatPayProvider>(); services.AddScoped<PaymentFactory>();
策略模式 —— 函数式简化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public interface ISortStrategy { int [] Sort (int [] data ) ; } public class BubbleSort : ISortStrategy { public int [] Sort (int [] data ) { } }public class QuickSort : ISortStrategy { public int [] Sort (int [] data ) { } }public class Sorter { private readonly Func<int [], int []> _sortFunc; public Sorter (Func<int [], int []> sortFunc ) { _sortFunc = sortFunc; } public int [] Sort (int [] data ) => _sortFunc(data); } var sorter = new Sorter(data =>{ Array.Sort(data); return data; }); var sorter2 = new Sorter(data => data.OrderBy(x => x).ToArray());
观察者模式 —— .NET 事件 vs IObservable 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 public class StockPublisher { public event EventHandler<StockPriceChangedEventArgs>? PriceChanged; protected virtual void OnPriceChanged (string symbol, decimal price ) { PriceChanged?.Invoke(this , new StockPriceChangedEventArgs(symbol, price)); } } public class StockObservable : IObservable <StockPrice >{ private readonly List<IObserver<StockPrice>> _observers = new (); public IDisposable Subscribe (IObserver<StockPrice> observer ) { _observers.Add(observer); return new Unsubscriber(_observers, observer); } public void Notify (StockPrice price ) { foreach (var observer in _observers) observer.OnNext(price); } private class Unsubscriber : IDisposable { private readonly List<IObserver<StockPrice>> _observers; private readonly IObserver<StockPrice> _observer; public Unsubscriber (List<IObserver<StockPrice>> observers, IObserver<StockPrice> observer ) { _observers = observers; _observer = observer; } public void Dispose () => _observers.Remove(_observer); } } Observable.Interval(TimeSpan.FromSeconds(1 )) .Select(tick => new StockPrice("AAPL" , 150 + Math.Sin(tick) * 5 )) .Subscribe(price => Console.WriteLine($"{price.Symbol} : {price.Price:C} " ));
建造者模式 —— 流畅 API 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 public class SqlQueryBuilder { private readonly StringBuilder _select = new (); private readonly StringBuilder _from = new (); private readonly StringBuilder _where = new (); private readonly StringBuilder _orderBy = new (); private int _take; public SqlQueryBuilder Select (string columns ) { _select.Append(columns); return this ; } public SqlQueryBuilder From (string table ) { _from.Append(table); return this ; } public SqlQueryBuilder Where (string condition ) { if (_where.Length > 0 ) _where.Append(" AND " ); _where.Append(condition); return this ; } public SqlQueryBuilder OrderBy (string column, bool descending = false ) { _orderBy.Append(column); if (descending ) _orderBy.Append(" DESC" ); return this ; } public SqlQueryBuilder Take (int count ) { _take = count; return this ; } public string Build () { var sql = new StringBuilder($"SELECT {_select} FROM {_from} " ); if (_where.Length > 0 ) sql.Append($" WHERE {_where} " ); if (_orderBy.Length > 0 ) sql.Append($" ORDER BY {_orderBy} " ); if (_take > 0 ) sql.Append($" LIMIT {_take} " ); return sql.ToString(); } } string sql = new SqlQueryBuilder() .Select("Id, Name, Price" ) .From("Products" ) .Where("Price > 100" ) .Where("Stock > 0" ) .OrderBy("Price" , descending : true ) .Take(10 ) .Build();
责任链模式 —— 中间件管道 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 public interface IHandler { Task HandleAsync (OrderContext context, Func<Task> next ) ; } public class ValidationHandler : IHandler { public async Task HandleAsync (OrderContext context, Func<Task> next ) { if (context.Order.Amount <= 0 ) throw new ValidationException("金额必须大于 0" ); Console.WriteLine("验证通过" ); await next(); } } public class LoggingHandler : IHandler { public async Task HandleAsync (OrderContext context, Func<Task> next ) { Console.WriteLine($"处理订单: {context.Order.Id} " ); await next(); Console.WriteLine($"订单处理完成: {context.Order.Id} " ); } } public class PipelineBuilder { private readonly List<IHandler> _handlers = new (); public PipelineBuilder Add (IHandler handler ) { _handlers.Add(handler); return this ; } public Func<OrderContext, Task> Build () { return async context => { async Task ExecuteAsync (int index ) { if (index < _handlers.Count) await _handlers[index].HandleAsync(context, () => ExecuteAsync(index + 1 )); } await ExecuteAsync(0 ); }; } } var pipeline = new PipelineBuilder() .Add(new ValidationHandler()) .Add(new LoggingHandler()) .Add(new SaveToDatabaseHandler()) .Build(); await pipeline(new OrderContext { Order = order });
状态模式 —— 游戏/工作流 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 public class OrderStateMachine { public IOrderState CurrentState { get ; private set ; } public OrderStateMachine () { CurrentState = new PendingState(); } public void Next () => CurrentState = CurrentState.Next(); public void Cancel () => CurrentState = CurrentState.Cancel(); public string Status => CurrentState.Status; public interface IOrderState { string Status { get ; } IOrderState Next () ; IOrderState Cancel () ; } public class PendingState : IOrderState { public string Status => "待支付" ; public IOrderState Next () => new PaidState(); public IOrderState Cancel () => new CancelledState(); } public class PaidState : IOrderState { public string Status => "已支付" ; public IOrderState Next () => new ShippedState(); public IOrderState Cancel () => new RefundingState(); } public class ShippedState : IOrderState { public string Status => "已发货" ; public IOrderState Next () => new DeliveredState(); public IOrderState Cancel () => new RefundingState(); } public class DeliveredState : IOrderState { public string Status => "已送达" ; public IOrderState Next () => this ; public IOrderState Cancel () => this ; } public class CancelledState : IOrderState { public string Status => "已取消" ; public IOrderState Next () => this ; public IOrderState Cancel () => this ; } public class RefundingState : IOrderState { public string Status => "退款中" ; public IOrderState Next () => new CancelledState(); public IOrderState Cancel () => this ; } }
适配器模式 —— 兼容旧接口 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class ThirdPartyLogger { public void LogMessage (string message, int level ) { Console.WriteLine($"[Level {level} ] {message} " ); } } public interface ILogger { void Info (string message ) ; void Error (string message, Exception? ex = null ) ; } public class LoggerAdapter : ILogger { private readonly ThirdPartyLogger _adaptee; public LoggerAdapter (ThirdPartyLogger adaptee ) => _adaptee = adaptee; public void Info (string message ) => _adaptee.LogMessage(message, 0 ); public void Error (string message, Exception? ex = null ) => _adaptee.LogMessage($"{message} : {ex} " , 1 ); }
C# 中设计模式演变趋势
模式
传统 C# 实现
现代 C# 实现
策略
接口 + 多态类
Func/Action 委托
工厂
抽象工厂类
DI + Func 工厂
观察者
事件 (event)
IObservable/IObserver + Rx
建造者
具体 Builder 类
记录+with 表达式
模板方法
抽象基类
高阶函数
访问者
双分发访问者
模式匹配 (switch)
总结 :设计模式是重构的”词汇表”,而非一成不变的模板。在 C# 中,许多传统模式可以被更简洁的语言特性替代(委托替代策略,record 替代 DTO/建造者),而另一些模式(DI 容器、中间件管道)已成为框架基础设施。理解模式的本质意图,在 .NET 生态中选择最地道的实现方式,比僵硬地套用 GoF 模板更重要。