设计模式之十 --- 状态(State)模式

http://blog.csdn.net/cjjky/article/details/7585207

 

【1】基本概念

          状态模式(State),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

【2】简单分析

         我们先来看下该设计模式的UML的结构图


【3】如何用Java语言实现该设计模式

本篇文章以一个贴近现实生活的例子来展示如何使用该设计模式,以方便大家尽快的掌握状态设计模式。例子:如某人去银行新开一个账户,该账户可以用来存钱或者取钱,我们可以以账户中的总资金来判断显示某用户账户的状态:红色状态(RedState),银色状态(SliverState),金色状态GoldState)。其实就好比银行中根据我们存储卡中的资金来给客户某种身份的识别,例如普通用户,VIP客户,公司客户....等等。

我们先看下该实例Demo的结构图:


3.1 State.java 源码:

  1. package com.andyidea.patterns.concretestate;  
  2.   
  3. import com.andyidea.patterns.context.Account;  
  4.   
  5. /**  
  6.  * State类,抽象状态类,定义一个接口以封装  
  7.  * 与Context的一个特定状态相关的行为。  
  8.  * @author Andy  
  9.  *  
  10.  */  
  11. public abstract class State {  
  12.       
  13.     protected Account account;  
  14.     protected double balance;  
  15.   
  16.     protected double interest;  
  17.     protected double lowerLimit;  
  18.     protected double upperLimit;  
  19.   
  20.     //-------------Properties------------------//  
  21.     public Account getAccount() {  
  22.         return account;  
  23.     }  
  24.     public void setAccount(Account account) {  
  25.         this.account = account;  
  26.     }  
  27.       
  28.     public double getBalance() {  
  29.         return balance;  
  30.     }  
  31.     public void setBalance(double balance) {  
  32.         this.balance = balance;  
  33.     }  
  34.     //------------------------------------------//  
  35.       
  36.     /**存入金额*/  
  37.     public abstract void deposit(double amount);  
  38.     /**支出金额*/  
  39.     public abstract void withdraw(double amount);  
  40.     /**利息*/  
  41.     public abstract void payInterest();  
  42.   
  43. }  
package com.andyidea.patterns.concretestate;

import com.andyidea.patterns.context.Account;

/**
 * State类,抽象状态类,定义一个接口以封装
 * 与Context的一个特定状态相关的行为。
 * @author Andy
 *
 */
public abstract class State {
	
    protected Account account;
    protected double balance;

    protected double interest;
    protected double lowerLimit;
    protected double upperLimit;

    //-------------Properties------------------//
    public Account getAccount() {
		return account;
	}
	public void setAccount(Account account) {
		this.account = account;
	}
	
	public double getBalance() {
		return balance;
	}
	public void setBalance(double balance) {
		this.balance = balance;
	}
	//------------------------------------------//
	
	/**存入金额*/
	public abstract void deposit(double amount);
	/**支出金额*/
    public abstract void withdraw(double amount);
    /**利息*/
    public abstract void payInterest();

}
3.2  RedState.java源码:

  1. package com.andyidea.patterns.concretestate;  
  2.   
  3.   
  4. /**  
  5.  * 用户账户状态:RedState  
  6.  * @author Andy  
  7.  * ConcreteState类,具体状态,每一个子类实现一个与  
  8.  * Context的一个状态相关的行为。  
  9.  */  
  10. public class RedState extends State {  
  11.       
  12.     private double serviceFee;  
  13.   
  14.     public RedState(State state) {  
  15.         this.balance = state.getBalance();  
  16.         this.account = state.getAccount();  
  17.         initialize();  
  18.     }  
  19.   
  20.      /** 模拟初始化基础数据*/  
  21.     private void initialize() {  
  22.         interest = 0.0;  
  23.         lowerLimit = -100.0;  
  24.         upperLimit = 0.0;  
  25.         serviceFee = 15.00;  
  26.     }  
  27.   
  28.     @Override  
  29.     public void deposit(double amount) {  
  30.           balance += amount;  
  31.           stateChangeCheck();  
  32.     }  
  33.   
  34.     @Override  
  35.     public void withdraw(double amount) {  
  36.           amount = amount - serviceFee;  
  37.           System.out.println("No funds available for withdrawal!");  
  38.     }  
  39.   
  40.     @Override  
  41.     public void payInterest() {  
  42.         // No interest is paid  
  43.     }  
  44.       
  45.     /** 状态检测 */  
  46.     private void stateChangeCheck() {  
  47.         if (balance > upperLimit) {  
  48.             account.setState(new SilverState(this));  
  49.         }  
  50.     }  
  51.   
  52. }  
package com.andyidea.patterns.concretestate;


/**
 * 用户账户状态:RedState
 * @author Andy
 * ConcreteState类,具体状态,每一个子类实现一个与
 * Context的一个状态相关的行为。
 */
public class RedState extends State {
	
	private double serviceFee;

	public RedState(State state) {
		this.balance = state.getBalance();
		this.account = state.getAccount();
		initialize();
	}

	 /** 模拟初始化基础数据*/
	private void initialize() {
		interest = 0.0;
		lowerLimit = -100.0;
		upperLimit = 0.0;
		serviceFee = 15.00;
	}

	@Override
	public void deposit(double amount) {
	      balance += amount;
	      stateChangeCheck();
	}

	@Override
	public void withdraw(double amount) {
	      amount = amount - serviceFee;
	      System.out.println("No funds available for withdrawal!");
	}

	@Override
	public void payInterest() {
		// No interest is paid
	}
	
	/** 状态检测 */
	private void stateChangeCheck() {
		if (balance > upperLimit) {
			account.setState(new SilverState(this));
		}
	}

}
SliverState.java源码:

  1. package com.andyidea.patterns.concretestate;  
  2.   
  3. import com.andyidea.patterns.context.Account;  
  4.   
  5. /**  
  6.  * 用户账户状态:SilverState  
  7.  * @author Andy  
  8.  * ConcreteState类,具体状态,每一个子类实现一个与  
  9.  * Context的一个状态相关的行为。  
  10.  */  
  11. public class SilverState extends State {  
  12.       
  13.     public SilverState(State state){  
  14.         this(state.balance,state.account);  
  15.     }  
  16.   
  17.     public SilverState(double balance, Account account){  
  18.       this.balance = balance;  
  19.       this.account = account;  
  20.       initialize();  
  21.     }  
  22.   
  23.     /** 模拟初始化基础数据*/  
  24.     private void initialize(){  
  25.       interest = 0.0;  
  26.       lowerLimit = 0.0;  
  27.       upperLimit = 1000.0;  
  28.     }  
  29.   
  30.     @Override  
  31.     public void deposit(double amount) {  
  32.           balance += amount;  
  33.           stateChangeCheck();  
  34.     }  
  35.   
  36.     @Override  
  37.     public void withdraw(double amount) {  
  38.           balance -amount;  
  39.           stateChangeCheck();  
  40.     }  
  41.   
  42.     @Override  
  43.     public void payInterest() {  
  44.           balance += interest * balance;  
  45.           stateChangeCheck();  
  46.     }  
  47.       
  48.     /** 状态检测 */  
  49.     private void stateChangeCheck(){  
  50.       if (balance < lowerLimit){  
  51.           account.setState(new RedState(this));  
  52.       }  
  53.       else if (balance > upperLimit){  
  54.           account.setState(new GoldState(this));  
  55.       }  
  56.     }  
  57.   
  58. }  
package com.andyidea.patterns.concretestate;

import com.andyidea.patterns.context.Account;

/**
 * 用户账户状态:SilverState
 * @author Andy
 * ConcreteState类,具体状态,每一个子类实现一个与
 * Context的一个状态相关的行为。
 */
public class SilverState extends State {
	
    public SilverState(State state){
    	this(state.balance,state.account);
    }

    public SilverState(double balance, Account account){
      this.balance = balance;
      this.account = account;
      initialize();
    }

    /** 模拟初始化基础数据*/
    private void initialize(){
      interest = 0.0;
      lowerLimit = 0.0;
      upperLimit = 1000.0;
    }

	@Override
	public void deposit(double amount) {
	      balance += amount;
	      stateChangeCheck();
	}

	@Override
	public void withdraw(double amount) {
	      balance -= amount;
	      stateChangeCheck();
	}

	@Override
	public void payInterest() {
	      balance += interest * balance;
	      stateChangeCheck();
	}
	
	/** 状态检测 */
    private void stateChangeCheck(){
      if (balance < lowerLimit){
    	  account.setState(new RedState(this));
      }
      else if (balance > upperLimit){
    	  account.setState(new GoldState(this));
      }
    }

}
GoldState.java源码:

  1. package com.andyidea.patterns.concretestate;  
  2.   
  3. import com.andyidea.patterns.context.Account;  
  4.   
  5. /**  
  6.  * 用户账户状态:GoldState  
  7.  * @author Andy  
  8.  * ConcreteState类,具体状态,每一个子类实现一个与  
  9.  * Context的一个状态相关的行为。  
  10.  */  
  11. public class GoldState extends State {  
  12.       
  13.     public GoldState(State state){  
  14.         this(state.balance, state.account);  
  15.     }  
  16.   
  17.     public GoldState(double balance, Account account){  
  18.       this.balance = balance;  
  19.       this.account = account;  
  20.       initialize();  
  21.     }  
  22.   
  23.     /** 模拟初始化基础数据*/  
  24.     private void initialize(){  
  25.       interest = 0.05;  
  26.       lowerLimit = 1000.0;  
  27.       upperLimit = 10000000.0;  
  28.     }  
  29.   
  30.     @Override  
  31.     public void deposit(double amount) {  
  32.          balance += amount;  
  33.          stateChangeCheck();  
  34.     }  
  35.   
  36.     @Override  
  37.     public void withdraw(double amount) {  
  38.           balance -amount;  
  39.           stateChangeCheck();  
  40.     }  
  41.   
  42.     @Override  
  43.     public void payInterest() {  
  44.           balance += interest * balance;  
  45.           stateChangeCheck();  
  46.     }  
  47.       
  48.     /** 状态检测 */  
  49.     private void stateChangeCheck() {  
  50.         if (balance < 0.0) {  
  51.             account.setState(new RedState(this));  
  52.         } else if (balance < lowerLimit) {  
  53.             account.setState(new SilverState(this));  
  54.         }  
  55.     }  
  56.   
  57. }  
package com.andyidea.patterns.concretestate;

import com.andyidea.patterns.context.Account;

/**
 * 用户账户状态:GoldState
 * @author Andy
 * ConcreteState类,具体状态,每一个子类实现一个与
 * Context的一个状态相关的行为。
 */
public class GoldState extends State {
	
    public GoldState(State state){
    	this(state.balance, state.account);
    }

    public GoldState(double balance, Account account){
      this.balance = balance;
      this.account = account;
      initialize();
    }

    /** 模拟初始化基础数据*/
    private void initialize(){
      interest = 0.05;
      lowerLimit = 1000.0;
      upperLimit = 10000000.0;
    }

	@Override
	public void deposit(double amount) {
	     balance += amount;
	     stateChangeCheck();
	}

	@Override
	public void withdraw(double amount) {
	      balance -= amount;
	      stateChangeCheck();
	}

	@Override
	public void payInterest() {
	      balance += interest * balance;
	      stateChangeCheck();
	}
	
	/** 状态检测 */
	private void stateChangeCheck() {
		if (balance < 0.0) {
			account.setState(new RedState(this));
		} else if (balance < lowerLimit) {
			account.setState(new SilverState(this));
		}
	}

}
3.3 Account.java类源码:

  1. package com.andyidea.patterns.context;  
  2.   
  3. import com.andyidea.patterns.concretestate.SilverState;  
  4. import com.andyidea.patterns.concretestate.State;  
  5.   
  6. /**  
  7.  * Context类,维护一个ConcreteState子类的实例  
  8.  * 这个实例定义当前的状态。  
  9.  * @author Andy  
  10.  *  
  11.  */  
  12. public class Account {  
  13.       
  14.     private State state;  
  15.     private String owner;  
  16.   
  17.     public Account(String owner){  
  18.       // 新开账户默认为 Silver状态  
  19.       this.owner = owner;  
  20.       this.state = new SilverState(0.0, this);  
  21.     }  
  22.   
  23.     public State getState() {  
  24.         return state;  
  25.     }  
  26.   
  27.     public void setState(State state) {  
  28.         this.state = state;  
  29.     }  
  30.   
  31.     public void deposit(double amount) {  
  32.         state.deposit(amount);  
  33.         System.out.println(owner + " Deposited  " + amount);  
  34.         System.out.println(owner + " Balance =  " + state.getBalance());  
  35.         System.out.println("Status = " + state.getClass().getSimpleName());  
  36.         System.out.println("==============================================");  
  37.     }  
  38.    
  39.     public void withdraw(double amount){  
  40.         state.withdraw(amount);  
  41.         System.out.println(owner + " Withdrew  " + amount);  
  42.         System.out.println(owner + " Balance =  " + state.getBalance());  
  43.         System.out.println("Status = " + state.getClass().getSimpleName());  
  44.         System.out.println("==============================================");  
  45.     }  
  46.    
  47.     public void payInterest(){  
  48.         state.payInterest();  
  49.         System.out.println(owner + " Interest Paid  ");  
  50.         System.out.println(owner + " Balance =  " + state.getBalance());  
  51.         System.out.println("Status = " + state.getClass().getSimpleName());  
  52.         System.out.println("==============================================");  
  53.     }  
  54.   
  55. }  
package com.andyidea.patterns.context;

import com.andyidea.patterns.concretestate.SilverState;
import com.andyidea.patterns.concretestate.State;

/**
 * Context类,维护一个ConcreteState子类的实例
 * 这个实例定义当前的状态。
 * @author Andy
 *
 */
public class Account {
	
    private State state;
    private String owner;

    public Account(String owner){
      // 新开账户默认为 Silver状态
      this.owner = owner;
      this.state = new SilverState(0.0, this);
    }

    public State getState() {
		return state;
	}

	public void setState(State state) {
		this.state = state;
	}

	public void deposit(double amount) {
		state.deposit(amount);
		System.out.println(owner + " Deposited  " + amount);
		System.out.println(owner + " Balance =  " + state.getBalance());
		System.out.println("Status = " + state.getClass().getSimpleName());
		System.out.println("==============================================");
	}
 
    public void withdraw(double amount){
        state.withdraw(amount);
        System.out.println(owner + " Withdrew  " + amount);
        System.out.println(owner + " Balance =  " + state.getBalance());
        System.out.println("Status = " + state.getClass().getSimpleName());
        System.out.println("==============================================");
    }
 
    public void payInterest(){
        state.payInterest();
        System.out.println(owner + " Interest Paid  ");
        System.out.println(owner + " Balance =  " + state.getBalance());
        System.out.println("Status = " + state.getClass().getSimpleName());
        System.out.println("==============================================");
    }

}
3.4 客户端测试类 StateClient.java 类源码:
  1. package com.andyidea.patterns;  
  2.   
  3. import com.andyidea.patterns.context.Account;  
  4.   
  5. public class StateClient {  
  6.       
  7.     public static void main(String[] args) {  
  8.           // 新开一个银行账户  
  9.           Account account = new Account("Andy.Chen");  
  10.   
  11.           // 存取款等系列操作  
  12.           account.deposit(500.0);  
  13.           account.deposit(300.0);  
  14.           account.deposit(550.0);  
  15.           account.payInterest();  
  16.           account.withdraw(2000.00);  
  17.           account.withdraw(1100.00);  
  18.     }  
  19.   
  20. }  
package com.andyidea.patterns;

import com.andyidea.patterns.context.Account;

public class StateClient {
	
	public static void main(String[] args) {
	      // 新开一个银行账户
	      Account account = new Account("Andy.Chen");

	      // 存取款等系列操作
	      account.deposit(500.0);
	      account.deposit(300.0);
	      account.deposit(550.0);
	      account.payInterest();
	      account.withdraw(2000.00);
	      account.withdraw(1100.00);
	}

}
【4】下面我们来看下程序运行的结果:

  1. Andy.Chen Deposited  500.0  
  2. Andy.Chen Balance =  500.0  
  3. Status = SilverState  
  4. ==============================================  
  5. Andy.Chen Deposited  300.0  
  6. Andy.Chen Balance =  800.0  
  7. Status = SilverState  
  8. ==============================================  
  9. Andy.Chen Deposited  550.0  
  10. Andy.Chen Balance =  1350.0  
  11. Status = GoldState  
  12. ==============================================  
  13. Andy.Chen Interest Paid    
  14. Andy.Chen Balance =  1417.5  
  15. Status = GoldState  
  16. ==============================================  
  17. Andy.Chen Withdrew  2000.0  
  18. Andy.Chen Balance =  -582.5  
  19. Status = RedState  
  20. ==============================================  
  21. No funds available for withdrawal!  
  22. Andy.Chen Withdrew  1100.0  
  23. Andy.Chen Balance =  -582.5  
  24. Status = RedState  
  25. ==============================================  
Andy.Chen Deposited  500.0
Andy.Chen Balance =  500.0
Status = SilverState
==============================================
Andy.Chen Deposited  300.0
Andy.Chen Balance =  800.0
Status = SilverState
==============================================
Andy.Chen Deposited  550.0
Andy.Chen Balance =  1350.0
Status = GoldState
==============================================
Andy.Chen Interest Paid  
Andy.Chen Balance =  1417.5
Status = GoldState
==============================================
Andy.Chen Withdrew  2000.0
Andy.Chen Balance =  -582.5
Status = RedState
==============================================
No funds available for withdrawal!
Andy.Chen Withdrew  1100.0
Andy.Chen Balance =  -582.5
Status = RedState
==============================================
【5】总结:

状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。

本文为 Andy.Chen 原创,欢迎大家继续关注Me的博文,欢迎大家转载,谢谢!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当代码中的条件语句if-else过于复杂时,可以考虑使用设计模式代替if-else语句,提高代码的可读性和可维护性。以下是一些常见的设计模式,可以用来代替if-else语句: 1. 工厂模式(Factory Pattern):通过工厂方法创建对象,而不是使用条件语句来直接创建对象。这样可以避免在代码中使用大量的if-else语句,同时也可以很方便地添加新的对象类型。 2. 状态模式State Pattern):将复杂的状态判断逻辑封装到不同的状态类中,避免在代码中使用大量的if-else语句。可以很方便地添加新的状态类型,也可以方便地维护和扩展状态的行为。 3. 策略模式(Strategy Pattern):将不同的算法封装到不同的策略类中,通过选择不同的策略类来实现不同的行为。这样可以避免在代码中使用复杂的if-else语句,同时也可以很方便地添加新的算法类型。 4. 观察者模式(Observer Pattern):将一个对象的状态变化通知给多个观察者对象,避免在代码中使用大量的if-else语句。可以很方便地添加新的观察者对象,也可以方便地维护和扩展观察者的行为。 5. 责任链模式(Chain of Responsibility Pattern):将多个处理对象组成一个链,每个处理对象都可以处理请求,如果一个对象不能处理请求,则将请求传递给下一个处理对象。这样可以避免在代码中使用大量的if-else语句,同时也可以很方便地添加新的处理对象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值