十一、状态模式

我们在做某一些操作的时候,遇到不同状态的时候就会有不同的处理方式。为了判别这些状态,我们必然会使用大量的if else语句来做状态判断处理。而随着if else(或switch case)语句的增多,程序的可读性,扩展性也会变得很弱。维护也会很麻烦,你可能看到过有的代码中 一个函数就有n多if语句,代码甚至超过了上千行。
        举一个例子:我们给一部手机打电话,就可能出现这几种情况:用户开机,用户关机,用户欠费停机,用户消户等。 所以当我们拨打这个号码的时候:系统就要判断,该用户是否在开机且不忙状态,又或者是关机,欠费等状态。但不管是那种状态我们都应给出对应的处理操作。下面我们用代码来模拟一下这个过程。

 1 /** */ /***********************************************************************
 2 * Module:  Context.java
 3 * Author:  yang00013
 4 * Purpose: Defines the Class Context
 5 ***********************************************************************/

 6
 7 import java.util.*;
 8
 9
10 public  class MobileTelephone {
11   //开机且用户没使用的状态
12   private int waitState = 1;
13   //关机状态
14   private int closeState = 2;
15   //停机状态
16   private int stopState = 3;
17  // 已消户
18   private int logoutState = 4;
19  // 拨通
20  private int connectState = 5;
21   //当前状态
22   private int state = openState;   
23   
24  
25   //打电话操作
26   public void call() {
27     if (state == waitState )
28     {
29        system.out.println("连接成功,可以通话");
30        //改变状态为连接通话状态
31        changeState(connectState);            
32     }
else if(state == closeState )
33       {
34            system.out.println("用户已关机");
35       }
else if(state == stopState){
36            system.out.println("用户欠费停机");
37       }
else if (state == connectState){
38            system.out.println("用户正在通话,请稍后再拨!"); 
39     }

40
41   }
   
42   
43   //通话计时
44   public void countTime(){
45     if (state == connectState )
46     {
47        system.out.println("计时处理。。。");
48        system.out.println("通话结束,计时结束");
49        changeState(waitState);            
50     }
else if(state = waitState){
51        system.out.println("电话不在连接状态,不计时。。。");
52     }
else if(state == closeState )
53       {
54            system.out.println("用户已关机");
55       }
else if(state == stopState){
56            system.out.println("用户欠费停机");
57       }

58
59  }

60  
61    //其他操作:比如开机,关机,欠费开机等操作与上雷同,在此省略。。。
62 
63
64   public void changeState(int concreteState) {
65      this.state = concreteState;
66   }

67
68}

         注意,看看上面的代码,显然它已经完成了我们的基本业务操作,但是,一旦我们有新的状态加入的话,我们势必要在每个业务方法里边增加相应的else if语句。所以加入x个状态就有可能加入n*x条else if语句,n表示函数(业务方法)的数量。

状态模式:把不同状态的操作分散到不同的状态对象里去完成。看看状态类的uml类图。
    

       从上图可以看出,每一个状态类都会去处理所有的业务方法,根据他自身的状态,去让不同函数(业务方法)作相应的不同处理。而我们先前的方式是,在不同的函数(业务方法)里去判断不同状态,然后分别对每一个状态作不同的处理。很显然,我们采用状态模式的方式在后续扩张和维护能力上都得到了很大程度提高,比如我们先加入一个状态,我就只仅仅需要加入一个相应的状态类就可以了。代码量也就是实现该状态下各个函数的不同处理过程而已。好,看看实现代码:

 1 /** */ /***********************************************************************
 2 * Module:  IState.java
 3 * Author:  yang00013
 4 * Purpose: Defines the Interface IState
 5 ***********************************************************************/

 6
 7 import java.util.*;
 8
 9
10 public  interface IState  {
11   
12   void call();
13   
14   void countTimes();
15   
16  // 其他操作。
17
18}
 空闲状态:
 1 /** */ /***********************************************************************
 2 * Module:  ConcreteStateA.java
 3 * Author:  yang00013
 4 * Purpose: Defines the Class ConcreteStateA
 5 ***********************************************************************/

 6
 7 import java.util.*;
 8
 9
10 public  class WaitState  implements IState  {
11   
12   private Context context;   
13   
14   public void call() {
15       //做连接操作
16        system.out.println("连接成功,可以通话");
17        //改变状态为连接通话状态
18        context。changeState(context.getConnectState());         
19   }

20   
21   
22   public void countTimes() {
23       system.out.print("电话不在连接状态,不能计时");
24   }

25   
26   
27  
28
29}
通话状态:
 1 /** */ /***********************************************************************
 2 * Module:  ConcreteStateB.java
 3 * Author:  yang00013
 4 * Purpose: Defines the Class ConcreteStateB
 5 ***********************************************************************/

 6
 7 import java.util.*;
 8
 9
10 public  class ConnectState  implements IState  {
11
12   private Context context;
13   
14   
15   public void call() {
16      system.out.print("用户正在通话,请稍后再拨");
17   }

18   
19
20   public void countTimes() {
21      system.out.println("计时处理。。。");
22      system.out.println("通话结束,计时结束");
23      context.changeState(context.getWaitState());    
24   }

25   
26  
27   
28}
新的手机类
 1 /** */ /***********************************************************************
 2 * Module:  Context.java
 3 * Author:  yang00013
 4 * Purpose: Defines the Class Context
 5 ***********************************************************************/

 6
 7 import java.util.*;
 8
 9
10 public  class MobileTelephone  {
11   //开机且空闲状态
12   private State waitState = new waitState();
13   //通话连接状态
14   private State connectState = new ConnectState();
15   //关机状态
16   private State stopState = new stopState();
17  //其它状态与上了雷同,在此省略。。。
18   //当前状态
19   private State state = waitState;   
20   
21   //拨打操作
22   public void call() {
23      state.call(); 
24   }
   
25  //计时操作
26   public void countTimes() {
27     state.countTimes();
28   }
   
29  
30  
31   
32   public void chageState(State concreteState) {
33      this.state = concreteState;
34   }

35
36
37   //setter/getter 方法列表
38   
39}

       状态模式和策略模式的最大区别在于它有状态间的切换,一个状态完了,就要切换到它下一个状态。

转载:http://www.blogjava.net/samyang/archive/2008/03/14/184700.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值