zoukankan      html  css  js  c++  java
  • 运用学过的设计原则和思想完善之前讲的性能计数器项目(下)

    上一节课中,我们针对版本 1 存在的问题(特别是 Aggregator 类、ConsoleReporter 和 EmailReporter 类)进行了重构优化。经过重构之后,代码结构更加清晰、合理、有逻辑性。不过,在细节方面还是存在一些问题,比如 ConsoleReporter、EmailReporter 类仍然存在代码重复、可测试性差的问题。今天,我们就在版本 3 中持续重构这部分代码。

    除此之外,在版本 3 中,我们还会继续完善框架的功能和非功能需求。比如,让原始数据的采集和存储异步执行,解决聚合统计在数据量大的情况下会导致内存吃紧问题,以及提高框架的易用性等,让它成为一个能用且好用的框架。

    代码重构优化

    我们知道,继承能解决代码重复的问题。我们可以将 ConsoleReporter 和 EmailReporter 中的相同代码逻辑,提取到父类 ScheduledReporter 中,以解决代码重复问题。按照这个思路,重构之后的代码如下所示:

    
    public abstract class ScheduledReporter {
      protected MetricsStorage metricsStorage;
      protected Aggregator aggregator;
      protected StatViewer viewer;
    
      public ScheduledReporter(MetricsStorage metricsStorage, Aggregator aggregator, StatViewer viewer) {
        this.metricsStorage = metricsStorage;
        this.aggregator = aggregator;
        this.viewer = viewer;
      }
    
      protected void doStatAndReport(long startTimeInMillis, long endTimeInMillis) {
        long durationInMillis = endTimeInMillis -  startTimeInMillis;
        Map<String, List<RequestInfo>> requestInfos =
                metricsStorage.getRequestInfos(startTimeInMillis, endTimeInMillis);
        Map<String, RequestStat> requestStats = aggregator.aggregate(requestInfos, durationInMillis);
        viewer.output(requestStats, startTimeInMillis, endTimeInMillis);
      }
    
    }
    

    ConsoleReporter 和 EmailReporter 代码重复的问题解决了,那我们再来看一下代码的可测试性问题。因为 ConsoleReporter 和 EmailReporter 的代码比较相似,且 EmailReporter 的代码更复杂些,所以,关于如何重构来提高其可测试性,我们拿 EmailReporter 来举例说明。将重复代码提取到父类 ScheduledReporter 之后,EmailReporter 代码如下所示:

    
    public class EmailReporter extends ScheduledReporter {
      private static final Long DAY_HOURS_IN_SECONDS = 86400L;
    
      private MetricsStorage metricsStorage;
      private Aggregator aggregator;
      private StatViewer viewer;
    
      public EmailReporter(MetricsStorage metricsStorage, Aggregator aggregator, StatViewer viewer) {
        this.metricsStorage = metricsStorage;
        this.aggregator = aggregator;
        this.viewer = viewer;
      }
    
      public void startDailyReport() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date firstTime = calendar.getTime();
    
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
          @Override
          public void run() {
            long durationInMillis = DAY_HOURS_IN_SECONDS * 1000;
            long endTimeInMillis = System.currentTimeMillis();
            long startTimeInMillis = endTimeInMillis - durationInMillis;
            doStatAndReport(startTimeInMillis, endTimeInMillis);
          }
        }, firstTime, DAY_HOURS_IN_SECONDS * 1000);
      }
    }
    
  • 相关阅读:
    js排序算法01——冒泡排序
    Math Issues
    2017年终总结
    js中的真值和假值
    element UI 中DateTimePicker 回传时间选择
    Equal Sides Of An Array
    javascript数组总结(0504)
    ajax生成html双引号问题
    关于php ci框架ie浏览器路径问题
    ie提示jquer缺少标识符,字符串或数字
  • 原文地址:https://www.cnblogs.com/ukzq/p/14837779.html
Copyright © 2011-2022 走看看