当前位置: 首页 > 后端技术 > Java

搞懂钩子方法和模板方法,看完这篇就够了

时间:2023-04-01 16:53:09 Java

要理解hook方法和模板方法,看这篇文章模板方法就够了。钩子方法是抽象方法或定义在接口中的方法的空实现,也是模板方法模式的一种实现。1 模板方法模式下的钩子方法我们以在线课程创建流程为例:发布预览资料→制作课件PPT→直播→提交课堂笔记→提交源代码→布置作业→检查作业。首先创建AbastractCourse抽象类。publicabstractclassAbastractCourse{publicfinalvoidcreateCourse(){//1.发布预习资料postPreResoucse();//2。制作课件PPTcreatePPT();//3。在线直播liveVideo();//4。上传课程发布数据postResource();//5。布局作业postHomework();if(needCheckHomework()){checkHomework();}}受保护的抽象voidcheckHomework();//钩子方法protectedbooleanneedCheckHomework(){returnfalse;}protectedvoidpostHomework(){System.out.println("Assignhomework");}protectedvoidpostResource(){System.out.println("上传课后资料");}protectedvoidliveVideo(){System.out.println("直播课");}protectedvoidcreatePPT(){System.out.println("创建课件");}protectedvoidpostPreResoucse(){System.out.println("发布预览资料");}}上面的代码中有一个hook方法,可能有的朋友不理解,这里说明一下。设计钩子方法的主要目的是干预执行过程,使控制行为过程更加灵活,更符合实际业务需求。hook方法的返回值一般是适合条件分支语句的返回值(如boolean、int等)。小伙伴们可以根据自己的业务场景来决定是否使用hook方式。然后创建JavaCourse类。publicclassJavaCourseextendsAbastractCourse{privatebooleanneedCheckHomework=false;publicvoidsetNeedCheckHomework(booleanneedCheckHomework){this.needCheckHomework=needCheckHomework;}@OverrideprotectedbooleanneedCheckHomework(){returnthis.needCheckHomework;}protectedvoidcheckHomework(){System.out.println("检查Java作业");}}创建PythonCourse类。publicclassPythonCourseextendsAbastractCourse{protectedvoidcheckHomework(){System.out.println("检查Python作业");}}最后写客户端测试代码。publicstaticvoidmain(String[]args){System.out.println("=========架构师课程=========");JavaCoursejava=newJavaCourse();java.setNeedCheckHomework(false);java.createCourse();System.out.println("=========Python教程=========");Python课程python=newPythonCourse();python.createCourse();}通过这样一个案例,相信小伙伴们对模板方法模式有了一个基本的印象。为了加深理解,我们结合一个常见的业务场景来介绍。2 使用模板方法模式重构JDBC业务操作创建一个模板类JdbcTemplate来封装所有的JDBC操作。以查询为例,每个查询表不同,返回的数据结构也不同。对于不同的数据,我们必须将其封装到不同的实体对象中。每个实体封装的逻辑不同,但是封装前后的处理流程是一样的。因此,可以使用模板方法模式来设计这样的业务场景。首先创建约束ORM逻辑的接口RowMapper。/***ORM映射自定义接口*由Tom创建。*/publicinterfaceRowMapper{TmapRow(ResultSetrs,introwNum)throwsException;}然后创建一个封装所有处理流程的抽象类JdbcTemplate。公共抽象类JdbcTemplate{私有数据源数据源;publicJdbcTemplate(DataSourcedataSource){this.dataSource=dataSource;}publicfinalListexecuteQuery(Stringsql,RowMapperrowMapper,Object[]values){try{//1.获取连接Connectionconn=this.getConnection();//2。创建语句集PreparedStatementpstm=this.createPrepareStatement(conn,sql);//3。执行语句setResultSetrs=this.executeQuery(pstm,values);//4。处理结果集Listresult=this.parseResultSet(rs,rowMapper);//5。关闭结果集rs.close();//6。关闭语句集pstm.close();//7。关闭连接conn.close();返回结果;}catch(Exceptione){e.printStackTrace();}返回空值;}privateListparseResultSet(ResultSetrs,RowMapperrowMapper)throwsException{Listresult=newArrayList();int行数=0;while(rs.next()){result.add(rowMapper.mapRow(rs,rowNum++));}返回结果;}privateResultSetexecuteQuery(PreparedStatementpstm,Object[]values)throwsSQLException{for(inti=0;iselectAll(){Stringsql="select*fromt_member";returnsuper.executeQuery(sql,newRowMapper(){publicMembermapRow(ResultSetrs,introwNum)throwsException{Membermember=newMember();//字段太多,原型模式member.setUsername(rs.getString("用户名"));member.setPassword(rs.getString("密码"));member.setAge(rs.getInt("age"));member.setAddr(rs.getString("addr"));返回成员;}},空);}}finally编写客户端测试代码。publicstaticvoidmain(String[]args){MemberDaomemberDao=newMemberDao(null);列表结果=memberDao.selectAll();System.out.println(result);}希望通过这两个案例的业务场景分析,朋友们可以对模板方法模式有更深入的了解。关注微信公众号“汤姆炸弹架构”回复“设计模式”获取完整源码。【推荐】汤姆炸弹架构:30个设计模式实战案例(附源码),挑战60W年薪不是梦技术在于分享,我分享我的快乐!如果本文对您有帮助,请关注并点赞;有什么建议也可以留言或私信。您的支持是我坚持创作的动力。关注微信公众号“汤姆炸弹架构”,获取更多技术干货!