面试题答案
一键面试1. 代理模式
- 应用场景:在用户认证模块中,为了保护核心认证逻辑不被直接访问,并且可以在访问前后添加额外逻辑(如日志记录、权限检查等),可以使用代理模式。
- C#代码片段:
public interface IUserAuthenticator
{
bool Authenticate(string username, string password);
}
public class UserAuthenticator : IUserAuthenticator
{
public bool Authenticate(string username, string password)
{
// 实际认证逻辑
return username == "admin" && password == "123456";
}
}
public class UserAuthenticatorProxy : IUserAuthenticator
{
private readonly IUserAuthenticator _authenticator;
public UserAuthenticatorProxy()
{
_authenticator = new UserAuthenticator();
}
public bool Authenticate(string username, string password)
{
Console.WriteLine($"尝试认证用户: {username}");
bool result = _authenticator.Authenticate(username, password);
Console.WriteLine($"认证结果: {result}");
return result;
}
}
- 在系统中的作用:通过代理模式,在不修改原有认证逻辑的基础上,增加了额外的功能,提高了系统的可维护性。同时,如果认证逻辑有变化,只需要修改
UserAuthenticator
类,代理类不需要大量修改,提高了可扩展性。
2. 观察者模式
- 应用场景:在订单处理模块中,当订单状态发生变化时,可能需要通知多个其他模块(如库存模块更新库存、物流模块安排发货等)。此时可以使用观察者模式。
- C#代码片段:
public delegate void OrderStatusChangedEventHandler(Order order);
public class Order
{
private string _status;
public event OrderStatusChangedEventHandler StatusChanged;
public string Status
{
get => _status;
set
{
_status = value;
StatusChanged?.Invoke(this);
}
}
}
public class InventoryModule
{
public void UpdateInventory(Order order)
{
Console.WriteLine($"库存模块: 订单 {order} 状态改变,更新库存。");
}
}
public class LogisticsModule
{
public void ArrangeDelivery(Order order)
{
Console.WriteLine($"物流模块: 订单 {order} 状态改变,安排发货。");
}
}
使用示例:
class Program
{
static void Main()
{
Order order = new Order();
InventoryModule inventory = new InventoryModule();
LogisticsModule logistics = new LogisticsModule();
order.StatusChanged += inventory.UpdateInventory;
order.StatusChanged += logistics.ArrangeDelivery;
order.Status = "已支付";
}
}
- 在系统中的作用:观察者模式使得订单处理模块与其他依赖模块解耦,当有新的模块需要监听订单状态变化时,只需要注册为观察者即可,提高了系统的可扩展性。同时,各个模块的职责更加清晰,便于维护。
3. 单例模式
- 应用场景:数据缓存模块通常需要在整个应用程序中共享,以确保数据的一致性和避免重复创建缓存实例带来的性能开销,适合使用单例模式。
- C#代码片段:
public class DataCache
{
private static DataCache _instance;
private static readonly object _lock = new object();
private Dictionary<string, object> _cache = new Dictionary<string, object>();
private DataCache()
{
}
public static DataCache Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
{
_instance = new DataCache();
}
}
}
return _instance;
}
}
public void Set(string key, object value)
{
_cache[key] = value;
}
public object Get(string key)
{
return _cache.ContainsKey(key)? _cache[key] : null;
}
}
- 在系统中的作用:单例模式保证了数据缓存实例在整个应用程序中唯一,避免了资源浪费,提高了性能。同时,由于只有一个实例,所有模块对缓存的操作都是一致的,便于维护和管理。
三种设计模式的交互
- 在实际系统中,代理模式中的
UserAuthenticatorProxy
在认证成功后,可以使用单例模式的DataCache.Instance
将认证信息缓存起来,减少后续认证请求的处理时间,提高性能。 - 当订单处理模块中的订单状态改变时,通过观察者模式通知相关模块。例如,库存模块在更新库存前,可以先从单例的
DataCache.Instance
中获取当前库存信息,避免重复查询数据库,提高系统性能。同时,库存模块和物流模块也可以通过代理模式来访问订单处理模块,在访问前后添加日志记录等额外逻辑。这样,三种设计模式相互协作,共同优化系统架构,提高系统的可扩展性、可维护性和性能。