策略模式
举例:
- 比较器
- 旅行路线
- 固定算法策略(封装)
- 买东西结算支付
场景:
根据用户的需求处理数据时候需要对算法做出选择,固定的一些算法(不再发生变化的算法),扩展。(算法会变的时候,不建议用策略模式)
客户本身就知道要采用什么样的算法去计算。(有选择的权利)
assets/支付的策略模式.png
策略模式代码:
Order
.class
public class Order {
private String uId;
private String orderId;
private double amount;
public Order(String uId, String orderId, double amount) {
this.uId = uId;
this.orderId = orderId;
this.amount = amount;
}
// public PayState pay(Payment payment) {
// return payment.pay(this.uId,this.amount);
// }
// 这个参数,完全可以用 Payment 这个接口来代替
// 为什么?
// 完美地解决了 switch 的过程, 不需要在代码逻辑中写 switch le
// 更不需要写 if else 了
public PayState pay(PayType payType) {
return payType.getPayment().pay(this.uId, this.amount);
}
}
PayState
.class
/**
* 支付完成以后的状态
**/
public class PayState {
private int code;
private String msg;
private Object data;
public PayState(int code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
@Override
public String toString() {
return "PayState{" +
"[交易状态:]code=" + code +
", [交易详情:]data=" + data +
", msg='" + msg + '\'' +
'}';
}
}
Payment
.class
public interface Payment {
// 每次增加一个支付渠道,我们就要去维护这个接口一次
// public final static Payment ALI_PAY = new AliPay();
// public final static Payment JD_PAY = new JDPay();
// public final static Payment WECHAT_PAY = new WeChatPay();
// public final static Payment UNION_PAY = new UnionPay();
PayState pay(String uid, double amount);
}
AliPay
.class
public class AliPay implements Payment {
public PayState pay(String uid, double amount) {
System.out.println("欢迎使用支付宝");
System.out.println("查询余额,开始扣款");
return new PayState(200,"支付成功",amount);
}
}
JDPay
.class
public class JDPay implements Payment {
public PayState pay(String uid, double amount) {
System.out.println("欢迎使用京东白条支付");
System.out.println("查询余额,开始扣款");
return new PayState(200,"支付成功",amount);
}
}
UnionPay
.class
public class UnionPay implements Payment {
public PayState pay(String uid, double amount) {
System.out.println("欢迎使用银联卡支付");
System.out.println("查询余额,开始扣款");
return new PayState(200,"支付成功",amount);
}
}
WeChatPay
.class
public class WeChatPay implements Payment {
public PayState pay(String uid, double amount) {
System.out.println("欢迎使用微信支付");
System.out.println("直接从微信红包扣款");
return new PayState(200,"支付成功",amount);
}
}
PayType
enum
public enum PayType {
ALI_PAY(new AliPay()),
JD_PAY(new JDPay()),
WECHAT_PAY(new WeChatPay()),
UNION_PAY(new UnionPay());
private Payment payment;
PayType(Payment payment) {
this.payment = payment;
}
public Payment getPayment() {
return payment;
}
}
PayStrategyTest
.class
public class PayStrategyTest {
public static void main(String[] args) {
// 省略把商品添加到购物车,再从购物车下单
// 直接从订单开始
Order order = new Order("1", "20180311001000009", 324.11);
// 开始支付,选择 微信支付、支付宝、银联卡、京东白条、财付通
// 每个渠道它支付的具体的算法是不一样的
// 基本的算法是固定的
// PayState payState = order.pay(new AliPay());
// PayState payState = order.pay(new JDPay());
// 这个值是在支付的时候才决定用哪个值
PayState payState = order.pay(PayType.ALI_PAY);
System.out.println(payState);
}
}
ComparableTest
.class
public class ComparableTest {
public static void main(String[] args) {
// 这就是一个策略模式
new ArrayList<Object>().sort(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return 0;
}
});
}
}
assets/Payment策略模式设计的支付的类图.png
设计模式都是混合使用,都没有单一存在的。
用设计模式,是用来解决复杂问题的,把复杂的问题简单化。不要去生搬硬套:容易把简单的事情复杂化。
把简单的事情搞复杂,谁都会,但是把复杂的事情变简单,那需要技术含量(借鉴经验)
一个类,直接 new 一下就好了,为什么要搞个工厂模式呢?
Spring 中的策略模式
-
BeanFactory
-
ListableFactory
-
…Factory
根据用户的配置去选择用什么样的工厂创建出来,这就是策略模式,通常会跟抽象工厂模式结合使用
举例:爬虫程序
- 根据 URL 来自动选择
BaiDuParser
爬取百度的数据SinaParser
SougouParser
- 返回解析好的 JSON 格式,统一好了
- 保存入库
模板模式:
通常叫做模板方法模式(Template Method)
举例–饮料:
- 加饮料
- 加水
- 烧水
- 加工
- 混合
固定的方法,通常写成抽象方法,让我们自己去实现
举例–JDBCTemplate
今天利用模板模式,自己写一个
模板模式代码:
Member
.class
public class Member {
private String userName;
private String passWord;
private int age;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
JdbcTemplate
.class – 手写 JDBCTemplate
public class JdbcTemplate {
private DataSource dataSource;
public JdbcTemplate(DataSource dataSource) {
this.dataSource = dataSource;
}
private Connection getConnection() throws Exception {
return this.dataSource.getConnection();
}
private PreparedStatement createPreparedStatement(Connection conn, String sql) throws Exception {
return conn.prepareStatement(sql);
}
private ResultSet executeQuery(PreparedStatement pstmt, Object[] values) throws Exception {
for (int i = 0; i < values.length; i++) {
pstmt.setObject(i, values[i]);
}
return pstmt.executeQuery();
}
private void closeStatement(Statement stmt) throws Exception {
stmt.close();
}
private void closeResultSet(ResultSet rs) throws Exception {
rs.close();
}
private void closeConnection(Connection conn) throws Exception {
// Spring 中,通常是不会关闭,把它放到连接池中回收
}
private List<?> parseResultSet(ResultSet rs, RowMapper rowMapper) throws Exception {
List<Object> result = new ArrayList<Object>();
int rowNum = 1;
while (rs.next()) {
result.add(rowMapper.mapRow(rs, rowNum++));
}
return result;
}
public List<?> executeQuery(String sql, RowMapper<?> rowMapper, Object[] values) {
try {
// 1. 获取链接
Connection conn = this.getConnection();
// 2. 创建语句集
PreparedStatement pstmt = this.createPreparedStatement(conn, sql);
// 3. 执行语句集,并且获得结果集
ResultSet rs = this.executeQuery(pstmt, values);
// 4. 解析语句集
List<?> result = this.parseResultSet(rs, rowMapper);
// 5. 关闭结果集
this.closeResultSet(rs);
// 6. 关闭语句集
this.closeStatement(pstmt);
// 7. 关闭连接
this.closeConnection(conn);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// public abstract Object processResult(ResultSet rs, int rowNum) throws SQLException;
}
RowMapper<T>
.class
public interface RowMapper<T> {
public T mapRow(ResultSet rs, int rowNum) throws Exception;
}
MemberDao
.class
/**
* 解耦
* 抽象类 >>>>>>>> 实现接口
* <br>Darian
**/
public class MemberDao {
// 为什么不继承,主要是为了解耦
// 类似于静态代理,静态代理 JDBCTemplate 的一些方法
private JdbcTemplate jdbcTemplate = new JdbcTemplate(null);
public List<?> query() {
String sql = "SELECT * FROM t_member";
return jdbcTemplate.executeQuery(sql, new RowMapper<Object>() {
public Object mapRow(ResultSet rs, int rowNum) throws Exception {
Member member = new Member();
member.setUserName(rs.getString("userName"));
member.setPassWord(rs.getString("passWord"));
member.setAge(rs.getInt("age"));
return member;
}
}, null);
}
}
MemberDaoTest
.class
public class MemberDaoTest {
public static void main(String[] args) {
MemberDao memberDao = new MemberDao();
memberDao.query();
}
}
assets/JdbcTemplate-手写JDBC模板模式类图.png
assets/模板模式-旅游路线规划.png
策略模式和模板模式对比
策略模式
- 只有选择权(由用户选择已有的固定算法)
模板模式
侧重点不是选择,你没得选择,你必须这么做,你可以参与某一部分内容的自定义去改变执行结果,没办法改变执行流程。
微信公众号:不止极客
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦