`

state 和 statement

阅读更多

1. Strategy Pattern and State Pattern

(1) Strategy Pattern (i)定义:

定义了算法族,把变化的各个部分封装起来,使得算法可以相互替换并独立于使用该算法的客户。

(ii)结构图: Strategy Pattern/State Pattern - chenxuezhen_1 - 风中飘絮

(iii)意图:封装变化以便类型在运行时根据需要选择合适的算法。这样提高了代码的复用度,也使程序更改更方便。

(iv)用到的OO原则:封装变化;对扩展开放,对修改关闭;针对接口编程而不是实现编程;多用组合少用继承。

(v)例子: 假设我们要完成公司员工这个类的操作,算法如下:

Employees {

string height;

string weight;

string diploma;

public string Description() {

string desc=””; desc += “Heighht:”+height+”;”;

desc += “Weighht:”+weight+”;”;

desc += “Diploma:”+diploma+”;”;

return desc;

}

public decimal GetWage() {

decimal wage if(temp) {

wage = 10*hours;

}

if(accountant) {

wage = 2000+ bonus;

} if(manager) {

wage 5000+bonus+ earning*5%;

}

……

return wage;

}

} 这里,我们假设Employees这个类有两个函数,一个用于个人情况描述的,一个用于计算工资的。个人描述是不变的,而工资的算法则因人而异。这样如果员工的种类改变了,增加或减少都要对类里面的函数进行修改。这种情况下我们就可以用Strategy Pattern来处理了。 首先把变化的部分也就是GetWage这个函数抽象出来成为一个接口或者抽象类: Interface Wage { GetWage(); } 然后根据具体需要加入Wage的子类实现GetWage(); TempWage:Wage { GetWage() { wage = 10*hours; } } AccountantWage:Wage { GetWage() { wage = 2000+ bonus; } } ManagerWage:Wage { GetWage() { wage 5000+bonus+ earning*5%; } } 这样以后就可以在Employees中声明一个Wage接口,把工资的计算委托给Wage接口中的函数来实现,Employees就变成: Employees { Wage wage; public Employees(Wage wage) { this.wage = wage; } string height; string weight; string diploma; public string Description() { string desc=””; desc += “Heighht:”+height+”;”; desc += “Weighht:”+weight+”;”; desc += “Diploma:”+diploma+”;”; return desc; } public decimal GetWage() { wage.GetWage(); } } 这样之后如果程序中要算Manager的工资就可以这样来做了: Manager :Employees() { public Manager() { wage = new ManagerWage();//这里决定用具体哪个工资计算法 } } 这时,主函数中用到的GetWage将是wage 5000+bonus+ earning*5%; Static void main() { Manager manager = new Manager(); Manager.GetWage(); Employees tempemployees = new Employees (new TempWage()); Tempemployees.GetWage();//这里用的将是Temp的工资计算法 } 例子中用策略模式的好处是:如果以后有新的工资计算法,我们只需要加入一个新的Wage子类,而不需要对Employees这个类做任何的改动。这样做还可以复用代码,如果另外一个类有类似的计算和某个工资计算一样,我们也可以直接用Wage这个接口,而不需要加入新的类或接口。 (2) State Pattern (i) 定义:允许对象在内部状态改变的时候改变其行为,使得对象看起来好像改变了它的类。 (ii) 结构图: Strategy Pattern/State Pattern - chenxuezhen_1 - 风中飘絮 (iii) 意图:把与对象状态相关的行为放入状态组成的类中,使对象状态的行为能够随着状态的改变而该变。 (iv) 用到的OO原则:和Strategy Pattern一样。 (v) 例子: 这里我们用TCP连接来举例,TCP连接有三个状态:Open,Lisening, Close,初步实现如下: TCPConnection { string open_state =”open”; string closed_state = “closed”; string listening_state = “listening”; string state = closed_state; public string Open { if(state == open_state) { return “TCP has been opened”; } if(state == closed_state) { state = open_state; return “open successfully” } if(state == listening_state) { return “TCP is listening”; } } public string Close { if(state == open_state) { state =closed_state; return “Closed Successfully”; } if(state == closed_state) { return “TCP has been closed” } if(state == listening_state) { state =closed_state; return “Closed Successfully”; } } public string Listening { if(state == open_state) { state =listening_state; return "Listen Successfully”; } if(state == closed_state) { return “TCP has been closed” } if(state == listening_state) { return “TCP is listening”; } } } 这样,如果我们每加一个State的话,要为每个函数都加一条实现语句,不仅麻烦还很容易出现bug.于是我们就想到了State Pattern。 实现一个State接口: State { Open(); Close(); Listening(); } 实现各个具体状态类: OpenState:State { TCPConnection tcp;//用于记录状态 Open() { return “TCP has been opened”; } Close() { tcp.state = CloseState; return “Close Succefully”; } Listening() { tcp.state = ListenState; return “Listen Succefully”; } } CloseState:State { TCPConnection tcp;//用于记录状态 Close() { return “TCP has been closed”; } Open() { tcp.state = OpenState; return “Open Succefully”; } Listening() { return “TCP has been closed”; } } ListenState:State { TCPConnection tcp;//用于记录状态 Open() { return “TCP is listening”; } Close() { tcp.state = CloseState; return “Close Succefully”; } Listening() { return “TCP has been closed”; } } 这样改了之后TCPConnection就可以写成: TCPConnection { State OpenState; State CloseState; State ListinState State state = CloseState ; state.Open(); state.Close(); state.Listening(); } 使用State Pattern后如果加入新的状态,我们只需要加入新状态的一个State子类就可以了。 (3) Strategy Pattern和State Pattern 异同点: (i) 同点:两种模式的结构图一样,做法都是用接口或者抽象类来封装变化的方法。一般来说在类中有许多判断语句的时候就可以考虑使用这两种模式。(当然模式使用时基于变化的,如果判断语句的条件是定死的,那么不用设计模式也没有问题) (ii) 不同点:意图不一样:State Pattern中很显著的特点就是有状态和行为,并且行为随着状态的改变而改变,相当于判断语句中的条件是一种种状态。State Pattern中实现的状态子类中是有耦合的。而Strategy Pattern,我个人认为判断语句中的条件是类别,不同的类型实现的操作不一样,这样就可以把操作抽象出来。抽象出来的操作子类之间是解耦的。

分享到:
评论

相关推荐

    报错:Uncaught SyntaxError: Cannot use import statement outside a module 详解

    JS错误Uncaught SyntaxError: Cannot use import statement outside a module< 分析及解决方法 错误信息: 错误分析: HTML 网页中,浏览器通过 script 标签加载 JavaScript 脚本。由于浏览器脚本的默认语言是 ...

    dm 数据库 Jdbc 连接驱动

    例如,你可以创建一个`Statement`对象来执行简单的SQL查询,或者使用`PreparedStatement`对象来防止SQL注入并提高性能。 此外,DM数据库还支持JDBC的事务管理功能,可以使用`Connection`对象的`setAutoCommit()`...

    SSD7 EX1 答案

    3. Write the SQL statement to retrieve the title and price of all books published by either of two publishers (say "Addison Wesley" and "McGraw Hill"). In the file Rel-ops.txt, list which relational ...

    pl0词法,语法分析器

    词法分析器通常采用正则表达式来定义这些标记的模式,并使用有限状态自动机(Finite State Automata, FSA)来识别这些模式。在PL0中,词法分析器会逐个读取字符,根据预定义的规则生成相应的标记。 接下来是语法...

    MySQL错误ERROR 1615 解决方法

    ERROR 1615 (HY000): Prepared statement needs to be re-prepared 经过测试,发现不是合服脚本的问题。经过一番搜索。发现原来是mysql的变量值设置不合理引起的,调整以下值: table_open_cache 64=>16384 table_...

    SQL Server2000游标例子

    根据不同的状态和读卡器ID,更新或插入到临时表`#readerstate`中,以便后续进行进一步的分析和处理。 ```sql IF (@State & 0xF0 > 0) BEGIN IF (@PreReaderID <> @ReaderID OR @PreState <> @State) BEGIN UPDATE...

    Oracle跟踪工具SQlTracker

    Oracle数据库监听工具

    jdbc 知识点详解

    3. 创建Statement:`Statement state = con.createStatement()` 4. 执行SQL:`ResultSet rs = state.executeQuery(sql)` 5. 处理结果:遍历`ResultSet`,获取数据 6. 关闭资源:`rs.close()`, `state.close()`, `con...

    中南大学考试试卷13年PLC试卷1.docx

    * 该软件提供了多种编程语言,包括Ladder Diagram、Function Block和Statement List等。 三、指令和寄存器 * PLC中有多种指令,包括LDI、AI、ONI等,用于实现不同的逻辑控制功能。 * 寄存器是PLC中用于存储数据的...

    Java基于jdbc实现的增删改查操作示例

    Statement state = (Statement) conn.createStatement(); int result=state.executeUpdate(sql); state.close(); conn.close(); System.out.println(result+"success"); } catch (ClassNotFoundException e) {...

    逻辑与计算机设计基础 第五版 第四章*习题答案

    此外,还用到了条件语句(case statement)来根据当前状态和输入信号的组合来决定下一个状态。在硬件设计中,这样的代码用于描述如何响应输入信号,以及如何根据输入信号改变系统的内部状态。 综合上述分析,我们...

    SCL高级编程

    SCL语言本身并不直接提供像STL(Statement List,梯形图语言)中那样的FP(Positive Edge,上升沿)和FN(Negative Edge,下降沿)指令。然而,通过自定义函数块(Function Block,FB)或功能(Function,FC)的方式...

    jsp+access实现的图书管理系统

    private Statement state=null; private Connection conn = null; ResultSet results=null; public connLib() { } public void openConn()throws Exception //连接数据库 { try { Class.forName("sun...

    UML与RSA建模教程

    1. **UML基础**:首先,教程会介绍UML的基本元素,包括用例图(Use Case Diagrams)、类图(Class Diagrams)、序列图(Sequence Diagrams)、状态图(State Diagrams)、活动图(Activity Diagrams)和组件图...

    JAVA学习使用JDBC的高级特征创建应用程序PPT教案学习.pptx

    在JDBC中,PreparedStatement接口是Statement接口的一个子接口,它提供了预编译的SQL语句,这对于处理动态参数和提高性能非常关键。下面将详细讨论PreparedStatement接口的高级特性以及如何在应用程序中使用它们。 ...

    通过JDBC通过java连接DB2数据库

    Statement state = conn.createStatement(); ``` 4. **执行SQL查询** - 通过`Statement`对象执行SQL查询,使用`executeQuery(String sql)`方法。这个方法接收一个SQL查询字符串作为参数,并返回一个`ResultSet`...

    雅思阅读超高频词汇及相关衍生词总结.doc

    6. **appropriate**和**inappropriate**:这两个词分别表示“适当的”和“不适当的”,在写作和口语中经常用来评价行为、选择或环境是否适合某种情况。 7. **staff**:代表“全体职员”,通常用作名词,如“the ...

    JDBC专题(三)-JDBC完成用户注册功能

    ##### 3.1 PreparedStatement和Statement的对比(面试题) - **PreparedStatement**:提供了预编译的功能,可以提高执行效率和安全性,尤其适用于多次执行相同的SQL语句的情况。 - **Statement**:直接执行SQL语句...

Global site tag (gtag.js) - Google Analytics