设计模式之模板方法模式-场景、例子、深入

  • 前言
  • 模板方法的设计模式的使用场景
  • 具体场景例子
  • 具体例子的类图
    • 1.声明抽象模板类AbstaractSearchTemplate
    • 2. 具体子类
      • 2.1 具体子类DnsTopDelaySearch
      • 2.2 具体子类SipTopDelaySearch
    • 3. 具体子类的使用
      • 3.1 具体子类DnsTopDelaySearch的使用
      • 3.2 具体子类SipTopDelaySearch的使用
    • 4. 钩子

前言

模板方法的设计模式的使用场景

设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关。算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。

具体场景例子

比如现在我们可以确定获取指标A,指标B,指标C,指标D,都需要经过,连接初始化,连接,执行,转换,关闭,五个步骤,并且对每个指标来说除极个别情况来说,初始化,连接,关闭三个步骤内部细节都是一样的。

具体例子的类图

1.声明抽象模板类AbstaractSearchTemplate

package cn.unicom.panabitpendant.TemplateMethod;import cn.unicom.panabitpendant.pojo.DelayPo;
import com.google.common.collect.Lists;
import io.github.whyareyousoseriously.czcommonutils.util.IpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;/*** @author chenzhen* Created by chenzhen on 2020/6/23.*/
abstract class AbstractSearchTemplate<T> {public static Logger log = LoggerFactory.getLogger(AbstractSearchTemplate.class);public String user;public String password;public String ip;public String port;public String dbDriver;public String table;Connection conn = null;Statement stmt = null;ResultSet rs = null;/*** 数据初始化*/public void init(String user, String password, String ip, String port, String dbDriver) {this.user = user;this.password = password;this.ip = ip;this.port = port;this.dbDriver = dbDriver;}/*** 连接*/public void connection() {long now = System.currentTimeMillis();SimpleDateFormat dbNameFormat = new SimpleDateFormat("yyyyMMddHH");String dbName = "npmflow" + dbNameFormat.format(new Date(now));SimpleDateFormat tableNameFormat = new SimpleDateFormat("yyyyMMddHHmm");//List<String> tables = this.generateHoursTable(new Date(now - 60 * 2 * 1000));table = tableNameFormat.format(new Date(now - 60 * 3 * 1000));// JDBC 驱动名 及数据库 URLfinal String JDBC_DRIVER = dbDriver;final String DB_URL = "jdbc:mysql://" + ip + ":" + port + "/" + dbName;// 数据库的用户名与密码,需要根据自己的设置final String USER = user;final String PASS = password;try {// 注册 JDBC 驱动// 把Driver类装载进jvmClass.forName(JDBC_DRIVER);// 打开链接log.info("连接数据库..." + DB_URL);conn = DriverManager.getConnection(DB_URL, USER, PASS);// 执行查询stmt = conn.createStatement();} catch (ClassNotFoundException | SQLException e) {e.printStackTrace();}}/*** 执行,转换*/public abstract T transform() throws SQLException;/*** 关闭*/public void close(){try {rs.close();} catch (SQLException e) {e.printStackTrace();}finally {// 关闭资源if (stmt != null) {try {stmt.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}log.info("连接结束");}public T exec(){T transform = null;try {this.connection();transform = this.transform();this.close();} catch (SQLException e) {e.printStackTrace();}return transform;}
}

2. 具体子类

2.1 具体子类DnsTopDelaySearch

package cn.unicom.panabitpendant.TemplateMethod;import cn.unicom.panabitpendant.config.IpPartition;
import cn.unicom.panabitpendant.pojo.DnsDelayPo;
import cn.unicom.panabitpendant.pojo.TopDelayPo;
import com.google.common.collect.Lists;
import io.github.whyareyousoseriously.czcommonutils.util.IpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;/*** @author chenzhen* Created by chenzhen on 2020/6/23.*/
@Component
public class DnsTopDelaySearch extends AbstractSearchTemplate<List<DnsDelayPo>> {@Overridepublic List<DnsDelayPo> transform() throws SQLException {List<DnsDelayPo> topDelayPos = Lists.newArrayList();String sql = "SELECT\n" +"t.s1 AS sIp, " +"t.sport AS sPort, " +"t.d1 AS dIp, " +"t.dport AS dPort, " +"t.host AS domainName, " +"t.appdelay AS appDelay " +"FROM " + "`" + super.table + "`" + " AS t " +"WHERE " +"t.appid = 6 " + " AND " +"t.pro = 17 " +"ORDER BY " +"t.appdelay DESC LIMIT 50" +";";super.rs = stmt.executeQuery(sql);while (rs.next()) {// 通过字段检索double appDelay = super.rs.getDouble("appDelay");String sIp = IpUtil.longToIP(super.rs.getLong("sIp"));String sPort = "" + super.rs.getInt("sPort");String dIp = IpUtil.longToIP(super.rs.getLong("dIp"));String dPort = "" + super.rs.getInt("dPort");String domainName = super.rs.getString("domainName");topDelayPos.add(new DnsDelayPo(sIp, sPort, dIp, dPort, domainName,0.0, 0.0, appDelay));}return topDelayPos;}
}

2.2 具体子类SipTopDelaySearch

package cn.unicom.panabitpendant.TemplateMethod;import cn.unicom.panabitpendant.config.IpPartition;
import cn.unicom.panabitpendant.pojo.DelayPo;
import com.google.common.collect.Lists;
import io.github.whyareyousoseriously.czcommonutils.util.IpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.sql.SQLException;
import java.util.List;
import java.util.Map;/*** @author chenzhen* Created by chenzhen on 2020/6/24.*/
@Component
public class SipDelaySearch extends AbstractSearchTemplate<List<DelayPo>> {@Autowiredprivate IpPartition ipPartition;@Overridepublic List<DelayPo> transform() throws SQLException {List<Map<String, String>> sipPartitionMap = ipPartition.getSipPartitionMap();List<DelayPo> delayPos = Lists.newArrayList();for (Map<String, String> stringStringMap : sipPartitionMap) {String scope = stringStringMap.get("scope");String[] split = scope.split(",");for (String s : split) {String[] se = s.split("-");long startIp = IpUtil.ipToLong(se[0]);long endIp = IpUtil.ipToLong(se[1]);String province = stringStringMap.get("province");String area = stringStringMap.get("area");String sql = "SELECT\n" +"Avg(t.clntdelay) AS avg_clntdelay, " +"Avg(t.svrdelay) AS avg_svrdelay, " +"Avg(t.appdelay) AS avg_appdelay, " +"MAX(t.clntdelay) AS max_clntdelay, " +"MAX(t.svrdelay) AS max_svrdelay, " +"MAX(t.appdelay) AS max_appdelay, " +"MIN(t.clntdelay) AS min_clntdelay, " +"MIN(t.svrdelay) AS min_svrdelay, " +"MIN(t.appdelay) AS min_appdelay, " +"AVG(t.retmixpkts1/t.pkts1) AS avg_up_rr, " +"MIN(t.retmixpkts1/t.pkts1) AS min_up_rr, " +"MAX(t.retmixpkts1/t.pkts1) AS max_up_rr, " +"AVG(t.retmixpkts2/t.pkts2) AS avg_down_rr, " +"MIN(t.retmixpkts2/t.pkts2) AS min_down_rr, " +"MAX(t.retmixpkts2/t.pkts2) AS max_down_rr " +"FROM " + "`" + table + "`" + " AS t " +"WHERE " +"t.s1 >= " + startIp + " AND " +"t.s1 <= " + endIp + " AND " +"t.pro = 17" + " AND " +//"t.appid = 61" + " AND " +"t.appdelay > 0" +";";rs = stmt.executeQuery(sql);while (rs.next()) {// 通过字段检索double clientDelay = rs.getDouble("avg_clntdelay");double serviceDelay = rs.getDouble("avg_svrdelay");double appDelay = rs.getDouble("avg_appdelay");double maxDelay = rs.getDouble("max_clntdelay");double maxServiceDelay = rs.getDouble("max_svrdelay");double maxAppDelay = rs.getDouble("max_appdelay");double minDelay = rs.getDouble("min_clntdelay");double minServiceDelay = rs.getDouble("min_svrdelay");double minAppDelay = rs.getDouble("min_appdelay");double avgUpRr = rs.getDouble("avg_up_rr");double minUpRr = rs.getDouble("min_up_rr");double maxUpRr = rs.getDouble("max_up_rr");double avgDownRr = rs.getDouble("avg_down_rr");double minDownRr = rs.getDouble("avg_down_rr");double maxDownRr = rs.getDouble("avg_down_rr");delayPos.add(new DelayPo(province, area, clientDelay, serviceDelay, appDelay, maxDelay, maxServiceDelay, maxAppDelay,minDelay, minServiceDelay, minAppDelay, avgUpRr, minUpRr, maxUpRr, avgDownRr, minDownRr, maxDownRr));}}}return delayPos;}
}

3. 具体子类的使用

3.1 具体子类DnsTopDelaySearch的使用

public List<DnsDelayPo> dnsTopDelay() {dnsTopDelaySearch.init(user, password, ip, port, dbDriver);return dnsTopDelaySearch.exec();}

3.2 具体子类SipTopDelaySearch的使用

public List<TopDelayPo> getSipTopDelay() {sipTopDelaySearch.init(user, password, ip, port, dbDriver);return sipTopDelaySearch.exec();}

4. 钩子

钩子方法的返回结果决定了模板方法后面部分的执行步骤,也就是程序接下来的走向,
这样一来,程序就拥有了变化的可能。
未完待续

JAVA设计模式之模板方法模式-场景、例子、深入相关推荐

  1. Java设计模式之模板方法模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

  2. JAVA设计模式之--模板方法模式

    序言 在现实生活中,很多事情都包含几个实现步骤,例如请客吃饭,无论吃什么,一般都包含点单.吃东西.买单等几个步骤,通常情况下这几个步骤的次序是:点单 --> 吃东西 --> 买单.在这三个 ...

  3. Java 设计模式之模板方法模式

    一.了解模板方法模式 1.1 什么是模板方法模式 模板方法模式 Template Method Parrern)在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变 ...

  4. 从西天取经的九九八十一难来看Java设计模式:模板方法模式

    模板方法模式 示例 模板方法模式 定义 意图 主要解决问题 适用场景 优缺点 西天取经的九九八十一难 示例 当我们设计一个类时,我们能明确它对外提供的某个方法的内部执行步骤, 但一些步骤,不同的子类有 ...

  5. java设计模式 之 模板方法模式

    1.模板方法模式的定义: 定义一个操作中的算法的框架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 2.模板方法模式的优点: ● 封装不变部分,扩展可变部 ...

  6. Java设计模式之——模板方法模式

    Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Me ...

  7. java状态模式例子答案_[转载]java设计模式_状态模式(带例子)

    状态模式(STATE) Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广泛,遵循一定的编 ...

  8. 折腾Java设计模式之建造者模式

    博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...

  9. java 模板方法_设计模式(java实现)_模板方法模式(Template method)

    设计模式(java实现)_模板方法模式(Template method) 模板方法模式是编程中经常用到到的模式.它定义了一个操作中的算法骨架,将某些步骤延迟到子类中实现.这样,新的子类可以在不改变一个 ...

  10. java备忘录模式应用场景_图解Java设计模式之备忘录模式

    图解Java设计模式之备忘录模式 游戏角色状态恢复问题 游戏角色有攻击力和防御力,在大战Boss前保存自身的状态(攻击力和防御力),当大战Boss后攻击力和防御力下降,从备忘录对象恢复到大战前的状态. ...

最新文章

  1. python 第三方库
  2. IOS笔记CALayer的position和anchorPoint
  3. CSDN博客如何在有序序列中缩进代码段或图片
  4. java thread 输出结果_大神来看看这段程序输出结果是什么?
  5. FPGA学习笔记---任务(task) 和函数 (function)
  6. div+css布局与seo的关系
  7. Blocks in Objective-C
  8. java之重定向与转发
  9. 【待补充】[Linux] nc
  10. 转:详细图解,一眼就能看懂!卷帘快门(Rolling Shutter)与全局快门(Global Shutter)的区别
  11. 值得推荐的在线报表设计器
  12. 7-4 疯狂星期四!!!!!
  13. 现代密码学-CA与数字证书详解
  14. 微信开发——测试号申请,接口配置,JS接口安全域名,自定义菜单
  15. swoole并没有你说的那么好,@韩天峰
  16. web安全性测试用例
  17. 谷歌移动端seo优化如何做
  18. March 4 2017 Week 10 Saturday
  19. 【日常篇】003_利用b站数据看《博人传》口碑变化
  20. weka java 分类算法_使用Weka快速实践机器学习算法

热门文章

  1. java web 学习计划
  2. 银江股份:全面布局持续并购打造智慧城市生态圈
  3. Spring MVC 全局异常处理(1) --HandlerExceptionResolver
  4. Python字符串、元组、列表、字典互相转换的方法
  5. Android Studio Prettify 插件
  6. 【分块】bzoj2120 数颜色
  7. 如何使用jquery处理json数据
  8. 监听listview item兼容于checkbox/textview/imageview
  9. 第八章第二层交换和生成树协议(STP)
  10. 纯数学教程 Page 203 例XLI (2)