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,我个人认为判断语句中的条件是类别,不同的类型实现的操作不一样,这样就可以把操作抽象出来。抽象出来的操作子类之间是解耦的。
相关推荐
JS错误Uncaught SyntaxError: Cannot use import statement outside a module< 分析及解决方法 错误信息: 错误分析: HTML 网页中,浏览器通过 script 标签加载 JavaScript 脚本。由于浏览器脚本的默认语言是 ...
例如,你可以创建一个`Statement`对象来执行简单的SQL查询,或者使用`PreparedStatement`对象来防止SQL注入并提高性能。 此外,DM数据库还支持JDBC的事务管理功能,可以使用`Connection`对象的`setAutoCommit()`...
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 ...
词法分析器通常采用正则表达式来定义这些标记的模式,并使用有限状态自动机(Finite State Automata, FSA)来识别这些模式。在PL0中,词法分析器会逐个读取字符,根据预定义的规则生成相应的标记。 接下来是语法...
ERROR 1615 (HY000): Prepared statement needs to be re-prepared 经过测试,发现不是合服脚本的问题。经过一番搜索。发现原来是mysql的变量值设置不合理引起的,调整以下值: table_open_cache 64=>16384 table_...
根据不同的状态和读卡器ID,更新或插入到临时表`#readerstate`中,以便后续进行进一步的分析和处理。 ```sql IF (@State & 0xF0 > 0) BEGIN IF (@PreReaderID <> @ReaderID OR @PreState <> @State) BEGIN UPDATE...
Oracle数据库监听工具
3. 创建Statement:`Statement state = con.createStatement()` 4. 执行SQL:`ResultSet rs = state.executeQuery(sql)` 5. 处理结果:遍历`ResultSet`,获取数据 6. 关闭资源:`rs.close()`, `state.close()`, `con...
* 该软件提供了多种编程语言,包括Ladder Diagram、Function Block和Statement List等。 三、指令和寄存器 * PLC中有多种指令,包括LDI、AI、ONI等,用于实现不同的逻辑控制功能。 * 寄存器是PLC中用于存储数据的...
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语言本身并不直接提供像STL(Statement List,梯形图语言)中那样的FP(Positive Edge,上升沿)和FN(Negative Edge,下降沿)指令。然而,通过自定义函数块(Function Block,FB)或功能(Function,FC)的方式...
private Statement state=null; private Connection conn = null; ResultSet results=null; public connLib() { } public void openConn()throws Exception //连接数据库 { try { Class.forName("sun...
1. **UML基础**:首先,教程会介绍UML的基本元素,包括用例图(Use Case Diagrams)、类图(Class Diagrams)、序列图(Sequence Diagrams)、状态图(State Diagrams)、活动图(Activity Diagrams)和组件图...
在JDBC中,PreparedStatement接口是Statement接口的一个子接口,它提供了预编译的SQL语句,这对于处理动态参数和提高性能非常关键。下面将详细讨论PreparedStatement接口的高级特性以及如何在应用程序中使用它们。 ...
Statement state = conn.createStatement(); ``` 4. **执行SQL查询** - 通过`Statement`对象执行SQL查询,使用`executeQuery(String sql)`方法。这个方法接收一个SQL查询字符串作为参数,并返回一个`ResultSet`...
6. **appropriate**和**inappropriate**:这两个词分别表示“适当的”和“不适当的”,在写作和口语中经常用来评价行为、选择或环境是否适合某种情况。 7. **staff**:代表“全体职员”,通常用作名词,如“the ...
##### 3.1 PreparedStatement和Statement的对比(面试题) - **PreparedStatement**:提供了预编译的功能,可以提高执行效率和安全性,尤其适用于多次执行相同的SQL语句的情况。 - **Statement**:直接执行SQL语句...