百万架构师第六课:设计模式:策略模式及模板模式
2025/1/4 6:03:20
本文主要是介绍百万架构师第六课:设计模式:策略模式及模板模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
策略模式
举例:
- 比较器
- 旅行路线
- 固定算法策略(封装)
- 买东西结算支付
场景:
根据用户的需求处理数据时候需要对算法做出选择,固定的一些算法(不再发生变化的算法),扩展。(算法会变的时候,不建议用策略模式)
客户本身就知道要采用什么样的算法去计算。(有选择的权利)
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
策略模式和模板模式对比
策略模式
- 只有选择权(由用户选择已有的固定算法)
模板模式
侧重点不是选择,你没得选择,你必须这么做,你可以参与某一部分内容的自定义去改变执行结果,没办法改变执行流程。
来源于: https://javaguide.net
微信公众号:不止极客
这篇关于百万架构师第六课:设计模式:策略模式及模板模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-04敏捷管理与看板工具:提升研发、设计、电商团队工作效率的利器
- 2025-01-04智慧养老管理工具如何重塑养老生态?
- 2025-01-04如何打造高绩效销售团队:工具与管理方法的结合
- 2025-01-04解决电商团队协作难题,在线文档工具助力高效沟通
- 2025-01-04春节超市管理工具:解锁高效运营与顾客满意度的双重密码
- 2025-01-046种主流销售预测模型:如何根据场景选用最佳方案
- 2025-01-04外贸服务透明化:增强客户信任与合作的最佳实践
- 2025-01-04重新定义电商团队协作:在线文档工具的战略作用
- 2025-01-04Easysearch Java SDK 2.0.x 使用指南(三)
- 2025-01-04百万架构师第八课:设计模式:设计模式容易混淆的几个对比|JavaGuide