状态模式(State Pattern)是一种【行为型】设计模式,它允许对象在其内部状态发生变化时改变其行为,看起来就像该对象改变了它的类一样。这种模式将状态相关的行为封装在独立的状态类中,并将状态转换逻辑集中管理,使系统更易于维护和扩展。
状态模式包含三个核心角色:
以下是一个自动售货机的示例,演示如何使用状态模式管理不同状态下的行为:
#include
#include
#include
// 前向声明
class VendingMachine;
// 状态接口
class State {
public:
virtual ~State() = default;
virtual void insertMoney(VendingMachine* machine, double amount) = 0;
virtual void selectProduct(VendingMachine* machine, const std::string& product) = 0;
virtual void dispense(VendingMachine* machine) = 0;
virtual void cancel(VendingMachine* machine) = 0;
virtual std::string getStateName() const = 0;
};
// 上下文:自动售货机
class VendingMachine {
private:
std::shared_ptr<State> currentState;
double balance;
std::string selectedProduct;
double productPrice;
public:
VendingMachine();
void setState(std::shared_ptr<State> state) {
currentState = state;
std::cout << "State changed to: " << currentState->getStateName() << std::endl;
}
void insertMoney(double amount) {
currentState->insertMoney(this, amount);
}
void selectProduct(const std::string& product) {
currentState->selectProduct(this, product);
}
void dispense() {
currentState->dispense(this);
}
void cancel() {
currentState->cancel(this);
}
double getBalance() const { return balance; }
void setBalance(double amount) { balance = amount; }
std::string getSelectedProduct() const { return selectedProduct; }
void setSelectedProduct(const std::string& product) { selectedProduct = product; }
double getProductPrice() const { return productPrice; }
void setProductPrice(double price) { productPrice = price; }
};
// 具体状态:待机状态
class IdleState : public State {
public:
void insertMoney(VendingMachine* machine, double amount) override {
machine->setBalance(amount);
std::cout << "Money inserted: " << amount << std::endl;
machine->setState(std::make_shared<HasMoneyState>());
}
void selectProduct(VendingMachine* machine, const std::string& product) override {
std::cout << "Please insert money first" << std::endl;
}
void dispense(VendingMachine* machine) override {
std::cout << "No product selected and no money inserted" << std::endl;
}
void cancel(VendingMachine* machine) override {
std::cout << "No transaction to cancel" << std::endl;
}
std::string getStateName() const override { return "Idle"; }
};
// 具体状态:已投币状态
class HasMoneyState : public State {
public:
void insertMoney(VendingMachine* machine, double amount) override {
double newBalance = machine->getBalance() + amount;
machine->setBalance(newBalance);
std::cout << "Additional money inserted: " << amount << std::endl;
std::cout << "Current balance: " << newBalance << std::endl;
}
void selectProduct(VendingMachine* machine, const std::string& product) override {
double price = 1.5; // 假设所有产品价格为1.5元
machine->setSelectedProduct(product);
machine->setProductPrice(price);
std::cout << "Product selected: " << product << ", Price: " << price << std::endl;
if (machine->getBalance() >= price) {
machine->setState(std::make_shared<ReadyToDispenseState>());
} else {
std::cout << "Insufficient balance. Please insert "
<< (price - machine->getBalance()) << " more" << std::endl;
}
}
void dispense(VendingMachine* machine) override {
std::cout << "Please select a product first" << std::endl;
}
void cancel(VendingMachine* machine) override {
std::cout << "Transaction cancelled. Returning " << machine->getBalance() << std::endl;
machine->setBalance(0);
machine->setState(std::make_shared<IdleState>());
}
std::string getStateName() const override { return "HasMoney"; }
};
// 具体状态:准备出货状态
class ReadyToDispenseState : public State {
public:
void insertMoney(VendingMachine* machine, double amount) override {
double newBalance = machine->getBalance() + amount;
machine->setBalance(newBalance);
std::cout << "Additional money inserted: " << amount << std::endl;
std::cout << "Current balance: " << newBalance << std::endl;
}
void selectProduct(VendingMachine* machine, const std::string& product) override {
double price = 1.5;
machine->setSelectedProduct(product);
machine->setProductPrice(price);
std::cout << "Product updated: " << product << ", Price: " << price << std::endl;
}
void dispense(VendingMachine* machine) override {
double price = machine->getProductPrice();
double balance = machine->getBalance();
std::cout << "Dispensing " << machine->getSelectedProduct() << std::endl;
std::cout << "Returning change: " << (balance - price) << std::endl;
machine->setBalance(0);
machine->setSelectedProduct("");
machine->setState(std::make_shared<IdleState>());
}
void cancel(VendingMachine* machine) override {
std::cout << "Transaction cancelled. Returning " << machine->getBalance() << std::endl;
machine->setBalance(0);
machine->setSelectedProduct("");
machine->setState(std::make_shared<IdleState>());
}
std::string getStateName() const override { return "ReadyToDispense"; }
};
// 初始化自动售货机
VendingMachine::VendingMachine() {
currentState = std::make_shared<IdleState>();
balance = 0;
selectedProduct = "";
productPrice = 0;
}
// 客户端代码
int main() {
// 创建自动售货机
auto vendingMachine = std::make_shared<VendingMachine>();
// 场景1:投币不足,取消交易
std::cout << "=== Scenario 1 ===" << std::endl;
vendingMachine->insertMoney(1.0);
vendingMachine->selectProduct("Coke");
vendingMachine->cancel();
std::cout << "\n";
// 场景2:投币足够,购买成功
std::cout << "=== Scenario 2 ===" << std::endl;
vendingMachine->insertMoney(2.0);
vendingMachine->selectProduct("Chips");
vendingMachine->dispense();
std::cout << "\n";
// 场景3:投币不足,追加投币,购买成功
std::cout << "=== Scenario 3 ===" << std::endl;
vendingMachine->insertMoney(1.0);
vendingMachine->selectProduct("Water");
vendingMachine->insertMoney(1.0);
vendingMachine->dispense();
return 0;
}
std::iostream
的状态(如good()
、eof()
、fail()
)可以看作是状态模式的应用。std::shared_ptr
的引用计数状态影响其行为。优点:
缺点:
以下是一个 TCP 连接状态管理的实现示例,演示如何使用状态模式处理不同连接状态:
#include
#include
#include
// 前向声明
class TCPConnection;
// 状态接口
class TCPState {
public:
virtual ~TCPState() = default;
virtual void open(TCPConnection* connection) = 0;
virtual void close(TCPConnection* connection) = 0;
virtual void send(TCPConnection* connection, const std::string& data) = 0;
virtual std::string getStateName() const = 0;
};
// 上下文:TCP连接
class TCPConnection {
private:
std::shared_ptr<TCPState> currentState;
public:
TCPConnection();
void setState(std::shared_ptr<TCPState> state) {
currentState = state;
std::cout << "Connection state changed to: " << currentState->getStateName() << std::endl;
}
void open() {
currentState->open(this);
}
void close() {
currentState->close(this);
}
void send(const std::string& data) {
currentState->send(this, data);
}
};
// 具体状态:关闭状态
class TCPClosed : public TCPState {
public:
void open(TCPConnection* connection) override {
std::cout << "Opening connection..." << std::endl;
// 执行打开连接的操作
connection->setState(std::make_shared<TCPOpen>());
}
void close(TCPConnection* connection) override {
std::cout << "Connection is already closed" << std::endl;
}
void send(TCPConnection* connection, const std::string& data) override {
std::cout << "Cannot send data. Connection is closed" << std::endl;
}
std::string getStateName() const override { return "Closed"; }
};
// 具体状态:打开状态
class TCPOpen : public TCPState {
public:
void open(TCPConnection* connection) override {
std::cout << "Connection is already open" << std::endl;
}
void close(TCPConnection* connection) override {
std::cout << "Closing connection..." << std::endl;
// 执行关闭连接的操作
connection->setState(std::make_shared<TCPClosed>());
}
void send(TCPConnection* connection, const std::string& data) override {
std::cout << "Sending data: " << data << std::endl;
// 执行数据发送的操作
connection->setState(std::make_shared<TCPListen>());
}
std::string getStateName() const override { return "Open"; }
};
// 具体状态:监听状态
class TCPListen : public TCPState {
public:
void open(TCPConnection* connection) override {
std::cout << "Connection is already open. Cannot open again while listening" << std::endl;
}
void close(TCPConnection* connection) override {
std::cout << "Closing connection..." << std::endl;
// 执行关闭连接的操作
connection->setState(std::make_shared<TCPClosed>());
}
void send(TCPConnection* connection, const std::string& data) override {
std::cout << "Cannot send data while in listening state" << std::endl;
}
std::string getStateName() const override { return "Listen"; }
};
// 初始化TCP连接
TCPConnection::TCPConnection() {
currentState = std::make_shared<TCPClosed>();
}
// 客户端代码
int main() {
// 创建TCP连接
auto connection = std::make_shared<TCPConnection>();
// 尝试发送数据(连接已关闭)
connection->send("Hello");
// 打开连接
connection->open();
// 发送数据
connection->send("Hello, world!");
// 尝试再次打开连接
connection->open();
// 关闭连接
connection->close();
// 尝试发送数据(连接已关闭)
connection->send("Goodbye");
return 0;
}
状态模式是 C++ 中处理复杂状态逻辑的有效工具,通过将状态相关行为封装在独立的类中,使系统更具灵活性和可维护性,特别适合需要根据状态动态改变行为的场景。