Strategy pattern

概念

策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。 策略模式: 定义了一族算法; 封装了每个算法; 这族的算法可互换代替
——Wikipedia

需求

设计一个 Sorter 类,可以根据不同的比较策略对对象进行排序。
比如现在有一个 Cat 类数组,我需要根据 Cat 类的 weight 属性对 Cat 数组进行排序。

Code

Cat.java

public class Cat{
    int weight, height;

    public Cat(int weight, int height) {
        this.weight = weight;
        this.height = height;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "weight=" + weight +
                ", height=" + height +
                '}';
    }
}

Sorter.java

public class Sorter<T> {

    public void sort(T[] arr, Comparator<T> comparator) {
        for(int i=0; i<arr.length - 1; i++) {
            int minPos = i;
				
            for(int j=i+1; j<arr.length; j++) {
                minPos = comparator.compare(arr[j],arr[minPos])==-1 ? j : minPos;
            }
            swap(arr, i, minPos);
        }
    }

    void swap(T[] arr, int i, int j) {
        T temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

Comparator.java
comparator 接口的不同实现就可以理解为不同的比较策略

@FunctionalInterface
public interface Comparator<T> 

Main.java

public class Main {
    public static void main(String[] args) {
        Cat[] a = {new Cat(3, 3), new Cat(5, 5), new Cat(1, 1)};
        Sorter<Cat> sorter = new Sorter<>();
        //Lambda表达式实现Comparator接口
        sorter.sort(a, (o1, o2) -> {
            if (o1.weight < o2.weight) return -1;
            else if (o1.weight > o2.weight) return 1;
            else return 0;
        });
        System.out.println(Arrays.toString(a));
    }
}

Spirng JdbcTemplate 中使用不同策略来处理结果集

Spring 版本为:1.0-m1

	public void doWithResultSetFromPreparedQuery(PreparedStatementCreator psc, ResultSetExtractor rse) throws DataAccessException {
		Connection con = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			con = DataSourceUtils.getConnection(this.dataSource);
			ps = psc.createPreparedStatement(con);

			if (logger.isInfoEnabled())
				logger.info("Executing SQL query using PreparedStatement: [" + psc + "]");

			rs = getQueryExecutor().executeQuery(ps);
			// 处理结果集 ResultSet rs
			rse.extractData(rs);

			SQLWarning warning = ps.getWarnings();
			rs.close();
			ps.close();
			throwExceptionOnWarningIfNotIgnoringWarnings(warning);
		}
		catch (SQLException ex) {
			if (rs != null) {
				try {
					rs.close();
				}
				catch (SQLException ignore) {}
			}
			if (ps != null) {
				try {
					ps.close();
				}
				catch (SQLException ignore) {}
			}
			throw getExceptionTranslator().translate("JdbcTemplate.query(psc) with PreparedStatementCreator [" + psc + "]", null, ex);
		}
		finally {
			DataSourceUtils.closeConnectionIfNecessary(con, this.dataSource);
		}
	}

rse.extractData(rs); 这行代码是处理结果集。ResultSetExtractor 是一个接口。

public interface ResultSetExtractor {
	void extractData(ResultSet rs) throws SQLException; 
}

不同的子类可以有不同的处理 rs 的策略。比如 RowCallbackHandlerResultSetExtractor 类的实现如下所示:

		public void extractData(ResultSet rs) throws SQLException {
			while (rs.next()) {
				this.callbackHandler.processRow(rs);
			}
		}

总结

策略模式高内聚了不变的流程,将变化的流程抽象为策略接口。即封装不变,暴露变化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值