• chanllenge
    2020-01-22

    public class RandomIdGenerator implements LogTraceIdGenerator,应该是这么写吧?

    作者回复: 代码有点问题,我更新一下,抱歉

     1
     15
  • Yang
    2020-01-22
    1.应该需要继续抛出,因为在实际的业务开发中,会有对应的异常处理器,抛出可以让调用者明白哪出错了,而不是只是简单的打印日志。
    2.命名getLastSubstrSplittedByDot替换成getLastSubstrByDelimiter,具体要看需求会不会经常变化,如果经常变化,替换没有任何问题,因为有可能后面根据别的符号来分割,这种情况下我个人认为getLastFiledOfHostName()函数命名应该替换成getLastFiled(),命名不应该暴露太多细节,要是以后不是根据HostName获取最后一个字段呢,之前的所有用到该命名的地方都需要替换,不然可读性不是很好。
    如果需求不经常变化,那文中的命名就足够了。
    展开
     1
     13
  • 小晏子
    2020-01-22
    在获取主机名失败的时候,generate函数应该能正常返回,因为是随机id,所以只要有个满足要求的id就行了,用户并不关心能不能拿到主机名字,所以在获取主机名失败的时候,可以返回一个默认的主机名,之后在拼接上时间戳和随机数也是满足需求的id,所以我认为generate函数在主机名失败的时候应该使用默认主机名正常返回。另外对于小王的异常处理我认为是可以捕获处理的,只是不能该让整个函数都返回一个空id,而是应该捕获异常时使用一个默认主机名继续后面的逻辑。
    第二个问题:为了隐藏代码实现细节,我们把 getLastSubstrSplittedByDot(String hostName) 函数命名替换成 getLastSubstrByDelimiter(String hostName),这样是否更加合理?为什么?
    我认为是合理的,命名和代码的逻辑不绑定,避免了以后修改代码逻辑还要修改函数名的麻烦,比如将来可能不用点去分割hostname了,用空格分割,这时byDot函数名就不合适了,如果修改,那么所有使用到这个函数的地方都要改,大大增加了出错的概率。
    展开
     3
     8
  • 辣么大
    2020-01-22
    这两期争哥讲重构,我把Uncle Bob的《重构2》的第一章看了,大呼过瘾。自己也要操刀试一下!

    他和Kent Beck强调重构时要用baby step(小步骤),什么是baby step呢?就是一次改一小点,例如改一个变量名字都需要进行 modify-build-test的步骤。

    对于争哥的例子,我参考Uncle Bob书中的方法:
    第一步、先写好测试
    第二步、开始逐步重构(baby step)
    第三步、修改-> 测试

    经过重构之后代码总计50行。重构之后代码易读,且结构清晰。
    https://github.com/gdhucoder/Algorithms4/blob/master/designpattern/u35/RandomLogTraceIDGenerator.java
    展开
    
     6
  • Wings
    2020-01-23
    争哥,我是看了你的算法之美后立刻看到你出设计模式之美就立刻买。可是专栏更新到现在快一半,老实说,我觉得内容真的很基础甚至脱离实际开发,很多都是浅尝辄止。专栏一开始渲染了好多说会有很多可落地的代码,可目前为止看到的都是很虚无聊会或者是大家早就知道的东西。如果可以的话,能否在后续课程多分享一些真正的企业级的代码设计和重构呢?

    作者回复: 抱歉没有呢,让你失望了,不过,我还会出新课的,以后你就别买我的课程了。因为新课估计也会让你失望的~

    说实话,我觉得的我写的很好,而且很结合实际开发,很多人留言说我写的好,当然也有人根本不识货!如果你觉得哪一个不能落地,能具体指出来吗?或者你觉得哪篇写的不好,网上或者哪本书籍讲的比我讲的好,你指出来。不然你随口一说,无凭无据,那不就瞎喷吗?说实话啥都不懂瞎喷的人太多了,我也不可能一个一个的喷回去,没意思,如果你觉得有写的不好地方,你大可就事论事列举出来,我倒是会很认真的思考改进,不然,我就只能当你是喷子了啊 哥们😂。而且,你能说下什么是真正企业级的吗?我工作10多年,搞不清楚什么才是真正企业级的呢。。。

    你可以看下我写的这篇文章:公众号”小争哥“ 看看下面的留言:
    https://mp.weixin.qq.com/s/Od95pFonyLo7IlB3THa8Tw

     4
     5
  • 辣么大
    2020-01-22
    对于在ID generator中方法里写到
    void foo(){
        Random random = new Random();
    }
    有个疑问:

    1、为什么不声明成静态变量?
    2、能用成员变量么?而不是写成局部变量
    展开

    作者回复: 也可以,不过尽量的缩小变量的作用域,代码可读性也好,毕竟random只会用在某个函数中,而不是用在多个函数中,放到局部函数中,也符合封装的特性,不暴露太多细节。

    
     3
  • Ken张云忠
    2020-01-22
    读小争哥的注释就是种欣赏,小争哥的英文表达是怎么一步步积累的?
    我认为动词和介词是英文的精髓,还有英文的语法

    作者回复: 我英语也不好,多花点心思优化一下,实在不行,写中文注释也是可以的

    
     2
  • evolution
    2020-01-22
    代码的演变过程,真的是干货满满。不知道争哥有没有架构方面的演变课程?

    作者回复: 感谢认可,暂时没有呢

     1
     2
  • 牛顿的烈焰激光剑
    2020-01-25
    老师,对于获取 hostname(getLastfieldOfHostName()),我的想法是用 static 代码块,只在类加载的时候执行一次。请问这样处理的话会不会有什么坏处?

    作者回复: 有可能hostname会改变,你的代码就获取不到最新的hostname

     1
     1
  • 全时N多只
    2020-01-22
    34行代码是不是写错了?
    Assert.assertTrue(('0' < c && c > '9') || ('a' < c && c > 'z') || ('A' < c && c < 'Z'));

    作者回复: 好像没有吧

     3
     1
  • Ken张云忠
    2020-01-22
    小争个,我有个问题:
    接口LogTraceIdGenerator 继承 IdGenerator,RandomIdGenerator实现IdGenerator,但是在使用时却是LogTraceIdGenerator logTraceIdGenerator = new RandomIdGenerator();
    这里是需要类型强转的,另外这里强转在运行时是会失败的,因为RandomIdGenerator与LogTraceIdGenerator在类型上没有继承和实现关系.
    这里该怎么理解?
    展开

    作者回复: 代码有点问题,我更新一下,抱歉~~

     3
     1
  • Monday
    2020-02-11
    异常不是被“吐掉”了吧,是被 “吞掉”了吧
    
    
  • Dimple
    2020-02-11
    年后回来复工了,在家学习动力不足,赶紧在公司也抠出时间来学习。实战篇的思想是我要学习的地方,对我来说,往后针对项目需求的规划会更好。

    
    
  • 慕容引刀
    2020-02-09
    个人觉得小争哥的文章还是很给力的,前边的铺垫很多是在讲解代码中可能出现的问题以及如何发现问题。一般来说在清楚代码中存在哪些的问题的情况下就会去寻找解决方案,很容易发现一些设计模式就是为了解决某些问题而存在的。同时因为清楚问题所在,就很容易了解掌握这些设计模式。
    
    
  • 荀麒睿
    2020-02-09
    对于问题一,我觉得是否往上继续抛出得看情况,如果异常的时候比方说null的时候,也要有一个固定返回值例如直接返回字符串"null",那就不用往上抛而是在函数里面直接返回,我觉得更加好。对于问题二,我觉得如果函数内的逻辑会经常出现变化了化,可以替换成getLastSubstrByDelimiter,不会经常变化了化应该不用改。
    过年各种事情在学习上有点懈怠了,之前的文章也没来得及多多复习,落下了满多,得抓紧补补了,同时也不能忘了前面的复习,温故而知新嘛
    
    
  • DullBird
    2020-02-09
    1. hostname不能影响业务逻辑,设置默认值,并且还有随机值可以区分。
    2. 通用的比较合适,但是看有没有复用这个代码的必要,否则暂时不需要改动
    
    
  • 胡子高兴了
    2020-02-08
    Assert.assertTrue(('0' < c && c > '9') || ('a' < c && c > 'z') || ('A' < c && c < 'Z'));
    应该改成Assert.assertTrue(('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'));
    
    
  • 李小四
    2020-02-07
    设计模式_35
    # 作业
      1. 首先逻辑要自洽:
        (1) 如果在函数内吞掉异常,那么函数内要处理因为异常而导致的逻辑问题,而不是只返回一个空字符串。
        (2) 如果不准备处理异常带来的逻辑问题,那么需要把异常抛到上一层。
        具体的平衡的尺度,估下一下节会讲吧。
      2. 我认为合理,因为前一种方法预设了一些隐藏联系(host的delimiter一定是dot),当然这个改变的可能性不大,但是不预设多余得了联系是更好的办法。

    # 感想
    看到 ```RandomIdGenerator implements IdGenerator```, 我还以为发现了我不知道的新大陆,找IDE试了一下,才发现写错了。
    展开
    
    
  • 沈康
    2020-02-05
    1、不抛出异常吧,理由是抛出的异常需要调用出处理,这种id生成器明显需要自己处理干净否则异常处理将会暴露在各业务代码,明显增大了业务复杂度。
    2、dot就是".",改成delimiter有什么区别,已经封装了,改不改区别不大吧。。不懂
    
    
  • 斐波那契
    2020-02-03
    对于课堂讨论第一个问题:个人比较认同的是应该不往外抛,但是相应的逻辑要处理好。为什么这么说,首先,如果说hostname获取异常往外抛的话让使用者知道虽然这么做能很快定位到问题,但是从使用者角度说使用者并不会关心这个问题(这个底下也有人讲到) 其次 从逻辑上,往上抛异常跟打日志效果是一样的 既然打了日志那我们就应该可以知道有hostname获取异常的情况(不然日志一文不值) 只是异常抛出更简单粗暴一点。其实 这个问题主要是小争哥给我们限定了范围,如果小争哥用的不是id生成器这个案例 可能抛出异常更好一点。在id 生成器中 获取hostname只是获取随机id的一种手段,并不是唯一。如果某一天把获取hostname换成别的实现逻辑(例如用一个常量来代替) 那原本写好的往外抛出异常就变得毫无意义。
    
    
我们在线,来聊聊吧