设计模式是软件设计与开发过程中常见问题的可复用解决方案。它们是通用模板或最佳实践,用于指导开发人员创建结构良好、可维护且高效的代码。
以下是.NET中一些常用的设计模式:
单例模式 描述:确保一个类只有一个实例,并提供一个全局访问点来访问该实例。 用法:当你需要对某个对象提供单一的全局访问点时(例如配置管理器或日志记录器),此模式很有用。
public class Singleton
{
private static readonly Singleton _instance = new Singleton();
private Singleton() { }
public static Singleton Instance => _instance;
}
示例:一个日志记录器类,为整个应用程序提供单一的全局实例用于记录日志。
public sealed class Logger
{
private static readonly Logger instance = new Logger();
private Logger()
{
// 私有构造函数,防止直接实例化
}
public static Logger Instance
{
get { return instance; }
}
public void Log(string message)
{
// 日志记录逻辑
Console.WriteLine(message);
}
}
使用方法:
Logger.Instance.Log("This is a log message.");
工厂模式 描述:提供一个用于创建对象的接口,同时允许子类改变将要创建的对象类型。 用法:当你需要创建对象,但不想向客户端暴露创建逻辑时,或者当你想提供一种创建相关对象却又不指定其具体类的方式时,该模式很有帮助。
public interface IProduct
{
void DoSomething();
}
public class ProductA : IProduct
{
public void DoSomething() { Console.WriteLine("Product A"); }
}
public class ProductB : IProduct
{
public void DoSomething() { Console.WriteLine("Product B"); }
}
public class ProductFactory
{
public static IProduct CreateProduct(string type)
{
return type switch
{
"A" => new ProductA(),
"B" => new ProductB(),
_ => throw new ArgumentException("Invalid type"),
};
}
}
示例:一个工厂类,根据指定的提供程序创建不同类型的数据库连接。
public interface IDatabaseConnection
{
void Connect();
}
public class SqlServerConnection : IDatabaseConnection
{
public void Connect()
{
// SQL Server连接逻辑
}
}
public class MySqlConnection : IDatabaseConnection
{
public void Connect()
{
// MySQL连接逻辑
}
}
public static class DatabaseConnectionFactory
{
public static IDatabaseConnection CreateConnection(string provider)
{
if (provider == "SqlServer")
return new SqlServerConnection();
else if (provider == "MySql")
return new MySqlConnection();
else
throw new ArgumentException("Invalid provider");
}
}
使用方法:
IDatabaseConnection connection = DatabaseConnectionFactory.CreateConnection("SqlServer");
connection.Connect();
适配器模式 描述:将一个类的接口转换为客户端期望的另一个接口。允许接口不兼容的类协同工作。 用法:当你有一个类需要与另一个类交互,但接口不匹配时很有用。适配器模式可用于弥合两者之间的差距。 示例:一个适配器类,允许在应用程序中使用第三方日志记录库。
public class ThirdPartyLogger
{
public void LogMessage(string message)
{
// 第三方日志记录逻辑
Console.WriteLine($"Third-Party Logger: {message}");
}
}
public class LoggerAdapter : ILogger
{
private readonly ThirdPartyLogger _thirdPartyLogger;
public LoggerAdapter(ThirdPartyLogger thirdPartyLogger)
{
_thirdPartyLogger = thirdPartyLogger;
}
public void Log(string message)
{
_thirdPartyLogger.LogMessage(message);
}
}
public interface ILogger
{
void Log(string message);
}
使用方法:
var thirdPartyLogger = new ThirdPartyLogger();
ILogger logger = new LoggerAdapter(thirdPartyLogger);
logger.Log("This is a log message.");
观察者模式 描述:定义对象之间的一对多依赖关系,以便当一个对象状态改变时,所有依赖它的对象都会自动收到通知并更新。 用法:在需要当另一个对象的状态改变时更新多个依赖对象的场景中很有帮助,例如在事件驱动编程或发布-订阅模型中。
public class Subject
{
private readonly List<IObserver> _observers = new List<IObserver>();
public void Attach(IObserver observer) => _observers.Add(observer);
public void Notify() => _observers.ForEach(o => o.Update());
}
public interface IObserver
{
void Update();
}
public class ConcreteObserver : IObserver
{
public void Update() { Console.WriteLine("Observer updated!"); }
}
装饰器模式 描述:动态地给对象附加额外的职责。装饰器为扩展功能提供了一种比继承更灵活的替代方案。 用法:当你需要在运行时给对象添加或移除职责,且不影响对象的核心功能时很有用。
命令模式 描述:将请求封装为一个对象,从而允许使用不同请求对客户端进行参数化、对请求进行排队或记录日志,并支持可撤销操作。 用法:在需要将操作的调用者与执行操作的对象分离的场景中很有帮助,例如在撤销/重做功能或事件驱动架构中。
仓储模式 描述:在应用程序的数据访问层和业务逻辑层之间提供一个抽象层。 用法:有助于以一种独立于底层数据源的方式管理数据访问,使得在不同数据源之间切换或测试应用程序的数据访问逻辑更加容易。
public interface IRepository<T>
{
IEnumerable<T> GetAll();
void Add(T item);
}
public class InMemoryRepository<T> : IRepository<T>
{
private readonly List<T> _items = new List<T>();
public IEnumerable<T> GetAll() => _items;
public void Add(T item) => _items.Add(item);
}
策略模式 描述:定义一系列算法,将每个算法封装起来并使它们可互换。
public interface IStrategy
{
int Execute(int a, int b);
}
public class Addition : IStrategy
{
public int Execute(int a, int b) => a + b;
}
public class Subtraction : IStrategy
{
public int Execute(int a, int b) => a - b;
}
public class Context
{
private IStrategy _strategy;
public void SetStrategy(IStrategy strategy) => _strategy = strategy;
public int ExecuteStrategy(int a, int b) => _strategy.Execute(a, b);
}
如果你喜欢我的文章,请给我一个赞!谢谢