设计模式——命令模式

来源:互联网 发布:华西附二院抢号软件 编辑:程序博客网 时间:2024/06/04 21:26

一 引入

问题:如何对一个对象类的操作进行解耦,使他们的执行可以动态地安排。

解决:定义一个统一的命令接口,让具体命令对象类的解耦操作。

二 类图


三 实例

继续考察上一遍博文中,数据库连接的实例,在MySqlImpl类中,有四个方法,但是通常远远不止四个方法,如果全写在这一个类中,类将会变得难以理解和维护,所以将其每个方法变为一个类:

3.1 Command Interface——DBCmd.java

public abstract class DBCmd {Object result;public abstract void excute();public Object getResult(){return result;}}

3.2 Concrete Command1——ConnectDB.java

public class ConnectDB extends DBCmd {@Overridepublic void excute() {String url = "jdbc:mysql://127.0.0.1/ARS";      String driver = "com.mysql.jdbc.Driver";      Connection conn = null;      try {              Class.forName(driver);//指定连接类型              conn = DriverManager.getConnection(url, "root", "root");//获取连接          } catch (Exception e) {              e.printStackTrace();          }    result=conn;}}

3.3  Concrete Command2——DisconnectDB.java

public class DisconnectDB extends DBCmd {Connection conn=null;public DisconnectDB(Connection conn) {super();this.conn=conn;}@Overridepublic void excute() {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}

3.4 Concrete Command3——GetUser.java

public class GetUser extends DBCmd {int id;public GetUser(int id) {super();this.id=id;}@Overridepublic void excute() {User user=new User();ConnectDB connectDB=new ConnectDB();connectDB.excute();Connection conn=(Connection)connectDB.getResult();String sql="select * from User where id=?";try{PreparedStatement ps=conn.prepareStatement(sql);ps.setInt(1, id);ResultSet rs=ps.executeQuery();rs.next();user.setId(rs.getInt("id"));user.setUserName(rs.getString("userName"));user.setPassword(rs.getString("password"));}catch (Exception e) {e.printStackTrace();}finally {DisconnectDB disconnectDB=new DisconnectDB(conn);disconnectDB.excute();}result=user;}}

3.5 Concrete Command3——SaveUser.java

public class SaveUser extends DBCmd {@Overridepublic void excute() {}}

按照上面写就好了,这里就不写了。。

3.6 Client.java

public class Client {public static void main(String args[]){GetUser getUser=new GetUser(1);getUser.excute();User user=(User)getUser.getResult();System.out.println(user.getUserName());}}

四 总结分析

4.1 适用情况

(1)将请求封装为命令对象,如上例。

(2)应用程序需要添加新的请求或函数,如上例需要添加删除User的函数。

(3)应用程序需要将请求排队并在不同的时间执行它们。

(4)应用程序需要动态改变动作执行顺序。

(5)应用程序需要支持撤销和重做。

(6)系统恢复中,应用程序需要记录更改并重做。备忘录模式也可用。

4.2 优点

(1)封装操作为命令对象,操作能灵活执行。

(2)可采用复合模式组成复合命令。

(3)容易添加新命令。

(4)支持撤销和重做操作。

4.3 缺点

所欲方法都变成一个类里的execute了。。。所以你有n多类要写。。


原创粉丝点击