`
sunnylocus
  • 浏览: 871384 次
  • 性别: Icon_minigender_1
  • 来自: 美国图森
社区版块
存档分类
最新评论

用State模式减少if..elseif语句

    博客分类:
  • Java
阅读更多

   我们在写程序的过程中会遇到很多的逻辑判断,一般都是用if ..else、if..else if、swith(..) case等来做判断,然后根据结果做一下分支处理,这样写虽然方便,但会增加以后的维护难度,假如有上百个if ..else if判断,估计后期维护的人看到代码头都大了。像这种情况可以用state模式来解决。

  State模式是行为模式之一。当某个对象的内部状态(通俗的说,成员变量)发生改变,它的行为也会发生改变。

  状态模式的角色:
抽象状态、具体状态(一种或多个状态,每种状态对应不同的行力),环境(context)角色(就是对象,包括当前对象状态、改变状态的方法和状态行为方法)

  为了帮助理解,举例说明:

  一个画图程序,有一个控制面板,上面罗列了各种画图工具以及其它颜色选择,滴管等工具,当用户选择或改变了画图工具时,就可以使用各种不同的工具进行画图或其他操作了。
我们把这个过程用另外一种方法再描述一下:
- 用户选择画图工具就是一个画笔状态的改变。
- 每个工具能画的图形可能完全不一样,也就是说它们的行为各不一样。
- 改变了画图工具,在画布上画出的图形当然也不一样了,换句话说,画笔状态的改变导致行为的不一样。
 再举个例子,100米短跑远动员。他有三种状态,生病状态,正常状态,兴奋状态。那么状态决定这个运动员的行为,生病状态跑的速度慢,兴奋状态跑的速度快。我们以运动员程序为例,如果不用设计模式的话,我们可能会这写

package com.bill99.pattern;

/**
 *<p>title: 一般运动员</p>
 *<p>Description: </p>
 *<p>CopyRight: CopyRight (c) 2009</p>
 *<p>Company: 99bill.com</p>
 *<p>Create date: 2009-11-3</P>
 *@author Zhang Weiyang <sunnylocus@163.com>
 */
public class Gamer {
	private final int NORMAL_STATE = 0; //正常状态
	private final int MALUM_STATE =1;   //生病状态
	private final int EXCITED_STATE =2; //兴奋状态
	private int state = 0;
	public void setState(int state){
		this.state = state;
	}
	public void run() {
		if(state == NORMAL_STATE) {       //正常状态下跑
			System.out.println("100米,跑完共用时15秒!");
		} else if(state == MALUM_STATE) { //生病状态下跑
			System.out.println("100米,跑完共用时20秒!");
		} else if(state == EXCITED_STATE) {//兴奋状态下跑
			System.out.println("100米,跑完共用时10秒!");
		} else {
			System.out.println("未知的状态");
		}
	}
}

 

如果以后维护的话,要再加一个超级兴奋的状态,得要改原来的源代码,添加一个代表超级兴奋的成员变量,再改if..else if判断,这样做不符合OO设计原则,实现不了程序的松耦合。

下面用状态模式来实现

package com.bill99.pattern.state;

/**
 *<p>title:状态接口 </p>
 *<p>Description:状态接口,每一个状态都要实现此接口 </p>
 *<p>CopyRight: CopyRight (c) 2009</p>
 *<p>Company: 99bill.com</p>
 *<p>Create date: 2009-11-3</P>
 *@author Zhang Weiyang <sunnylocus@163.com>
 */
public interface IState {
	/**
	 * 起跑
	 */
	public void doRun();
}

 

package com.bill99.pattern.state;

/**
 *<p>title: 兴奋状态运动员</p>
 *<p>Description: </p>
 *<p>CopyRight: CopyRight (c) 2009</p>
 *<p>Company: 99bill.com</p>
 *<p>Create date: 2009-11-3</P>
 *@author Zhang Weiyang <sunnylocus@163.com>
 */
public class ExcitedState implements IState {
	public void doRun() {
		System.out.println("100米,跑完共用时10钞!");
	}
}

 

package com.bill99.pattern.state;

/**
 *<p>title:生病状态运动员 </p>
 *<p>Description: </p>
 *<p>CopyRight: CopyRight (c) 2009</p>
 *<p>Company: 99bill.com</p>
 *<p>Create date: 2009-11-3</P>
 *@author Zhang Weiyang <sunnylocus@163.com>
 */
public class MalumState implements IState {

	public void doRun() {
		System.out.println("100米,跑完共用时20秒!");
	}
}

 

package com.bill99.pattern.state;

/**
 *<p>title:正常状态运动员 </p>
 *<p>Description: </p>
 *<p>CopyRight: CopyRight (c) 2009</p>
 *<p>Company: 99bill.com</p>
 *<p>Create date: 2009-11-3</P>
 *@author Zhang Weiyang <sunnylocus@163.com>
 */
public class NormalState implements IState {

	public void doRun() {
		System.out.println("100米,跑完共用时15秒!");
	}
}

 构建一个场景,运动员类,该运动员类包括表示当前对象状态的成员变量,改变当前状态的方法,和状态行为方法

package com.bill99.pattern.state;

/**
 *<p>title: 采用状态模式的运动员</p>
 *<p>Description: </p>
 *<p>CopyRight: CopyRight (c) 2009</p>
 *<p>Company: 99bill.com</p>
 *<p>Create date: 2009-11-3</P>
 *@author Zhang Weiyang <sunnylocus@163.com>
 */
public class Gamer {
	//当前状态
	private IState state = new NormalState();
	//改变状态的方法
	public void setState(IState state){
		this.state = state;
	}
	//状态行为方法,同上面的Gamer 类相比这里没有if..else if判断
	public void run() {
		state.doRun();
	}
}

 测试类

package com.bill99.pattern.state;

/**
 *<p>title: 测试类</p>
 *<p>Description: </p>
 *<p>CopyRight: CopyRight (c) 2009</p>
 *<p>Company: 99bill.com</p>
 *<p>Create date: 2009-11-3</P>
 *@author Zhang Weiyang <sunnylocus@163.com>
 */
public class StateTest {
	public static void main(String[] args) {
		//没有使用状态设计模式
		com.bill99.pattern.Gamer game = new com.bill99.pattern.Gamer();
		game.setState(0);
		game.run();
		game.setState(1);
		game.run();
		game.setState(2);
		game.run();
		System.out.println("---------------------");
		//使用状态设计模式
		//正常状态下跑 
		Gamer gamer = new Gamer();
		gamer.run(); 
		//生病状态下跑
		gamer.setState(new MalumState());
		gamer.run();
		//兴奋状态下跑
		gamer.setState(new ExcitedState());
		gamer.run();
	}
}

 

运行结果:

100米,跑完共用时15秒!
100米,跑完共用时20秒!
100米,跑完共用时10秒!
---------------------
100米,跑完共用时15秒!
100米,跑完共用时20秒!
100米,跑完共用时10钞!

 

假如我们再扩展一个超级兴奋的状态SuperExcitedState,只需实现IState接口,定义好该状态的行为,调用如下

gamer.setState(new  SuperExcitedState());

gamer.run();

而不用改原有代码,提高程序的松耦合。

5
0
分享到:
评论
8 楼 liuzhiwenac 2014-10-29  
各位童鞋,这个最大的好处是实现了“对修改关闭,对扩展开放”,无疑代码会更好维护,更健壮。
7 楼 huangheyuan1229 2013-07-11  
z这个是strategy模式
6 楼 zuishengmengsi1990 2012-05-02  
[b][/b][i][/i][u][/u]
引用
[img][/img][flash=200,200][/flash]

    [*]

    [*]

    [*]

    [*]

    [*]

    [*]

    [*]

    [*]

    [*]

    [*]
[color=darkred][/color][/u][u]
5 楼 k1280000 2011-10-14  
sopships 写道
javne 写道
但是类多了

同感,除非业务内容很多的情况下用,不过好像比较少吧
不过思路可以学习学习


匿名类 ?
4 楼 k1280000 2011-10-14  
匿名类呢 ?
3 楼 gstripe 2010-04-20  
类多了其实也没什么 不要的类删了就是, 重要的是 只要添加类 而不用去该原有的代码。
2 楼 sopships 2010-04-08  
javne 写道
但是类多了

同感,除非业务内容很多的情况下用,不过好像比较少吧
不过思路可以学习学习
1 楼 javne 2010-01-11  
但是类多了

相关推荐

    试谈java设计模式之State.docx

    如果我们经常使用 If-Else 语句来判断状态并进行切换,那么就可以考虑使用 State 模式。例如,在数据库系统中,某个对象的属性不同,对象的行为也不同,这时可以使用 State 模式来实现状态切换。 State 模式的优点...

    PB基础语句

    THEN 语句的语法格式为:IF 逻辑表达式 1 THEN 语句 1 [ELSEIF 逻辑表达式 2 THEN 语句 2 ...] [ELSE 语句 n] END IF。 示例: ``` Integer ss = integer(sle_1.text) IF s St_1.text = “不及格” ELSE St_1....

    试谈java设计模式之State.doc

    State模式的核心思想是封装可能改变的行为到相应的状态对象中,让对象在其内部状态改变时可以调用不同的行为方法,而不是使用大量的if...else语句来判断并执行不同的行为。 在实际开发中,当一个对象的行为依赖于它...

    java设计模式之State.pdf

    - 状态的切换逻辑复杂,如果使用大量的if-else或switch语句会导致代码难以理解和维护。 - 需要将状态相关的操作封装在独立的对象中,以提高代码的复用性和可扩展性。 在Java中,正确使用State模式可以有效地管理和...

    PB基本语句循环语句[参考].pdf

    多行 IF 语句的语法格式为:IF 逻辑表达式1 THEN 语句 1 [ ELSEIF 逻辑表达式 2 THEN 语句 2 ... ] [ ELSE 语句 n] END IF。 例如: Integer s s = integer(sle_1.text) If s St_1.text = “不及格 ” Else St_1...

    C#面向对象设计模式纵横谈(22):(行为型模式) State 状态模式

    - 避免了条件分支语句:状态模式将与特定状态相关的行为封装到相应的状态对象中,消除了大量的if...else或switch语句,提高了代码的可读性和可维护性。 - 允许状态转换逻辑与状态对象绑定在一起,这使得增加新的状态...

    十天学会php之(一二三四五六七八九十)天

    - **if...else**:`if`语句用于条件判断,可以有单个条件、带有`else`的条件和复杂的`if...elseif...else`结构。例如: ```php if ($state == 1) { echo "哈哈"; } else { echo "呵呵"; } ``` - **递归if.....

    java设计模式之-状态模式-实现

    - 消除条件语句:原本可能需要大量if...else或switch...case语句来处理不同状态的情况,现在可以通过状态对象的调用来代替,使得代码更易于理解和维护。 然而,状态模式也有一些潜在的缺点,如增加系统类和对象的...

    10天学会php

    - **if...elseif...else**:多重条件判断,按顺序检查每个条件,直到找到满足的条件并执行相应的代码块。 循环结构包括`for`、`while`、`do...while`和`foreach`等,用于重复执行一段代码,直到特定条件不再满足...

    英文原版的设计模式详解,Patterns in C 2, STATE

    我们可以使用switch语句和if-else链来实现这种行为。 typedef enum { stopped, started } State; struct DigitalStopWatch { /* 让变量持有对象的状态。 */ State state; TimeSource source; Display ...

    c++状态模式

    4. **替代大量条件分支语句**:通过状态模式,可以避免在上下文类中充斥着大量的if...else或者switch...case语句,提高了代码的可读性和可维护性。 然而,状态模式也有一定的缺点,如增加了系统类的数量,可能导致...

    PHP入门教程-PHP版

    - `if...elseif...else`:`if (expr1) { statement1 } elseif (expr2) { statement2 } else { statement3 }` 例如: ```php if ($state == 1) { echo "哈哈"; } else { echo "哎呀"; } ?&gt; ``` 在这个例子中,...

    107个常用javascript语句

    14.JS中的判断语句结构:if(condition){}else{} 15.JS中的循环结构:for([initial expression];[condition];[upadte expression]) {inside loop} 16.循环中止的命令是:break 17.JS中的函数定义:function functionName...

    登录状态判断,使用状态模式

    状态模式通常用于替代复杂的条件语句(如if...else...),使得代码更加清晰和易于管理。我们以登录状态为例来深入探讨这一模式。 在登录应用中,用户的状态主要有两种:未登录和已登录。在传统的编程方式中,我们会...

    c#连接数据库常用的语句

    if (con.State == System.Data.ConnectionState.Closed) con.Open(); } catch (System.Data.SqlClient.SqlException E) { //如果出现错误,关闭数据连接,并抛出错误信息 this.Close(); throw new Exception...

    C语言实现函数查表跳转程序

    2. 使用if-elseif-else语句:使用if-elseif-else语句可以根据不同的输入值跳转到不同的函数中执行。 ```c if (state == 1) { state_fuc1(); } else if (state == 2) { state_fuc2(); } else { ... } ``` 3. 使用...

    jsx-if:一个非常轻量级的助手,它向jsx添加了看起来很自然的条件

    JSX IF 一个非常轻量级的帮助程序,用于在JSX中编写具有本机外观的条件语句。...var _if = jsxIf._if, _elseif = jsxIf._elseif, _else = jsxIf._else;_if函数至少接受两个参数:条件和一个值或函数,如果为true

    设计模式的状态模式的例子

    在某些情况下,大量使用if-else或switch语句会导致代码难以理解和维护,而状态模式则提供了一种优雅的解决方案。 总之,状态模式是一种强大的设计工具,它帮助我们在运行时动态地改变对象的行为,同时保持代码的...

    Java设计模式之状态模式(State模式)介绍

    在示例中,`Context`类的`push`和`pull`方法使用了大量if-else语句来判断和切换状态。这种情况下,使用状态模式可以将每个状态的行为封装到单独的类中,减少代码的耦合度,使得状态的添加、删除或修改更加方便。 ...

    vb学生成绩管理系统

    If ADOcn.State = adStateClosed Then ADOcn.Open '打开到数据库的连接 End Sub 完成本项工作后,就创建了一个全局变量ADOcn,但它是一个特殊的变量,其数据类型是数据连接对象(Connection对象)。可以把ADDcn理解...

Global site tag (gtag.js) - Google Analytics