设计模式——命令模式

一 引入

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

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

二 类图


三 实例

继续考察上一遍博文中,数据库连接的实例,在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 {
	@Override
	public 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;
	}
	@Override
	public 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;
	}
	@Override
	public 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 {

	@Override
	public 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多类要写。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值