Java设计模式(10) —— 状态

State

 

Intent
Allow an object to alter its behavior when its internal state changes.

How to
1.Context delegates state-specific requests to the current ConcreteState object.
2.Clients can configure a context with State objects. Once a context is configured, its clients don't have to deal with the  State objects directly.
3.Either Context or the ConcreteState subclasses can decide which state succeeds another and under what circumstances.

Context
defines the interface of interest to clients.
maintains an instance of a ConcreteState subclass that defines the current state.
State
defines an interface for encapsulating the behavior associated with a particular state of the Context.
ConcreteState subclasses
each subclass implements a behavior associated with a state of the Context.

Known cases
Credit Account
Process

UML

Java设计模式(10) —— 状态_第1张图片

 

假设账户有三种状态:

1.如果没透支,则取款不收取费用(NonfeeState)

2.如果透支数小于等于200,则取款费用为2元(FeeState)

3.如果透支数多于500,则不允许取款(OverdrawState)

 

代码:

public class Account { private State state; private long balance; public Account(long balance, State state) { this.balance = balance; this.state = state; } public void setState(State state) { this.state = state; } public State getState() { return state; } public void setBalance(long count) { this.balance = count; } public long getBalance() { return balance; } public void withdraw(long count) { state.withdraw(this, count); } public void diposit(long count) { state.diposit(this, count); } }

public interface State { int NONFEE_LIMIT = 0; int FEE_LIMIT = -200; int OVERDRAW_LIMIT = -500; int FEE = 2; void withdraw(Account account, long count); void diposit(Account account, long count); }

public class NonfeeState implements State { private static NonfeeState unique = new NonfeeState(); private NonfeeState() {} public static NonfeeState getInstance() { return unique; } public void diposit(Account account, long count) { long balance = account.getBalance() + count; account.setBalance(balance); } public void withdraw(Account account, long count) { long balance = account.getBalance() - count; State state = this; if (balance < State.NONFEE_LIMIT) { if (balance >= State.FEE_LIMIT) { state = FeeState.getInstance(); } else if (balance < State.OVERDRAW_LIMIT) { state = OverdrawState.getInstance(); } } account.setState(state); account.setBalance(balance); } }

public class FeeState implements State { private static FeeState unique = new FeeState(); private FeeState() {} public static FeeState getInstance() { return unique; } public void diposit(Account account, long count) { long balance = account.getBalance() + count; State state = this; if (balance >= State.NONFEE_LIMIT) { state = NonfeeState.getInstance(); } account.setState(state); account.setBalance(balance); } public void withdraw(Account account, long count) { long balance = account.getBalance() - count - State.FEE; State state = this; if (balance < State.OVERDRAW_LIMIT) { state = OverdrawState.getInstance(); } account.setState(state); account.setBalance(balance); } }

public class OverdrawState implements State { private static OverdrawState unique = new OverdrawState(); private OverdrawState() {} public static OverdrawState getInstance() { return unique; } public void diposit(Account account, long count) { long balance = account.getBalance() + count; State state = this; if (balance >= State.NONFEE_LIMIT) { state = NonfeeState.getInstance(); } else if (balance < State.NONFEE_LIMIT && balance >= State.FEE_LIMIT) { state = FeeState.getInstance(); } account.setState(state); account.setBalance(balance); } public void withdraw(Account account, long count) { throw new RuntimeException("Overdraw"); } }

 

说明:

(1)如果此例不运用状态模式,则会在Account中的withdraw和diposit方法中有if-else语句(如果发现一个类中有许多方法有相同的条件逻辑判断,可能表示这个类可以重构成状态模式)

(2)由于各个State子类无状态,因此全局只需使用一个实例即可

你可能感兴趣的:(Java设计模式(10) —— 状态)