您的位置 首页 教程

状态模式

状态模式定义了一系列状态,对于不同状态进行相应的处理,将状态与行为分离,减少了代码的复杂度,并且提高扩展性。

状态模式

什么是状态模式

状态模式是一种行为型设计模式。它允许对象在内部状态改变时改变行为,看起来像是改变了对象的类。状态模式将对象行为包装在不同的状态对象中,对象在运行时将自己委托给当前附加的状态对象。这样可以使对象在不同的状态下拥有不同的行为。

状态模式可以使一个对象的状态更加干净,解耦了状态切换的业务逻辑,使得状态的变化独立于对象本身的行为,方便维护拓展。

状态模式的优缺点

优点

  • 状态模式将与特定状态相关的行为局部化到一个状态对象中,使得代码更清晰易懂。
  • 将特定状态的行为放在状态对象中,使得它们可以被多个上下文对象共享。
  • 易于增加新的状态,只需要添加相应的状态类即可。
  • 利用多态性来进行状态切换,使得代码更具有灵活性和可维护性。

缺点

  • 状态模式会增加代码的复杂度,因为增加状态意味着增加状态类。
  • 状态模式的使用频率并不高,除非有多个对象同时要进行状态转换的场景中才会用到。

状态模式的应用场景

  • 当一个对象的行为取决于它的状态,并且在运行时它必须根据状态改变它的行为时。
  • 当复杂对象有很多状态,并且它们的转换规则相互影响时。
  • 当需要防止在对象状态下执行某些不合理的行为时。
  • 当一个系统中的某个对象的行为取决于其他对象的状态时,可以使用观察者模式和状态模式相结合。

状态模式示例代码

假设有一个银行账户类,账户可以有两种状态:正常状态和透支状态。如果账户余额为正,则账户正常状态,否则为透支状态。

“` java
// 账户状态抽象类
public abstract class AccountState {
protected Account account;
protected double balance;
protected double interest;
protected double lowerLimit;
protected double upperLimit;
public abstract void deposit(double amount);
public abstract void withdraw(double amount);
public abstract void payInterest();
// 状态切换处理
public abstract void stateCheck();
}

// 正常状态类
public class NormalState extends AccountState {
public NormalState(Account account) {
this.account = account;
this.interest = 0.01;
this.lowerLimit = 0;
this.upperLimit = 1000;
}
public NormalState(AccountState state) {
this.account = state.account;
this.balance = state.balance;
this.interest = 0.01;
this.lowerLimit = 0;
this.upperLimit = 1000;
}
@Override
public void deposit(double amount) {
balance += amount;
stateCheck();
}
@Override
public void withdraw(double amount) {
balance -= amount;
stateCheck();
}
@Override
public void payInterest() {
balance += balance * interest;
stateCheck();
}
@Override
public void stateCheck() {
if (balance < lowerLimit) { account.setState(new OverdraftState(this)); } else if (balance > upperLimit) {
account.setState(new UpperLimitState(this));
}
}
}

// 透支状态类
public class OverdraftState extends AccountState {
public OverdraftState(AccountState state) {
this.account = state.account;
this.balance = state.balance;
this.interest = 0.07;
this.lowerLimit = -1000;
this.upperLimit = 0;
}
@Override
public void deposit(double amount) {
balance += amount;
stateCheck();
}
@Override
public void withdraw(double amount) {
balance -= amount;
stateCheck();
}
@Override
public void payInterest() {
balance += balance * interest;
stateCheck();
}
@Override
public void stateCheck() {
if (balance > upperLimit) {
account.setState(new NormalState(this));
}
}
}

// 超限状态类
public class UpperLimitState extends AccountState {
public UpperLimitState(AccountState state) {
this.account = state.account;
this.balance = state.balance;
this.interest = 0.05;
this.lowerLimit = 1000;
this.upperLimit = Integer.MAX_VALUE;
}
@Override
public void deposit(double amount) {
balance += amount;
stateCheck();
}
@Override
public void withdraw(double amount) {
balance -= amount;
stateCheck();
}
@Override
public void payInterest() {
balance += balance * interest;
stateCheck();
}
@Override
public void stateCheck() {
if (balance < lowerLimit) { account.setState(new OverdraftState(this)); } } } // 银行账户类 public class Account { private AccountState state; private String owner; private double balance; public Account(String owner, double balance) { this.owner = owner; this.balance = balance; this.state = new NormalState(this); } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public void setState(AccountState state) { this.state = state; } public void deposit(double amount) { state.deposit(amount); System.out.println("存款金额为:" + amount); System.out.println("账户余额为:" + balance); System.out.println("账户状态为:" + state.getClass().getSimpleName() + "\n"); } public void withdraw(double amount) { state.withdraw(amount); System.out.println("取款金额为:" + amount); System.out.println("账户余额为:" + balance); System.out.println("账户状态为:" + state.getClass().getSimpleName() + "\n"); } public void computeInterest() { state.payInterest(); System.out.println("账户状态为:" + state.getClass().getSimpleName() + "\n"); } } ```

在这个示例中,银行账户类通过委托状态对象控制其行为。查询账户余额、存款、取款等行为都委托给状态对象中的具体方法处理,状态对象会根据账户的余额自动切换为正常、透支或超过限额的状态。

总结

状态模式的设计思路是通过将状态封装到不同的状态类中,维护一个抽象的状态类来表示对象的状态,通过在运行时动态切换状态对象来更改对象的行为,从而实现不同状态下的不同行为。状态模式的主要优点在于实现了状态与行为的分离,易于增加新的状态,也易于维护拓展。但状态模式在一些场景下也存在一定的缺点,例如会增加代码的复杂度。

关于作者: 品牌百科

热门文章