面试题答案
一键面试1. 类结构
- 抽象基类:定义了一系列算法的抽象接口。例如,在策略模式中,可命名为
Strategy
抽象基类。 - 具体派生类:继承自抽象基类,实现具体的算法策略。如
ConcreteStrategyA
、ConcreteStrategyB
等。 - 上下文类:持有一个抽象基类的指针或引用,用于调用具体策略。
2. 成员函数
- 抽象基类:
- 包含纯虚函数,这些函数定义了具体策略需要实现的接口。例如
virtual void execute() = 0;
,不同的策略将以不同方式实现此execute
函数。
- 包含纯虚函数,这些函数定义了具体策略需要实现的接口。例如
- 具体派生类:
- 实现抽象基类中的纯虚函数。例如
ConcreteStrategyA
类会实现void execute() { /*具体策略A的实现代码*/ }
。
- 实现抽象基类中的纯虚函数。例如
- 上下文类:
- 包含一个指向抽象基类的成员变量,例如
Strategy* strategy;
。 - 提供设置策略的函数,如
void setStrategy(Strategy* newStrategy) { strategy = newStrategy; }
。 - 提供调用策略的函数,如
void contextExecute() { if(strategy) strategy->execute(); }
。
- 包含一个指向抽象基类的成员变量,例如
3. 对象交互过程
- 创建具体策略对象,如
ConcreteStrategyA* strategyA = new ConcreteStrategyA();
- 创建上下文对象,如
Context context;
- 将具体策略对象设置到上下文对象中,
context.setStrategy(strategyA);
- 上下文对象调用策略,
context.contextExecute();
,此时会执行ConcreteStrategyA
的execute
方法。如果之后想切换策略,可创建新的具体策略对象并设置到上下文对象中,如ConcreteStrategyB* strategyB = new ConcreteStrategyB(); context.setStrategy(strategyB);
,再次调用contextExecute
就会执行ConcreteStrategyB
的execute
方法。
4. 优点
- 可维护性高:具体策略的实现与上下文分离,当需要修改某个策略时,只需修改对应的具体派生类,不影响其他部分。
- 可扩展性强:新增策略非常容易,只需创建一个新的派生类并实现抽象基类的接口即可,符合开闭原则。
- 灵活性好:上下文可以在运行时动态切换策略,根据不同的情况使用不同的算法。
5. 可能存在的缺点
- 增加系统复杂性:引入了抽象基类和多个派生类,使得类的数量增多,系统结构变得复杂,对于简单场景可能过度设计。
- 客户端需要了解策略细节:客户端需要知道有哪些具体策略可供选择,并负责创建和设置具体策略对象,增加了客户端的使用难度。