• 辣么大
    2020-02-01
    问题1,reporter可测性差的问题,可以mock storage,将request信息到map中。
    // mock
    MetricsStorage storage = new MockRedisMetricsStorage();

    问题2,reporter的创建过程可以使用简单工厂方法。Aggregator完全没有必要暴露出来,可以隐藏。
    ConsoleReporter consoleReporter = ReporterFactory.createConsoleReporter(storage);

    争哥的代码我复制下来,并且跟着重构了一下,想跑跑看的同学请参考:
    https://github.com/gdhucoder/Algorithms4/tree/master/designpattern/u39
    展开
    
     5
  • 小晏子
    2020-01-31
    课后思考:
    1. 将两个reporter中的run里的逻辑单独提取出来做成一个公共函数void doReport(duration, endTime, startTime),这个函数易于单独测试,两个reporter类中调用doReport,因为两个reporter类中并无特殊的逻辑处理,只使用了jdk本身提供的功能,我们可以相信jdk本身的正确性,所以这块就可以不写单元测试了,这就简化了测试也解决了重复代码的问题。
    
     3
  • 平风造雨
    2020-02-01
    1. Reporter中线程调用的run方法可以单独提取一个方法不依赖额外的线程去调用,方便单元测试。
    2. 另外Reporter中的线程模型是否可以单独提取出一个类,该类负责按需创建线程,并且调用实际的埋点统计方法。
    3. 可以借助框架层面依赖注入的方式,更为简单的构造Reporter类。
    
     2
  • javaadu
    2020-01-31
    2. 如果使用Spring Boot之类的框架,就可以利用框架做自动注入;如果没有,则可以用工厂方法设计模式来拼比掉复杂的对象创建过程
    
     2
  • javaadu
    2020-01-31
    1. 看了下,ConoleReporter和EmailReporter的核心区别在于使用的显示器不同,另外就是调度的频次不同,第二个不同是可以通用化的,可以提取出一个抽象的调度器(把查询数据、调用聚合统计对象的代码都放进去),支持每秒、分、时、天调度;ConsoleReportor和EmailReporter都使用这个调度器,自己只维护对应的显示器对象的引用就可以了。
    
     2
  • 杨小将军
    2020-02-09
    下面是目前的想法,希望后面能颠覆现在的想法哈哈
    1、虽然这两个类的执行逻辑代码是一致的,但是这两个类是属于串联执行过程的上帝类,它们的实现代码逻辑是重复的,但语义上是属于不一样的功能,所以其实没有代码重复的问题。
    这两个类的测试我觉得应该不叫单元测试而是集成测试了吧?所以应该是把函数里的各个小函数分别做单元测试。还有一个问题,像类似得到统计数据这种函数应该怎么进行测试呢?比如aggregate()就很难进行测试。
    2、可以设有默认的组装类,只有当需要另外指定其它组装类的时候才需要使用者亲自创建组装类,这应该也是符合框架的易用性及扩展性的。
    展开
    
     1
  • whistleman
    2020-02-07
    打卡~看完一遍理解不是很深刻,准备手敲一遍。
    
     1
  • Jxin
    2020-01-31
    1.将定时和输出报表这两件事分离。单独的定时线程,在关键的时间点都触发一个事件。输出报表的两个类去监听自己关心的时间job的事件(生产消费模式)。如此一来,定时触发好不好使不再是我api使用方考虑的事。我只需要测试对应输出报表的业务是否正常。然后就控制台和邮件这两个报表类,其生成报表的逻辑是一样的,仅仅是展示的“方式”不一样。所以让我选,我会合并这两个类,生成报表的逻辑为私有方法,然后单独写一个控制台输出的public方法和邮箱输出的public方法(输出模式多,且存在组合需求的话会采用分发+约定的方式,降低调用方负担)。那么这个类,生成报表逻辑公用,两个输出方法是走的api,所以也不关心,我只需要测试 报表生成的逻辑即可。

    2.越灵活自然越复杂。 约定大于配置呗。除了业务埋点必须实现,其他都可以约定。
    展开
    
     1
  • 守拙
    2020-01-31
    课堂讨论

    1. 今天我们提到,重构之后的 ConsoleReporter 和 EmailReporter 仍然存在代码重复和可测试性差的问题,你可以思考一下,应该如何解决呢?

       ConsoleReporter和EmailReporter的代码重复集中在viewer#output()部分.可以抽象一个AbsReporter,将重复代码放在基类中,并让ConsoleReporter和EmailReporter继承自AbsReporter. 这里基类与衍生类完全符合is-a关系, 但并未使用多态性.

    2. 从上面的使用示例中,我们可以看出,框架易用性有待提高:ConsoleReporter 和 EmailReporter 的创建过程比较复杂,使用者需要正确地组装各种类才行。对于框架的易用性,你有没有什么办法改善一下呢?

    ​ 可以使用builder模式改造, 提供更友好的依赖注入方式. 除此以外, 还应编写良好的注释, 帮助客户端程序员正确的使用框架.

    ​        示例:

    ​        ConsoleReporter instance = ConsoleReporter.Builder()

    ​         .setMetricsStorate(storage)

    ​         .setAggregator(aggregator)

    ​            .setStatViewer(viewer)

    ​            .setExecutor(executor)

    ​            .build();
    展开
    
     1
  • liu_liu
    2020-01-31
    1. 可定义父类,重复代码抽取为函数进行复用
    2. 用工厂方法,屏蔽创建过程
    
     1
  • 高源
    2020-01-31
    仔细学习分析一下重构后带来的好处,解决了哪些问题
    
     1
  • L🚲🐱
    2020-02-10
    打卡, 看完一遍感觉理解不太深刻, 打算抽时间手敲一遍, 加深理解
    
    
  • Geek_3b1096
    2020-02-10
    结构清晰是关键
    
    
  • ちよくん
    2020-01-31
    打卡
    
    
我们在线,来聊聊吧