面试题答案
一键面试抽象策略类构造函数对策略模式可扩展性和灵活性的影响
- 可扩展性:
- 正向影响:如果抽象策略类构造函数接受一些通用的参数,比如与策略执行相关的配置信息等,那么子类在继承时可以直接复用这些参数设置逻辑。这使得新增策略类时,只需关注自身独特的策略实现,而无需重复处理这些通用配置的初始化,从而增强了可扩展性。例如,一个绘图策略抽象类,其构造函数接受绘图颜色配置参数,所有具体绘图策略子类继承时就可以直接使用该颜色配置,新的绘图策略子类也能方便地复用这一配置初始化逻辑。
- 负向影响:若抽象策略类构造函数过于复杂,或者依赖过多具体实现细节,会导致新增策略类时受到限制。例如构造函数依赖于特定的硬件环境参数,而新的策略可能运行在不同硬件环境下,这就会影响可扩展性。
- 灵活性:
- 正向影响:通过构造函数传递不同的依赖对象,可以使策略在运行时具有不同的行为。例如,抽象策略类构造函数接受一个日志记录器对象,不同策略类在构造时传入不同的日志记录器实现(如文件日志记录器、数据库日志记录器),从而在执行策略过程中实现不同的日志记录方式,增加了灵活性。
- 负向影响:如果构造函数参数定义过于僵化,不允许动态变化,会降低灵活性。比如构造函数只接受固定类型的参数,不支持运行时动态替换,就无法根据不同场景灵活调整策略行为。
优化策略模式的设计思路
- 依赖注入:通过抽象策略类构造函数进行依赖注入,将策略执行所依赖的对象传递进来。这样可以使策略类与依赖对象解耦,增强灵活性和可测试性。
- 设置默认参数:在抽象策略类构造函数中设置合理的默认参数,对于大多数常见场景,子类无需额外设置这些参数,简化子类构造。但对于特殊场景,子类可以通过覆盖或传入不同参数来改变默认行为。
代码实现示例(以Python为例)
from abc import ABC, abstractmethod
class AbstractStrategy(ABC):
def __init__(self, logger=None):
self.logger = logger
@abstractmethod
def execute(self):
pass
class ConcreteStrategyA(AbstractStrategy):
def execute(self):
if self.logger:
self.logger.log('Executing Strategy A')
print('Strategy A executed')
class ConcreteStrategyB(AbstractStrategy):
def execute(self):
if self.logger:
self.logger.log('Executing Strategy B')
print('Strategy B executed')
class Logger:
def log(self, message):
print(f'Log: {message}')
# 使用示例
logger = Logger()
strategy_a = ConcreteStrategyA(logger)
strategy_b = ConcreteStrategyB(logger)
strategy_a.execute()
strategy_b.execute()
在上述代码中,AbstractStrategy
抽象类的构造函数接受一个logger
参数,通过依赖注入的方式,具体策略类ConcreteStrategyA
和ConcreteStrategyB
在执行策略时可以利用传入的logger
进行日志记录,增强了灵活性。同时,对于不需要日志记录的场景,也可以不传入logger
,通过设置默认参数None
保证了灵活性。