频道栏目
首页 > 程序开发 > 软件开发 > Java > 正文
java模板模式与策略模式示例
2011-11-18 13:53:07           
收藏   我要投稿

 

模板方法简介:

把一些公用的通用的内容抽出来,个性的变动的内容做为参数暴露出来,做为一个模板。在使用时只用传递不同的参数到此模板,便可以得到想要的数据结果,这就是设计模式中得模板方法模式。

 

下面是使用模板方法来设计dao层的代码示例:

 

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

 

/**

 * 定义一个抽象的dao父类

 *

 * @author wb_gaobingyin

 *

 */

abstract class BaseDao {

       /**

        * 这里把查询对象时的公用的地方抽出来了,做为查询单个对象的一个模板,

        * 具体的查询将在这个模板上开展,这种处理的方式就叫做模板方法。

        * @param sql

        * @param args

        * @return

        */

       public Object getObject(String sql, Object[] args) {

              Connection conn = null;

              PreparedStatement ps = null;

              ResultSet rs = null;

              Object obj = null;

              try {

                     ps = conn.prepareStatement(sql);

                     rs = ps.executeQuery();

                     for (int i = 0; i < args.length; i++) {

                            ps.setObject(i + 1, args[i]);// 给sql中得参数赋值

                     }

                     if (rs.next()) {

                            obj = this.RowMapperMethod(rs);// 这个方法调用的时总会调用子类中实现的具体方法,进行不同的字段与属性的映射

                     }

              } catch (SQLException e) {

                     e.printStackTrace();

              } finally {

                     // 释放数据库链接对象

              }

              return obj;

       }

 

       public abstract Object RowMapperMethod(ResultSet rs) throws SQLException;

}

 

class UserDaoImpl extends BaseDao {

       /**

        * 根据id查询user对象

        *

        * @return User

        */

       public User getUser() {

              String sql = "select user_id,user_name,age from uset_tbl where user_id=?";

              Object[] args = new Object[] { "abing" };

              User user = (User) this.getObject(sql, args);// 在模板的基础上传入参数,获得想要的结果

              return user;

       }

 

       /**

        * 实现基类中的映射方法,不对的实现dao里有不同的装配方式

        */

       public Object RowMapperMethod(ResultSet rs) throws SQLException {

              User user = new User();

              user.setUserId(rs.getString("user_id"));

              user.setUserName(rs.getString("user_name"));

              user.setAge(rs.getInt("age"));

              return user;

       }

 

}

 

class User {

 

       private String userId;

       private String userName;

       private int age;

 

       public String getUserId() {

              return userId;

       }

 

       public void setUserId(String userId) {

              this.userId = userId;

       }

 

       public String getUserName() {

              return userName;

       }

 

       public void setUserName(String userName) {

              this.userName = userName;

       }

 

       public int getAge() {

              return age;

       }

 

       public void setAge(int age) {

              this.age = age;

       }

 

 

 

 

 

 

 

上面dao的设计基础上,假如我现在有一个新的需求,即根据userId仅仅查询出userName,那该如何处理,如何拓展,显然上面的模板已经不能够满足了,是不是需要再写一个模板呢。想想抽模板的过程,是把不变的部分抽出来,而变的部分sql,args做为参数暴露出,装配参数也是变的,所以是用抽象方法让子类去实现。目前的问题就出在装配上,能不能把装配的过程也做为一个参数传递呢?这里就需要用的策略模式了。

策略模式简介:

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

1、 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。(例如FlyBehavior和QuackBehavior) 2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。(例如FlyBehavior和QuackBehavior的具体实现可任意变化或扩充)

3、 对客户(Duck)隐藏具体策略(算法)的实现细节,彼此完全独立。

 

下面是使用策略模式在模板方法之上的dao层改进代码:

 

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

 

/**

 * 定义一个抽象的dao父类

 *

 * @author abing

 *

 */

class BaseDao {

       /**

        * 在模板方法的基础上,为getObject方法添加了一个RowMapper[策略接口]接口属性,

        * 通过调用方构建不同的RowMapper[策略接口]来完成不同的行为

        *

        * @param sql

        * @param args

        * @return

        */

       public Object getObject(String sql, Object[] args, RowMapper rm) {

              Connection conn = null;

              PreparedStatement ps = null;

              ResultSet rs = null;

              Object obj = null;

              try {

                     ps = conn.prepareStatement(sql);

                     rs = ps.executeQuery();

                     for (int i = 0; i < args.length; i++) {

                            ps.setObject(i + 1, args[i]);// 给sql中得参数赋值

                     }

                     if (rs.next()) {

                            obj = rm.mapRows(rs);

                     }

              } catch (SQLException e) {

                     e.printStackTrace();

              } finally {

                     // 释放数据库链接对象

              }

              return obj;

       }

 

}

 

/**

 * 定义一个行映射器-[策略接口] 只需要这么一个接口,通过内部类的使用就可以构建不同的方法实现体,来完成不同的事情

 *

 * @author abing

 *

 */

interface RowMapper {

       public Object mapRows(ResultSet rs) throws SQLException;

}

 

class UserDaoImpl extends BaseDao {

       /**

        * 根据id查询user对象

        *

        * @return User

        */

       public User getUser() {

              String sql = "select user_id,user_name,age from uset_tbl where user_id=?";

              Object[] args = new Object[] { "abing" };

              // 这里使用匿名内部类

              User user = (User) this.getObject(sql, args, new RowMapper() {

                     @Override

                     public Object mapRows(ResultSet rs) throws SQLException {

                            // 构建并且返回user对象,这是一种策略

                            User user = new User();

                            user.setUserId(rs.getString("user_id"));

                            user.setUserName(rs.getString("user_name"));

                            user.setAge(rs.getInt("age"));

                            return user;

 

                     }

              });

              return user;

       }

 

       /**

        * 根据id查询userName属性

        *

        * @return User

        */

       public String getUserName() {

              String sql = "select user_id,user_name,age from uset_tbl where user_id=?";

              Object[] args = new Object[] { "abing" };

              // 构建且仅返回userName字符串对象,这也是一种策略

              String userName = (String) this.getObject(sql, args, new RowMapper() {

                     @Override

                     public Object mapRows(ResultSet rs) throws SQLException {

                            // TODO Auto-generated method stub

                            return rs.getString("user_name");

                     }

              });

              return userName;

       }

 

}

 

class User {

 

       private String userId;

       private String userName;

       private int age;

 

       public String getUserId() {

              return userId;

       }

 

       public void setUserId(String userId) {

              this.userId = userId;

       }

 

       public String getUserName() {

              return userName;

       }

 

       public void setUserName(String userName) {

              this.userName = userName;

       }

 

       public int getAge() {

              return age;

       }

 

       public void setAge(int age) {

              this.age = age;

       }

 

}

摘自 pcenshao

点击复制链接 与好友分享!回本站首页
上一篇:一个Java程序员应该掌握的10项技能
下一篇:java通过ftp进行文件的上传下载
相关文章
图文推荐
文章
推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站