
1. 引言
设计模式是软件开发中经过验证的、用于解决特定设计问题的通用解决方案。它们代表了众多软件开发者在面对同类问题时积累的最佳实践和经验。设计模式不是现成的代码,而是一种思想、一种方法论,它为软件设计中的常见问题提供了可重用的解决方案。
1994年,Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides(被称为"四人帮"或"Gang of Four",简称GoF)出版了《设计模式:可复用面向对象软件的基础》一书,系统地介绍了23种经典设计模式,这些模式至今仍被广泛应用于软件开发中。
1.1 设计模式的价值
- 提高开发效率:设计模式提供了经过验证的解决方案,避免了"重新发明轮子"
- 提高代码质量:设计模式有助于创建更加灵活、可维护和可扩展的系统
- 促进团队沟通:设计模式提供了一种共同的语言,使团队成员能够更有效地交流设计理念
- 降低维护成本:设计良好的系统更容易理解和修改,减少了维护成本
- 应对变化:设计模式考虑了系统的可扩展性,使系统更好地应对需求变化
1.2 设计模式的分类
GoF设计模式按其目的可分为三大类:
- 创建型模式:处理对象的创建方式,确保对象创建适合于特定场景
- 结构型模式:处理类和对象的组合,组成更大的结构
- 行为型模式:关注对象之间的通信和责任分配
2. 面向对象设计原则
设计模式遵循一系列面向对象设计原则,这些原则指导着模式的创建和应用。理解这些原则对于正确应用设计模式至关重要。
2.1 单一职责原则 (SRP)
一个类应该只有一个引起它变化的原因。换句话说,一个类应该只负责一项职责。
// 违反单一职责原则的示例
public class UserManager
{
// 用户管理相关职责
public void AddUser(string username) { /* ... */ }
public void RemoveUser(string username) { /* ... */ }
// 报表生成相关职责 - 不应该在这个类中
public void GenerateUserReport() { /* ... */ }
public void ExportUserDataToCSV() { /* ... */ }
}
// 符合单一职责原则的示例
public class UserManager
{
// 仅包含用户管理相关职责
public void AddUser(string username) { /* ... */ }
public void RemoveUser(string username) { /* ... */ }
}
public class UserReportGenerator
{
// 专门负责报表生成
public void GenerateUserReport() { /* ... */ }
public void ExportUserDataToCSV() { /* ... */ }
}
2.2 开放封闭原则 (OCP)
软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着当需要增加新功能时,应该通过扩展现有代码而不是修改它来实现。
// 违反开放封闭原则的示例
public class Rectangle
{
public double Width { get; set; }
public double Height { get; set; }
}
public class AreaCalculator
{
public double CalculateArea(object shape)
{
// 每次添加新形状都需要修改这个方法
if (shape is Rectangle rectangle)
{
return rectangle.Width * rectangle.Height;
}
// 如果添加圆形,就需要修改此方法
return 0;
}
}
// 符合开放封闭原则的示例
public interface IShape
{
double CalculateArea();
}
public class Rectangle : IShape
{
public double Width { get; set; }
public double Height { get; set; }
public double CalculateArea()
{
return Width * Height;
}
}
public class Circle : IShape
{
public double Radius { get; set; }
public double CalculateArea()
{
return Math.PI * Radius * Radius;
}
}
// 现在添加新形状不需要修改此类
public class AreaCalculator
{
public double CalculateArea(IShape shape)
{
return shape.CalculateArea();
}
}
2.3 里氏替换原则 (LSP)
子类型必须能够替换其基类型。这意味着程序中的对象应该可以被其子类的实例所替换,而不影响程序的正确性。
// 违反里氏替换原则的示例
public class Bird
{
public virtual void Fly()
{
// 飞行的实现
}
}
public class Ostrich : Bird
{
public override void Fly()
{
// 鸵鸟不能飞,这里会抛出异常或者空实现
throw new NotSupportedException("鸵鸟不能飞行");
}
}
// 符合里氏替换原则的示例
public abstract class Bird
{
// 通用鸟类行为
public abstract void Move();
}
public class FlyingBird : Bird
{
public override void Move()
{
// 飞行实现
}
public virtual void Fly()
{
// 飞行的具体实现
}
}
public class NonFlyingBird : Bird
{
public override void Move()
{
// 非飞行鸟类的移动实现(例如行走)
}
}
2.4 接口隔离原则 (ISP)
客户端不应该被迫依赖于它们不使用的方法。这个原则建议将大接口分解为更小、更具体的接口。
// 违反接口隔离原则的示例
public interface IWorker
{
void Work();
void Eat();
void Sleep();
}
public class Human : IWorker
{
public void Work() { /* ... */ }
public void Eat() { /* ... */ }
public void Sleep() { /* ... */ }
}
public class Robot : IWorker
{
public void Work() { /* ... */ }
public void Eat() { /* 机器人不需要进食,但被迫实现 */ }
public void Sleep() { /* 机器人不需要睡觉,但被迫实现 */ }
}
// 符合接口隔离原则的示例
public interface IWorkable
{
void Work();
}
public interface IEatable
{
void Eat();
}
public interface ISleepable
{
void Sleep();
}
public class Human : IWorkable, IEatable, ISleepable
{
public void Work() { /* ... */ }
public void Eat() { /* ... */ }
public void Sleep() { /* ... */ }
}
public class Robot : IWorkable
{
public void Work() { /* ... */ }
// 不需要实现不相关的接口
}
2.5 依赖倒置原则 (DIP)
高层模块不应该依赖于低层模块,二者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
// 违反依赖倒置原则的示例
public class LightBulb
{
public void TurnOn() { /* ... */ }
public void TurnOff() { /* ... */ }
}
public class Switch
{
private readonly LightBulb _bulb;
// 直接依赖具体实现
public Switch()
{
_bulb = new LightBulb();
}
public void Toggle(bool isOn)
{
if (isOn)
_bulb.TurnOn();
else
_bulb.TurnOff();
}
}
// 符合依赖倒置原则的示例
public interface ISwitchable
{
void TurnOn();
void TurnOff();
}
public class LightBulb : ISwitchable
{
public void TurnOn() { /* ... */ }
public void TurnOff() { /* ... */ }
}
public class Fan : ISwitchable
{
public void TurnOn() { /* ... */ }
public void TurnOff() { /* ... */ }
}
public class Switch
{
private readonly ISwitchable _device;
// 依赖抽象,而非具体实现
public Switch(ISwitchable device)
{
_device = device;
}
public void Toggle(bool isOn)
{
if (isOn)
_device.TurnOn();
else
_device.TurnOff();
}
}
2.6 合成复用原则 (CRP)
尽量使用对象组合,而不是通过继承来达到复用的目的。
// 违反合成复用原则的示例 - 通过继承实现复用
public class Database
{
public void Connect() { /* ... */ }
public void Disconnect() { /* ... */ }
public void ExecuteQuery(string query) { /* ... */ }
}
public class SpecializedDatabase : Database
{
// 通过继承复用Database的功能
public void ExecuteSpecialQuery()
{
Connect();
ExecuteQuery("special query");
Disconnect();
}
}
// 符合合成复用原则的示例 - 通过组合实现复用
public class DatabaseService
{
private readonly Database _database;
public DatabaseService(Database database)
{
_database = database;
}
// 通过组合复用Database的功能
public void ExecuteSpecialQuery()
{
_database.Connect();
_database.ExecuteQuery("special query");
_database.Disconnect();
}
}
2.7 迪米特法则 (LoD)
一个对象应该对其他对象保持最少的了解,只与它的"朋友"交谈。这个原则也被称为"最少知识原则"。
// 违反迪米特法则的示例
public class Customer
{
public Wallet Wallet { get; set; }
}
public class Wallet
{
public decimal Money { get; set; }
}
public class ShopKeeper
{
public void ProcessPayment(Customer customer, decimal amount)
{
// 直接访问客户的钱包,违反了迪米特法则
if (customer.Wallet.Money >= amount)
{
customer.Wallet.Money -= amount;
}
}
}
// 符合迪米特法则的示例
public class Customer
{
private Wallet _wallet;
public Customer()
{
_wallet = new Wallet();
}
// 提供方法处理付款,封装钱包的访问
public bool MakePayment(decimal amount)
{
if (_wallet.Money >= amount)
{
_wallet.Money -= amount;
return true;
}
return false;
}
}
public class ShopKeeper
{
public void ProcessPayment(Customer customer, decimal amount)
{
// 不直接访问客户的钱包,而是请求客户处理付款
bool paymentSuccessful = customer.MakePayment(amount);
if (paymentSuccessful)
{
// 处理成功的付款
}
}
}
3. 创建型设计模式
创建型设计模式关注对象的创建过程,帮助我们以更灵活的方式创建对象,而不是直接使用new操作符。
3.1 单例模式 (Singleton)
单例模式确保一个类只有一个实例,并提供一个全局访问点。
C#实现示例:
/// <summary>
/// 单例模式的线程安全实现
/// </summary>
public sealed class Singleton
{
// 私有静态实例,使用volatile确保多线程访问的可见性
private static volatile Singleton _instance;
// 用于锁定的对象
private static readonly object _lock = new object();
// 私有构造函数,防止外部实例化
private Singleton()
{
// 初始化代码
}
/// <summary>
/// 获取单例实例的全局访问点
/// </summary>
public static Singleton Instance
{
get
{
// 双重检查锁定模式
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
{
_instance = new Singleton();
}
}
}
return _instance;
}
}
/// <summary>
/// 业务方法示例
/// </summary>
public void DoSomething()
{
Console.WriteLine("单例正在执行操作...");
}
}
// 使用示例
public class Program
{
public static void Main()
{
// 不能通过构造函数创建实例
// Singleton singleton = new Singleton(); // 编译错误
// 通过全局访问点获取实例
Singleton instance1 = Singleton.Instance;
Singleton instance2 = Singleton.Instance;
// 验证两个实例是同一个对象
Console.WriteLine($"实例是相同的: {ReferenceEquals(instance1, instance2)}");
// 调用实例方法
instance1.DoSomething();
}
}
3.2 工厂方法模式 (Factory Method)
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类。工厂方法让一个类的实例化延迟到其子类。
C#实现示例:
/// <summary>
/// 产品接口,定义工厂方法创建的对象的接口
/// </summary>
public interface IProduct
{
string Operation();
}
/// <summary>
/// 具体产品A,实现产品接口
/// </summary>
public class ConcreteProductA : IProduct
{
public string Operation()
{
return "结果来自具体产品A";
}
}
/// <summary>
/// 具体产品B,实现产品接口
/// </summary>
public class ConcreteProductB : IProduct
{
public string Operation()
{
return "结果来自具体产品B";
}
}
/// <summary>
/// 创建者抽象类,声明工厂方法
/// </summary>
public abstract class Creator
{
/// <summary>
/// 工厂方法 - 由子类实现以创建具体产品
/// </summary>
public abstract IProduct FactoryMethod();
/// <summary>
/// 使用工厂方法的核心业务逻辑
/// </summary>
public string SomeOperation()
{
// 调用工厂方法创建产品
var product = FactoryMethod();
// 使用产品
return $"创建者: 与 {product.Operation()} 一起工作";
}
}
/// <summary>
/// 具体创建者A,创建具体产品A
/// </summary>
public class ConcreteCreatorA : Creator
{
public override IProduct FactoryMethod()
{
return new ConcreteProductA();
}
}
/// <summary>
/// 具体创建者B,创建具体产品B
/// </summary>
public class ConcreteCreatorB : Creator
{
public override IProduct FactoryMethod()
{
return new ConcreteProductB();
}
}
// 使用示例
public class Program
{
public static void Main()
{
Console.WriteLine("使用具体创建者A:");
ClientCode(new ConcreteCreatorA());
Console.WriteLine("\n使用具体创建者B:");
ClientCode(new ConcreteCreatorB());
}
/// <summary>
/// 客户端代码使用创建者,但不关心具体是哪个创建者
/// </summary>
public static void ClientCode(Creator creator)
{
Console.WriteLine($"客户端代码: {creator.SomeOperation()}");
}
}
3.3 抽象工厂模式 (Abstract Factory)
抽象工厂模式提供一个创建相关或依赖对象家族的接口,而不明确指定它们的具体类。
C#实现示例:
/// <summary>
/// 抽象产品A接口
/// </summary>
public interface IAbstractProductA
{
string UsefulFunctionA();
}
/// <summary>
/// 具体产品A1 - 风格1的产品A
/// </summary>
public class ConcreteProductA1 : IAbstractProductA
{
public string UsefulFunctionA()
{
return "产品A1的结果";
}
}
/// <summary>
/// 具体产品A2 - 风格2的产品A
/// </summary>
public class ConcreteProductA2 : IAbstractProductA
{
public string UsefulFunctionA()
{
return "产品A2的结果";
}
}
/// <summary>
/// 抽象产品B接口
/// </summary>
public interface IAbstractProductB
{
string UsefulFunctionB();
// 产品B可以与产品A协作
string AnotherUsefulFunctionB(IAbstractProductA collaborator);
}
/// <summary>
/// 具体产品B1 - 风格1的产品B
/// </summary>
public class ConcreteProductB1 : IAbstractProductB
{
public string UsefulFunctionB()
{
return "产品B1的结果";
}
public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
{
var result = collaborator.UsefulFunctionA();
return $"B1与({result})协作的结果";
}
}
/// <summary>
/// 具体产品B2 - 风格2的产品B
/// </summary>
public class ConcreteProductB2 : IAbstractProductB
{
public string UsefulFunctionB()
{
return "产品B2的结果";
}
public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
{
var result = collaborator.UsefulFunctionA();
return $"B2与({result})协作的结果";
}
}
/// <summary>
/// 抽象工厂接口 - 声明一组用于创建产品家族的方法
/// </summary>
public interface IAbstractFactory
{
IAbstractProductA CreateProductA();
IAbstractProductB CreateProductB();
}
/// <summary>
/// 具体工厂1 - 创建风格1的产品家族
/// </summary>
public class ConcreteFactory1 : IAbstractFactory
{
public IAbstractProductA CreateProductA()
{
return new ConcreteProductA1();
}
public IAbstractProductB CreateProductB()
{
return new ConcreteProductB1();
}
}
/// <summary>
/// 具体工厂2 - 创建风格2的产品家族
/// </summary>
public class ConcreteFactory2 : IAbstractFactory
{
public IAbstractProductA CreateProductA()
{
return new ConcreteProductA2();
}
public IAbstractProductB CreateProductB()
{
return new ConcreteProductB2();
}
}
// 使用示例
public class Program
{
public static void Main()
{
// 使用第一个工厂创建产品
Console.WriteLine("客户端: 使用第一个工厂类型...");
ClientCode(new ConcreteFactory1());
// 使用第二个工厂创建产品
Console.WriteLine("\n客户端: 使用第二个工厂类型...");
ClientCode(new ConcreteFactory2());
}
/// <summary>
/// 客户端代码仅通过抽象类型工作,不关心具体工厂和产品
/// </summary>
public static void ClientCode(IAbstractFactory factory)
{
var productA = factory.CreateProductA();
var productB = factory.CreateProductB();
Console.WriteLine(productA.UsefulFunctionA());
Console.WriteLine(productB.UsefulFunctionB());
Console.WriteLine(productB.AnotherUsefulFunctionB(productA));
}
}
3.4 建造者模式 (Builder)
建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
C#实现示例:
/// <summary>
/// 产品类 - 表示被构建的复杂对象
/// </summary>
public class Product
{
// 产品可以由多个部分组成
private List<string> _parts = new List<string>();
/// <summary>
/// 添加产品部件
/// </summary>
public void Add(string part)
{
_parts.Add(part);
}
/// <summary>
/// 列出所有产品部件
/// </summary>
public string ListParts()
{
return $"产品部件: {string.Join(", ", _parts)}\n";
}
}
/// <summary>
/// 生成器接口 - 声明构建产品各个部分的方法
/// </summary>
public interface IBuilder
{
void BuildPartA();
void BuildPartB();
void BuildPartC();
Product GetProduct();
}
/// <summary>
/// 具体生成器 - 实现构建和装配各个部件的接口
/// </summary>
public class ConcreteBuilder : IBuilder
{
private Product _product = new Product();
/// <summary>
/// 重置生成器实例,以便重新构建另一个产品
/// </summary>
public ConcreteBuilder()
{
Reset();
}
private void Reset()
{
_product = new Product();
}
/// <summary>
/// 构建产品的A部分
/// </summary>
public void BuildPartA()
{
_product.Add("部件A1");
}
/// <summary>
/// 构建产品的B部分
/// </summary>
public void BuildPartB()
{
_product.Add("部件B1");
}
/// <summary>
/// 构建产品的C部分
/// </summary>
public void BuildPartC()
{
_product.Add("部件C1");
}
/// <summary>
/// 获取构建好的产品
/// 注意:此方法在实际应用中通常会重置生成器
/// </summary>
public Product GetProduct()
{
Product result = _product;
Reset();
return result;
}
}
/// <summary>
/// 指导者类 - 定义构建产品的顺序
/// </summary>
public class Director
{
private IBuilder _builder;
/// <summary>
/// 设置使用的生成器
/// </summary>
public void SetBuilder(IBuilder builder)
{
_builder = builder;
}
/// <summary>
/// 构建最小可行产品
/// </summary>
public void BuildMinimalViableProduct()
{
_builder.BuildPartA();
}
/// <summary>
/// 构建完整功能产品
/// </summary>
public void BuildFullFeaturedProduct()
{
_builder.BuildPartA();
_builder.BuildPartB();
_builder.BuildPartC();
}
}
// 使用示例
public class Program
{
public static void Main()
{
// 创建生成器
var builder = new ConcreteBuilder();
// 创建指导者
var director = new Director();
// 设置指导者使用的生成器
director.SetBuilder(builder);
// 使用指导者创建不同配置的产品
Console.WriteLine("基本产品:");
director.BuildMinimalViableProduct();
Console.WriteLine(builder.GetProduct().ListParts());
Console.WriteLine("完整产品:");
director.BuildFullFeaturedProduct();
Console.WriteLine(builder.GetProduct().ListParts());
// 不使用指导者,直接使用生成器
Console.WriteLine("自定义产品:");
builder.BuildPartA();
builder.BuildPartC();
Console.WriteLine(builder.GetProduct().ListParts());
}
}
3.5 原型模式 (Prototype)
原型模式通过复制现有的对象来创建新对象,而不是通过实例化。
C#实现示例:
/// <summary>
/// 原型接口 - 声明克隆方法
/// </summary>
public interface IPrototype
{
IPrototype Clone();
}
/// <summary>
/// 具体原型A - 实现克隆方法
/// </summary>
public class ConcretePrototypeA : IPrototype
{
/// <summary>
/// 原型的属性
/// </summary>
public string Property { get; set; }
public ConcretePrototypeA(string property)
{
Property = property;
}
/// <summary>
/// 创建当前对象的浅表副本
/// </summary>
public IPrototype Clone()
{
// 在这个简单示例中,执行浅复制就足够了
return new ConcretePrototypeA(Property);
}
}
/// <summary>
/// 包含引用类型属性的原型 - 实现深复制
/// </summary>
public class Person : IPrototype
{
/// <summary>
/// 值类型属性
/// </summary>
public int Age { get; set; }
/// <summary>
/// 引用类型属性
/// </summary>
public string Name { get; set; }
/// <summary>
/// 包含另一个引用类型的属性
/// </summary>
public Address Address { get; set; }
public Person(int age, string name, Address address)
{
Age = age;
Name = name;
Address = address;
}
/// <summary>
/// 创建当前对象的深表副本
/// </summary>
public IPrototype Clone()
{
// 创建一个新的Address对象,而不是共享同一个引用
Address clonedAddress = null;
if (Address != null)
{
clonedAddress = new Address(Address.Street, Address.City, Address.Country);
}
// 返回包含新Address对象的新Person实例
return new Person(Age, Name, clonedAddress);
}
public override string ToString()
{
return $"Person[Age={Age}, Name={Name}, Address={Address}]";
}
}
/// <summary>
/// 用于演示深复制的地址类
/// </summary>
public class Address
{
public string Street { get; set; }
public string City { get; set; }
public string Country { get; set; }
public Address(string street, string city, string country)
{
Street = street;
City = city;
Country = country;
}
public override string ToString()
{
return $"Address[Street={Street}, City={City}, Country={Country}]";
}
}
// 使用示例
public class Program
{
public static void Main()
{
// 使用简单原型
ConcretePrototypeA prototypeA = new ConcretePrototypeA("测试");
ConcretePrototypeA cloneA = (ConcretePrototypeA)prototypeA.Clone();
Console.WriteLine($"原始对象属性值: {prototypeA.Property}");
Console.WriteLine($"克隆对象属性值: {cloneA.Property}");
Console.WriteLine($"是否为同一实例: {ReferenceEquals(prototypeA, cloneA)}");
// 展示深复制
Address address = new Address("中关村大街1号", "北京", "中国");
Person original = new Person(30, "张三", address);
Person clone = (Person)original.Clone();
Console.WriteLine("\n原始对象:");
Console.WriteLine(original);
Console.WriteLine("克隆对象:");
Console.WriteLine(clone);
// 修改原始对象的地址,验证深复制是否成功
original.Address.Street = "天安门广场";
Console.WriteLine("\n修改原始对象地址后:");
Console.WriteLine("原始对象:");
Console.WriteLine(original);
Console.WriteLine("克隆对象:");
Console.WriteLine(clone);
Console.WriteLine($"地址是否为同一实例: {ReferenceEquals(original.Address, clone.Address)}");
}
}
4. 结构型设计模式
结构型设计模式关注类和对象的组合。它们在不同的对象之间建立关系,使得这些对象能够协同工作,形成更大的结构。
4.1 适配器模式 (Adapter)
适配器模式允许将一个类的接口转换成客户端期望的另一个接口,使得原本不兼容的类可以在一起工作。
C#实现示例:
/// <summary>
/// 目标接口 - 客户端期望的接口
/// </summary>
public interface ITarget
{
string Request();
}
/// <summary>
/// 适配者类 - 需要被适配的类
/// </summary>
public class Adaptee
{
/// <summary>
/// 适配者的特殊请求方法
/// </summary>
public string SpecificRequest()
{
return "特殊请求";
}
}
/// <summary>
/// 对象适配器 - 通过组合使用适配者
/// </summary>
public class Adapter : ITarget
{
private readonly Adaptee _adaptee;
public Adapter(Adaptee adaptee)
{
_adaptee = adaptee;
}
/// <summary>
/// 实现目标接口,但内部调用适配者的方法
/// </summary>
public string Request()
{
// 这里可以进行一些转换工作
return $"适配者的工作: {_adaptee.SpecificRequest()}";
}
}
// 使用示例
public class Program
{
public static void Main()
{
// 创建适配者实例
Adaptee adaptee = new Adaptee();
// 创建适配器并传入适配者
ITarget target = new Adapter(adaptee);
// 客户端通过目标接口调用适配器
Console.WriteLine("适配者说: " + adaptee.SpecificRequest());
Console.WriteLine("目标接口说: " + target.Request());
}
}
4.2 桥接模式 (Bridge)
桥接模式将抽象部分与其实现部分分离,使它们都可以独立地变化。
C#实现示例:
/// <summary>
/// 实现部分的接口
/// </summary>
public interface IImplementation
{
string OperationImplementation();
}
/// <summary>
/// 具体实现A
/// </summary>
public class ConcreteImplementationA : IImplementation
{
public string OperationImplementation()
{
return "具体实现A的结果";
}
}
/// <summary>
/// 具体实现B
/// </summary>
public class ConcreteImplementationB : IImplementation
{
public string OperationImplementation()
{
return "具体实现B的结果";
}
}
/// <summary>
/// 抽象部分 - 定义抽象部分的接口
/// </summary>
public class Abstraction
{
protected IImplementation _implementation;
public Abstraction(IImplementation implementation)
{
_implementation = implementation;
}
public virtual string Operation()
{
return $"抽象: 基础操作与 {_implementation.OperationImplementation()}";
}
}
/// <summary>
/// 扩展的抽象 - 扩展抽象部分的接口
/// </summary>
public class ExtendedAbstraction : Abstraction
{
public ExtendedAbstraction(IImplementation implementation) : base(implementation)
{
}
public override string Operation()
{
return $"扩展抽象: 扩展操作与 {_implementation.OperationImplementation()}";
}
}
// 使用示例
public class Program
{
public static void Main()
{
// 创建实现
IImplementation implementationA = new ConcreteImplementationA();
IImplementation implementationB = new ConcreteImplementationB();
// 将抽象与实现组合在一起
Abstraction abstraction = new Abstraction(implementationA);
Console.WriteLine(abstraction.Operation());
// 改变实现
abstraction = new Abstraction(implementationB);
Console.WriteLine(abstraction.Operation());
// 使用扩展抽象
ExtendedAbstraction extendedAbstraction = new ExtendedAbstraction(implementationA);
Console.WriteLine(extendedAbstraction.Operation());
extendedAbstraction = new ExtendedAbstraction(implementationB);
Console.WriteLine(extendedAbstraction.Operation());
}
}
4.3 组合模式 (Composite)
组合模式将对象组合成树形结构,以表示"部分-整体"的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。
C#实现示例:
using System;
using System.Collections.Generic;
/// <summary>
/// 组件接口 - 组合中所有对象的通用接口
/// </summary>
public abstract class Component
{
protected string name;
public Component(string name)
{
this.name = name;
}
/// <summary>
/// 基本操作,所有组件必须实现
/// </summary>
public abstract string Operation();
/// <summary>
/// 添加组件的方法,默认实现是抛出异常
/// </summary>
public virtual void Add(Component component)
{
throw new NotImplementedException();
}
/// <summary>
/// 移除组件的方法,默认实现是抛出异常
/// </summary>
public virtual void Remove(Component component)
{
throw new NotImplementedException();
}
/// <summary>
/// 是否是复合组件
/// </summary>
public virtual bool IsComposite()
{
return false;
}
}
/// <summary>
/// 叶子节点 - 组合中的终端对象,没有子节点
/// </summary>
public class Leaf : Component
{
public Leaf(string name) : base(name)
{
}
public override string Operation()
{
return $"叶子 {name}";
}
}
/// <summary>
/// 复合组件 - 可以包含子组件的组件
/// </summary>
public class Composite : Component
{
protected List<Component> _children = new List<Component>();
public Composite(string name) : base(name)
{
}
/// <summary>
/// 添加子组件
/// </summary>
public override void Add(Component component)
{
_children.Add(component);
}
/// <summary>
/// 移除子组件
/// </summary>
public override void Remove(Component component)
{
_children.Remove(component);
}
/// <summary>
/// 执行组件操作,通常会递归调用所有子组件的操作
/// </summary>
public override string Operation()
{
int i = 0;
string result = $"分支 {name} (";
foreach (var component in _children)
{
result += component.Operation();
if (i != _children.Count - 1)
{
result += " + ";
}
i++;
}
return result + ")";
}
public override bool IsComposite()
{
return true;
}
}
// 使用示例
public class Program
{
public static void Main()
{
// 创建树形结构
// 创建根节点
Component root = new Composite("Root");
// 创建分支节点
Component branch1 = new Composite("Branch 1");
Component branch2 = new Composite("Branch 2");
// 创建叶子节点
Component leaf1 = new Leaf("Leaf 1");
Component leaf2 = new Leaf("Leaf 2");
Component leaf3 = new Leaf("Leaf 3");
// 组装树形结构
branch1.Add(leaf1);
branch1.Add(leaf2);
branch2.Add(leaf3);
root.Add(branch1);
root.Add(branch2);
// 直接使用根节点
Console.WriteLine("使用根节点:");
Console.WriteLine(root.Operation());
// 使用分支节点
Console.WriteLine("\n使用分支节点:");
Console.WriteLine(branch1.Operation());
// 使用叶子节点
Console.WriteLine("\n使用叶子节点:");
Console.WriteLine(leaf1.Operation());
}
}
4.4 装饰器模式 (Decorator)
装饰器模式动态地给一个对象添加一些额外的职责,比继承更灵活。
C#实现示例:
/// <summary>
/// 组件接口 - 定义装饰器和被装饰对象的公共接口
/// </summary>
public interface IComponent
{
string Operation();
}
/// <summary>
/// 具体组件 - 定义一个可以被装饰的对象
/// </summary>
public class ConcreteComponent : IComponent
{
public string Operation()
{
return "具体组件结果";
}
}
/// <summary>
/// 装饰器基类 - 维护一个对组件对象的引用
/// </summary>
public abstract class Decorator : IComponent
{
protected IComponent _component;
public Decorator(IComponent component)
{
_component = component;
}
// 装饰器将操作委托给组件
public virtual string Operation()
{
return _component.Operation();
}
}
/// <summary>
/// 具体装饰器A - 向组件添加责任
/// </summary>
public class ConcreteDecoratorA : Decorator
{
public ConcreteDecoratorA(IComponent component) : base(component)
{
}
// 在被装饰组件的操作前后添加自己的行为
public override string Operation()
{
return $"具体装饰器A({base.Operation()})";
}
}
/// <summary>
/// 具体装饰器B - 向组件添加责任
/// </summary>
public class ConcreteDecoratorB : Decorator
{
public ConcreteDecoratorB(IComponent component) : base(component)
{
}
// 在被装饰组件的操作前后添加自己的行为
public override string Operation()
{
return $"具体装饰器B({base.Operation()})";
}
// 装饰器B特有的方法
public string AddedBehavior()
{
return "添加的行为";
}
}
// 使用示例
public class Program
{
public static void Main()
{
// 创建一个简单组件
IComponent simple = new ConcreteComponent();
Console.WriteLine("简单组件结果:");
Console.WriteLine(simple.Operation());
// 用装饰器A装饰它
IComponent decorator1 = new ConcreteDecoratorA(simple);
Console.WriteLine("\n使用装饰器A的结果:");
Console.WriteLine(decorator1.Operation());
// 用装饰器B装饰装饰器A
IComponent decorator2 = new ConcreteDecoratorB(decorator1);
Console.WriteLine("\n使用装饰器B包装装饰器A的结果:");
Console.WriteLine(decorator2.Operation());
// 可以直接嵌套多个装饰器
IComponent decorator3 = new ConcreteDecoratorB(
new ConcreteDecoratorA(
new ConcreteComponent()));
Console.WriteLine("\n使用嵌套装饰器的结果:");
Console.WriteLine(decorator3.Operation());
}
}
4.5 外观模式 (Facade)
外观模式为子系统中的一组接口提供一个一致的界面,使得子系统更加容易使用。
C#实现示例:
/// <summary>
/// 子系统1 - 复杂子系统的一部分
/// </summary>
public class Subsystem1
{
public string Operation1()
{
return "子系统1: 准备就绪!";
}
public string OperationN()
{
return "子系统1: 开始运行!";
}
}
/// <summary>
/// 子系统2 - 复杂子系统的一部分
/// </summary>
public class Subsystem2
{
public string Operation1()
{
return "子系统2: 准备就绪!";
}
public string OperationZ()
{
return "子系统2: 开始运行!";
}
}
/// <summary>
/// 外观 - 提供简单接口访问复杂子系统
/// </summary>
public class Facade
{
protected Subsystem1 _subsystem1;
protected Subsystem2 _subsystem2;
/// <summary>
/// 外观可以接受已有的子系统对象或创建新的子系统对象
/// </summary>
public Facade(Subsystem1 subsystem1 = null, Subsystem2 subsystem2 = null)
{
_subsystem1 = subsystem1 ?? new Subsystem1();
_subsystem2 = subsystem2 ?? new Subsystem2();
}
/// <summary>
/// 外观提供简单的接口来运行复杂的子系统
/// </summary>
public string Operation()
{
string result = "外观初始化子系统:\n";
result += _subsystem1.Operation1();
result += "\n" + _subsystem2.Operation1();
result += "\n外观命令子系统执行操作:\n";
result += _subsystem1.OperationN();
result += "\n" + _subsystem2.OperationZ();
return result;
}
}
// 使用示例
public class Program
{
public static void Main()
{
// 外观可以与已存在的子系统一起工作
Subsystem1 subsystem1 = new Subsystem1();
Subsystem2 subsystem2 = new Subsystem2();
Facade facade = new Facade(subsystem1, subsystem2);
Console.WriteLine(facade.Operation());
// 外观可以创建并配置子系统
Facade facade2 = new Facade();
Console.WriteLine("\n使用自动创建的子系统:");
Console.WriteLine(facade2.Operation());
}
}
4.6 享元模式 (Flyweight)
享元模式通过共享尽可能多的相似对象来最小化内存使用和对象创建的开销。
C#实现示例:
using System;
using System.Collections.Generic;
/// <summary>
/// 享元接口 - 定义享元对象接受外部状态的方法
/// </summary>
public interface IFlyweight
{
void Operation(string extrinsicState);
}
/// <summary>
/// 具体享元 - 存储内部状态并实现享元接口
/// </summary>
public class ConcreteFlyweight : IFlyweight
{
private readonly string _intrinsicState;
public ConcreteFlyweight(string intrinsicState)
{
_intrinsicState = intrinsicState;
}
public void Operation(string extrinsicState)
{
Console.WriteLine($"具体享元: 内部状态 = {_intrinsicState}, 外部状态 = {extrinsicState}");
}
}
/// <summary>
/// 享元工厂 - 创建并管理享元对象
/// </summary>
public class FlyweightFactory
{
private Dictionary<string, IFlyweight> _flyweights = new Dictionary<string, IFlyweight>();
public FlyweightFactory()
{
// 初始化一些常用的享元对象
_flyweights.Add("X", new ConcreteFlyweight("共享 X"));
_flyweights.Add("Y", new ConcreteFlyweight("共享 Y"));
_flyweights.Add("Z", new ConcreteFlyweight("共享 Z"));
}
/// <summary>
/// 返回一个现有的享元或创建一个新的享元
/// </summary>
public IFlyweight GetFlyweight(string key)
{
if (!_flyweights.ContainsKey(key))
{
Console.WriteLine($"FlyweightFactory: 找不到键为 {key} 的享元,创建新实例。");
_flyweights.Add(key, new ConcreteFlyweight($"共享 {key}"));
}
else
{
Console.WriteLine($"FlyweightFactory: 重用现有的享元,键为 {key}。");
}
return _flyweights[key];
}
/// <summary>
/// 列出所有享元
/// </summary>
public void ListFlyweights()
{
int count = _flyweights.Count;
Console.WriteLine($"\n工厂中的享元数量: {count}");
foreach (var key in _flyweights.Keys)
{
Console.WriteLine(key);
}
}
}
// 使用示例
public class Program
{
public static void Main()
{
// 客户端代码通常会创建一堆预初始化的享元
var factory = new FlyweightFactory();
factory.ListFlyweights();
// 使用现有的享元
Console.WriteLine("\n使用现有的享元:");
IFlyweight fx = factory.GetFlyweight("X");
fx.Operation("客户端外部状态A");
// 重用现有的享元
Console.WriteLine("\n重用现有的享元:");
IFlyweight fy = factory.GetFlyweight("Y");
fy.Operation("客户端外部状态B");
// 创建新的享元
Console.WriteLine("\n创建新的享元:");
IFlyweight fw = factory.GetFlyweight("W");
fw.Operation("客户端外部状态C");
factory.ListFlyweights();
}
}
4.7 代理模式 (Proxy)
代理模式为另一个对象提供一个替身或占位符,以控制对这个对象的访问。
C#实现示例:
/// <summary>
/// 主题接口 - 代理和实际主题共同的接口
/// </summary>
public interface ISubject
{
void Request();
}
/// <summary>
/// 实际主题 - 定义代理所代表的真实对象
/// </summary>
public class RealSubject : ISubject
{
public void Request()
{
Console.WriteLine("RealSubject: 处理请求");
}
}
/// <summary>
/// 代理 - 保存一个引用,使代理可以访问实际主题
/// </summary>
public class Proxy : ISubject
{
private RealSubject _realSubject;
/// <summary>
/// 根据需要创建或使用已有的实际主题
/// </summary>
public Proxy(RealSubject realSubject = null)
{
_realSubject = realSubject ?? new RealSubject();
}
/// <summary>
/// 代理的请求方法可以在转发调用前后执行附加工作
/// </summary>
public void Request()
{
if (CheckAccess())
{
// 可以在调用RealSubject之前做一些事情
_realSubject.Request();
// 可以在调用RealSubject之后做一些事情
LogAccess();
}
}
/// <summary>
/// 检查是否允许访问实际主题
/// </summary>
private bool CheckAccess()
{
// 这里可以有一些真实的检查逻辑
Console.WriteLine("Proxy: 检查访问权限");
return true;
}
/// <summary>
/// 记录对实际主题的访问
/// </summary>
private void LogAccess()
{
Console.WriteLine("Proxy: 记录访问时间");
}
}
// 使用示例
public class Program
{
public static void Main()
{
Console.WriteLine("客户端: 直接使用实际主题");
RealSubject realSubject = new RealSubject();
realSubject.Request();
Console.WriteLine("\n客户端: 通过代理使用实际主题");
Proxy proxy = new Proxy();
proxy.Request();
}
}
5. 行为型设计模式
行为型设计模式关注对象之间的通信和责任分配。它们帮助定义对象之间通信的方式,以及不同对象间如何协作以完成特定任务。
5.1 观察者模式 (Observer)
观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
C#实现示例:
using System;
using System.Collections.Generic;
/// <summary>
/// 主题接口 - 定义添加、删除和通知观察者的操作
/// </summary>
public interface ISubject
{
void Attach(IObserver observer);
void Detach(IObserver observer);
void Notify();
}
/// <summary>
/// 观察者接口 - 定义更新方法
/// </summary>
public interface IObserver
{
void Update(ISubject subject);
}
/// <summary>
/// 具体主题 - 维护状态并通知观察者变化
/// </summary>
public class ConcreteSubject : ISubject
{
// 状态,当它改变时通知观察者
private string _state;
// 观察者列表
private List<IObserver> _observers = new List<IObserver>();
// 状态属性
public string State
{
get { return _state; }
set
{
_state = value;
// 状态变化时通知观察者
Notify();
}
}
// 添加观察者
public void Attach(IObserver observer)
{
Console.WriteLine("主题: 添加一个观察者");
_observers.Add(observer);
}
// 移除观察者
public void Detach(IObserver observer)
{
_observers.Remove(observer);
Console.WriteLine("主题: 移除一个观察者");
}
// 通知所有观察者
public void Notify()
{
Console.WriteLine("主题: 通知观察者...");
foreach (var observer in _observers)
{
observer.Update(this);
}
}
// 一些业务逻辑
public void SomeBusinessLogic()
{
Console.WriteLine("\n主题: 我在做一些重要的事情");
this.State = $"状态已更改为: {DateTime.Now}";
}
}
/// <summary>
/// 具体观察者A - 实现更新接口
/// </summary>
public class ConcreteObserverA : IObserver
{
public void Update(ISubject subject)
{
if (subject is ConcreteSubject concreteSubject)
{
Console.WriteLine($"具体观察者A: 对新状态做出反应: {concreteSubject.State}");
}
}
}
/// <summary>
/// 具体观察者B - 实现更新接口
/// </summary>
public class ConcreteObserverB : IObserver
{
public void Update(ISubject subject)
{
if (subject is ConcreteSubject concreteSubject)
{
Console.WriteLine($"具体观察者B: 对新状态做出反应: {concreteSubject.State}");
}
}
}
// 使用示例
public class Program
{
public static void Main()
{
// 创建主题
var subject = new ConcreteSubject();
// 创建观察者
var observerA = new ConcreteObserverA();
var observerB = new ConcreteObserverB();
// 订阅
subject.Attach(observerA);
subject.Attach(observerB);
// 改变状态
subject.SomeBusinessLogic();
// 取消订阅
subject.Detach(observerB);
// 再次改变状态
subject.SomeBusinessLogic();
}
}
5.2 策略模式 (Strategy)
策略模式定义一系列算法,将每个算法封装起来,并使它们可以相互替换。此模式使得算法可以独立于使用它的客户而变化。
C#实现示例:
/// <summary>
/// 策略接口 - 定义算法族的共同接口
/// </summary>
public interface IStrategy
{
string Execute(string data);
}
/// <summary>
/// 具体策略A - 定义具体算法
/// </summary>
public class ConcreteStrategyA : IStrategy
{
public string Execute(string data)
{
// 具体算法A的实现
return $"使用策略A处理数据: {data.ToUpper()}";
}
}
/// <summary>
/// 具体策略B - 定义具体算法
/// </summary>
public class ConcreteStrategyB : IStrategy
{
public string Execute(string data)
{
// 具体算法B的实现
return $"使用策略B处理数据: {new string(data.ToCharArray().Reverse().ToArray())}";
}
}
/// <summary>
/// 具体策略C - 定义具体算法
/// </summary>
public class ConcreteStrategyC : IStrategy
{
public string Execute(string data)
{
// 具体算法C的实现
return $"使用策略C处理数据: {string.Join(" ", data.ToCharArray())}";
}
}
/// <summary>
/// 上下文 - 维护对策略对象的引用
/// </summary>
public class Context
{
// 当前使用的策略
private IStrategy _strategy;
// 可以在构造函数中设置初始策略
public Context(IStrategy strategy = null)
{
_strategy = strategy;
}
// 允许在运行时更改策略
public void SetStrategy(IStrategy strategy)
{
_strategy = strategy;
}
// 委托策略执行算法
public string ExecuteStrategy(string data)
{
if (_strategy == null)
{
return "未设置策略";
}
return _strategy.Execute(data);
}
}
// 使用示例
public class Program
{
public static void Main()
{
// 创建上下文
var context = new Context();
// 设置并执行策略A
context.SetStrategy(new ConcreteStrategyA());
Console.WriteLine(context.ExecuteStrategy("Hello, World!"));
// 改变策略为B
context.SetStrategy(new ConcreteStrategyB());
Console.WriteLine(context.ExecuteStrategy("Hello, World!"));
// 改变策略为C
context.SetStrategy(new ConcreteStrategyC());
Console.WriteLine(context.ExecuteStrategy("Hello, World!"));
}
}
5.3 模板方法模式 (Template Method)
模板方法模式在一个方法中定义一个算法的骨架,将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的特定步骤。
C#实现示例:
/// <summary>
/// 抽象类 - 定义算法骨架
/// </summary>
public abstract class AbstractClass
{
// 模板方法,定义算法的骨架
public void TemplateMethod()
{
Console.WriteLine("AbstractClass: 算法已开始");
PrimitiveOperation1();
PrimitiveOperation2();
Hook();
Console.WriteLine("AbstractClass: 算法已结束");
}
// 原始操作1 - 必须由子类实现
protected abstract void PrimitiveOperation1();
// 原始操作2 - 必须由子类实现
protected abstract void PrimitiveOperation2();
// 钩子方法 - 子类可以选择性地覆盖
protected virtual void Hook() { }
}
/// <summary>
/// 具体类A - 实现原始操作
/// </summary>
public class ConcreteClassA : AbstractClass
{
protected override void PrimitiveOperation1()
{
Console.WriteLine("ConcreteClassA: 实现操作1");
}
protected override void PrimitiveOperation2()
{
Console.WriteLine("ConcreteClassA: 实现操作2");
}
}
/// <summary>
/// 具体类B - 实现原始操作并覆盖钩子
/// </summary>
public class ConcreteClassB : AbstractClass
{
protected override void PrimitiveOperation1()
{
Console.WriteLine("ConcreteClassB: 实现操作1");
}
protected override void PrimitiveOperation2()
{
Console.WriteLine("ConcreteClassB: 实现操作2");
}
// 覆盖钩子方法
protected override void Hook()
{
Console.WriteLine("ConcreteClassB: 覆盖了钩子方法");
}
}
// 使用示例
public class Program
{
public static void Main()
{
Console.WriteLine("使用具体类A:");
AbstractClass abstractClass = new ConcreteClassA();
abstractClass.TemplateMethod();
Console.WriteLine("\n使用具体类B:");
abstractClass = new ConcreteClassB();
abstractClass.TemplateMethod();
}
}
5.4 命令模式 (Command)
命令模式将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
C#实现示例:
using System;
using System.Collections.Generic;
/// <summary>
/// 命令接口 - 声明执行和撤销操作
/// </summary>
public interface ICommand
{
void Execute();
void Undo();
}
/// <summary>
/// 接收者 - 知道如何执行与命令相关的操作
/// </summary>
public class Receiver
{
public void Action(string action)
{
Console.WriteLine($"接收者: 执行 {action}");
}
}
/// <summary>
/// 具体命令 - 将接收者和动作绑定在一起
/// </summary>
public class ConcreteCommand : ICommand
{
private readonly Receiver _receiver;
private readonly string _action;
public ConcreteCommand(Receiver receiver, string action)
{
_receiver = receiver;
_action = action;
}
// 调用接收者的相关操作
public void Execute()
{
Console.WriteLine($"命令: 调用接收者执行 {_action}");
_receiver.Action(_action);
}
// 撤销操作
public void Undo()
{
Console.WriteLine($"命令: 撤销接收者的 {_action}");
_receiver.Action($"撤销 {_action}");
}
}
/// <summary>
/// 调用者 - 请求命令执行请求
/// </summary>
public class Invoker
{
private ICommand _command;
// 设置要执行的命令
public void SetCommand(ICommand command)
{
_command = command;
}
// 执行命令
public void ExecuteCommand()
{
if (_command != null)
{
Console.WriteLine("调用者: 执行命令");
_command.Execute();
}
}
// 撤销命令
public void UndoCommand()
{
if (_command != null)
{
Console.WriteLine("调用者: 撤销命令");
_command.Undo();
}
}
}
// 使用示例
public class Program
{
public static void Main()
{
// 创建接收者
var receiver = new Receiver();
// 创建命令并绑定接收者
var command = new ConcreteCommand(receiver, "某个行动");
// 创建调用者并设置命令
var invoker = new Invoker();
invoker.SetCommand(command);
// 执行和撤销命令
invoker.ExecuteCommand();
invoker.UndoCommand();
}
}
5.5 迭代器模式 (Iterator)
迭代器模式提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
C#实现示例:
using System;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// 迭代器接口 - 在C#中通常使用内置的IEnumerable和IEnumerator接口
/// </summary>
public interface ICustomIterator<T>
{
bool MoveNext();
void Reset();
T Current { get; }
}
/// <summary>
/// 集合接口 - 在C#中通常使用内置的IEnumerable接口
/// </summary>
public interface ICustomCollection<T>
{
ICustomIterator<T> CreateIterator();
}
/// <summary>
/// 具体集合 - 存储元素并创建迭代器
/// </summary>
public class ConcreteCollection<T> : ICustomCollection<T>
{
private List<T> _items = new List<T>();
// 添加项
public void AddItem(T item)
{
_items.Add(item);
}
// 创建迭代器
public ICustomIterator<T> CreateIterator()
{
return new ConcreteIterator<T>(this);
}
// 获取项数量
public int Count
{
get { return _items.Count; }
}
// 通过索引访问项
public T this[int index]
{
get { return _items[index]; }
}
}
/// <summary>
/// 具体迭代器 - 实现迭代接口
/// </summary>
public class ConcreteIterator<T> : ICustomIterator<T>
{
private readonly ConcreteCollection<T> _collection;
private int _current = 0;
public ConcreteIterator(ConcreteCollection<T> collection)
{
_collection = collection;
}
// 移动到下一项
public bool MoveNext()
{
return ++_current < _collection.Count;
}
// 重置迭代器
public void Reset()
{
_current = 0;
}
// 获取当前项
public T Current
{
get { return _collection[_current]; }
}
}
/// <summary>
/// 使用C#内置集合接口的集合
/// </summary>
public class BuiltInCollection<T> : IEnumerable<T>
{
private List<T> _items = new List<T>();
// 添加项
public void AddItem(T item)
{
_items.Add(item);
}
// 实现IEnumerable接口
public IEnumerator<T> GetEnumerator()
{
return _items.GetEnumerator();
}
// 显式实现IEnumerable接口
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
// 使用示例
public class Program
{
public static void Main()
{
// 使用自定义迭代器接口
Console.WriteLine("使用自定义迭代器:");
var collection = new ConcreteCollection<string>();
collection.AddItem("项目 A");
collection.AddItem("项目 B");
collection.AddItem("项目 C");
var iterator = collection.CreateIterator();
// 手动迭代
Console.WriteLine(iterator.Current);
while (iterator.MoveNext())
{
Console.WriteLine(iterator.Current);
}
// 使用C#内置集合接口
Console.WriteLine("\n使用C#内置集合接口:");
var builtInCollection = new BuiltInCollection<string>();
builtInCollection.AddItem("项目 X");
builtInCollection.AddItem("项目 Y");
builtInCollection.AddItem("项目 Z");
// 使用foreach语法糖自动迭代
foreach (var item in builtInCollection)
{
Console.WriteLine(item);
}
}
}
5.6 状态模式 (State)
状态模式允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
C#实现示例:
/// <summary>
/// 上下文 - 保存当前状态并委托状态相关的行为
/// </summary>
public class Context
{
// 当前状态
private IState _state;
public Context(IState initialState)
{
TransitionTo(initialState);
}
/// <summary>
/// 转换到新状态
/// </summary>
public void TransitionTo(IState state)
{
Console.WriteLine($"上下文: 转换到 {state.GetType().Name}");
_state = state;
_state.SetContext(this);
}
/// <summary>
/// 委托行为给当前状态
/// </summary>
public void Request1()
{
_state.Handle1();
}
public void Request2()
{
_state.Handle2();
}
}
/// <summary>
/// 状态接口 - 声明与上下文的交互方法
/// </summary>
public interface IState
{
void SetContext(Context context);
void Handle1();
void Handle2();
}
/// <summary>
/// 具体状态A
/// </summary>
public class ConcreteStateA : IState
{
private Context _context;
public void SetContext(Context context)
{
_context = context;
}
public void Handle1()
{
Console.WriteLine("ConcreteStateA处理请求1。");
// 可以在这里改变上下文的状态
}
public void Handle2()
{
Console.WriteLine("ConcreteStateA处理请求2。");
Console.WriteLine("ConcreteStateA改变上下文的状态为B。");
_context.TransitionTo(new ConcreteStateB());
}
}
/// <summary>
/// 具体状态B
/// </summary>
public class ConcreteStateB : IState
{
private Context _context;
public void SetContext(Context context)
{
_context = context;
}
public void Handle1()
{
Console.WriteLine("ConcreteStateB处理请求1。");
Console.WriteLine("ConcreteStateB改变上下文的状态为A。");
_context.TransitionTo(new ConcreteStateA());
}
public void Handle2()
{
Console.WriteLine("ConcreteStateB处理请求2。");
}
}
// 使用示例
public class Program
{
public static void Main()
{
// 创建上下文并设置初始状态
var context = new Context(new ConcreteStateA());
// 执行请求,会委托给当前状态处理
Console.WriteLine("客户端: 执行请求1");
context.Request1();
Console.WriteLine("\n客户端: 执行请求2");
context.Request2();
// 上下文已经转换到B状态
Console.WriteLine("\n客户端: 执行请求1");
context.Request1();
// 上下文又回到A状态
Console.WriteLine("\n客户端: 执行请求2");
context.Request2();
}
}
6. 总结与展望
6.1 设计模式的优缺点
设计模式作为软件开发中的最佳实践,具有明显的优点:
- 提高代码质量:设计模式遵循面向对象设计原则,有助于创建松耦合、高内聚的代码
- 加快开发速度:提供了经过验证的解决方案,避免从零开始解决常见问题
- 增强代码维护性:通过标准化和模块化,使代码更易于理解和修改
- 促进团队协作:提供共同的词汇和理解,改善团队沟通
然而,设计模式并非万能,也存在一些潜在的缺点:
- 过度使用:不必要地应用设计模式会增加代码的复杂性
- 性能开销:某些设计模式可能引入额外的抽象层,导致性能下降
- 学习曲线:理解和正确应用设计模式需要时间和经验
- 上下文依赖:设计模式的适用性取决于具体问题和上下文
6.2 选择合适的设计模式
选择正确的设计模式是一项重要的决策,应考虑以下因素:
- 问题特性:理解问题的本质和约束
- 设计目标:明确系统的质量属性(可扩展性、可维护性等)
- 权衡取舍:考虑模式的优缺点与当前需求的匹配度
- 团队经验:考虑团队对特定模式的熟悉程度
- 系统上下文:考虑与现有系统架构的兼容性
6.3 设计模式的演进
设计模式并非静态不变,它们随着技术和范式的变化而演进:
- 函数式编程的普及带来了新的设计模式和对传统模式的重新诠释
- 微服务架构催生了分布式系统特有的设计模式
- 响应式编程引入了处理异步数据流的新模式
- 领域驱动设计融合了多种设计模式,形成了更高层次的架构模式
6.4 学习资源
以下是深入学习设计模式的优质资源:
在线资源:
- Refactoring.Guru - 设计模式的详细解释和代码示例
- Microsoft Learn - .NET架构原则和设计模式
- SourceMaking - 设计模式、反模式和重构
- dofactory - .NET设计模式示例和实践
社区和论坛:
7. 结语
设计模式是软件开发中不可或缺的知识体系,尤其对于C#这样成熟的面向对象语言来说更是如此。深入理解和正确应用设计模式,能够帮助开发者创建更加灵活、可维护的软件系统。
然而,设计模式不应被视为教条,而应作为工具和指导原则。最重要的是理解问题的本质和设计原则,然后选择或调整适当的模式来解决特定问题。