MST

星途 面试题库

面试题:C++ 抽象类构造函数在策略模式优化中的考量

在策略模式中,若不同的策略类继承自同一个抽象策略类,抽象策略类的构造函数对于策略模式的可扩展性和灵活性有何影响?请分析并给出在特定场景下,通过抽象类构造函数优化策略模式的设计思路及相应代码实现。
40.0万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

抽象策略类构造函数对策略模式可扩展性和灵活性的影响

  1. 可扩展性
    • 正向影响:如果抽象策略类构造函数接受一些通用的参数,比如与策略执行相关的配置信息等,那么子类在继承时可以直接复用这些参数设置逻辑。这使得新增策略类时,只需关注自身独特的策略实现,而无需重复处理这些通用配置的初始化,从而增强了可扩展性。例如,一个绘图策略抽象类,其构造函数接受绘图颜色配置参数,所有具体绘图策略子类继承时就可以直接使用该颜色配置,新的绘图策略子类也能方便地复用这一配置初始化逻辑。
    • 负向影响:若抽象策略类构造函数过于复杂,或者依赖过多具体实现细节,会导致新增策略类时受到限制。例如构造函数依赖于特定的硬件环境参数,而新的策略可能运行在不同硬件环境下,这就会影响可扩展性。
  2. 灵活性
    • 正向影响:通过构造函数传递不同的依赖对象,可以使策略在运行时具有不同的行为。例如,抽象策略类构造函数接受一个日志记录器对象,不同策略类在构造时传入不同的日志记录器实现(如文件日志记录器、数据库日志记录器),从而在执行策略过程中实现不同的日志记录方式,增加了灵活性。
    • 负向影响:如果构造函数参数定义过于僵化,不允许动态变化,会降低灵活性。比如构造函数只接受固定类型的参数,不支持运行时动态替换,就无法根据不同场景灵活调整策略行为。

优化策略模式的设计思路

  1. 依赖注入:通过抽象策略类构造函数进行依赖注入,将策略执行所依赖的对象传递进来。这样可以使策略类与依赖对象解耦,增强灵活性和可测试性。
  2. 设置默认参数:在抽象策略类构造函数中设置合理的默认参数,对于大多数常见场景,子类无需额外设置这些参数,简化子类构造。但对于特殊场景,子类可以通过覆盖或传入不同参数来改变默认行为。

代码实现示例(以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参数,通过依赖注入的方式,具体策略类ConcreteStrategyAConcreteStrategyB在执行策略时可以利用传入的logger进行日志记录,增强了灵活性。同时,对于不需要日志记录的场景,也可以不传入logger,通过设置默认参数None保证了灵活性。