将 Type Code 替换为 State/Strategy 模式
Replace Type Code with State/Strategy
要将 Type Code 替换为 State/Strategy 模式,你的目的是通过将行为分离到独立的类中来消除使用类型代码(如整数、字符串或枚举类型)来决定行为的需要。这种做法能够让系统变得更加灵活和易于维护。
理解 Type Code
首先,让我们明确什么是 Type Code。通常,这种类型代码(如枚举类型或整数值)会决定某些行为。例如,假设你有以下代码:
enum class Status { Inactive, Active, Pending };
class User {
public:
Status status;
void performAction() {
if (status == Status::Inactive) {
// 执行 Inactive 状态下的行为
} else if (status == Status::Active) {
// 执行 Active 状态下的行为
} else if (status == Status::Pending) {
// 执行 Pending 状态下的行为
}
}
};
这个 performAction() 方法通过 if 或 switch 来检查 status,并根据不同的状态执行不同的逻辑。这种方式在状态增加时非常难以维护,因为每增加一个状态,都需要修改这个方法,违反了开放封闭原则。
使用 State 或 Strategy 模式
我们将这种行为分离到各自的类中,这样就不再需要用条件判断来切换行为了。
State 模式
State 模式适用于对象的状态变化决定其行为。你可以为每个状态创建一个类,并将具体行为封装在这些类中。
例如:
class State {
public:
virtual ~State() = default;
virtual void performAction() = 0;
};
class InactiveState : public State {
public:
void performAction() override {
// 执行 Inactive 状态下的行为
}
};
class ActiveState : public State {
public:
void performAction() override {
// 执行 Active 状态下的行为
}
};
class PendingState : public State {
public:
void performAction() override {
// 执行 Pending 状态下的行为
}
};
class User {
private:
std::unique_ptr<State> state; // 使用智能指针管理状态
public:
User(std::unique_ptr<State> initialState) : state(std::move(initialState)) {}
void setState(std::unique_ptr<State> newState) {
state = std::move(newState); // 动态改变状态
}
void performAction() {
state->performAction(); // 调用当前状态的行为
}
};
这样,通过将每个状态的行为封装到自己的类中,你可以方便地改变用户的状态而不需要修改原有的逻辑。
Strategy 模式
Strategy 模式适用于当你需要在不同的算法或行为之间进行选择时。与 State 模式不同,Strategy 模式侧重于不同的行为或策略。
例如,假设你有不同的支付方式,你可以通过 Strategy 模式来选择不同的支付策略:
class PaymentStrategy {
public:
virtual ~PaymentStrategy() = default;
virtual void pay() = 0;
};
class CreditCardPayment : public PaymentStrategy {
public:
void pay() override {
// 信用卡支付的逻辑
}
};
class PayPalPayment : public PaymentStrategy {
public:
void pay() override {
// PayPal 支付的逻辑
}
};
class BitcoinPayment : public PaymentStrategy {
public:
void pay() override {
// 比特币支付的逻辑
}
};
class Order {
private:
std::unique_ptr<PaymentStrategy> paymentStrategy;
public:
Order(std::unique_ptr<PaymentStrategy> strategy) : paymentStrategy(std::move(strategy)) {}
void setPaymentStrategy(std::unique_ptr<PaymentStrategy> newStrategy) {
paymentStrategy = std::move(newStrategy); // 动态改变支付策略
}
void executePayment() {
paymentStrategy->pay(); // 使用当前的支付策略
}
};
状态管理与策略管理
你可以根据需求选择 State 或 Strategy 模式:
- State 模式:如果行为取决于对象的内在状态并且需要在状态之间切换(例如用户的不同状态:Inactive, Active,
Pending)。 - Strategy 模式:如果你有多个独立的行为或策略,可以根据不同的条件选择执行哪一个策略(例如支付策略、排序策略等)。
重构后的代码结构
如果将原来的 User 类中的 if 判断转换成 State 模式,它将变得更加灵活。例如:
int main() {
// 创建不同状态的用户
User user(std::make_unique<InactiveState>());
// 执行 Inactive 状态下的行为
user.performAction();
// 切换到 Active 状态
user.setState(std::make_unique<ActiveState>());
// 执行 Active 状态下的行为
user.performAction();
// 切换到 Pending 状态
user.setState(std::make_unique<PendingState>());
// 执行 Pending 状态下的行为
user.performAction();
}
优点
- 清晰的代码结构:每个状态或策略的行为都被封装在各自的类中,代码更加模块化。
- 易于扩展:如果将来需要添加新的状态或策略,只需创建新的类,而不需要修改现有的代码。
- 符合开放封闭原则:你可以在不修改现有代码的情况下轻松扩展系统。
总结
将 Type Code 替换为 State 或 Strategy 模式,可以使你的代码更加灵活、可维护,并且符合面向对象设计的原则。通过将不同的行为委托给不同的类,你避免了在条件语句中重复判断类型,增加了系统的可扩展性。