• 辣么大
    2019-12-20
    1、注释或者文档违反DRY
    2、数据对象违反DRY

    对于1,例如一个方法。写了好多的注释解释代码的执行逻辑,后续修改的这个方法的时候可能,忘记修改注释,造成对代码理解的困难。实际应用应该使用KISS原则,将方法写的见名知意,尽量容易阅读。注释不必过多。

    对于2、例如类
    class User
      String id
      Date registerDate
      int age
      int registedDays
    其中 age可以由身份证号码算出来,而且每年都会递增。注册会员多少天了,也可以算出来。所以是不是可以考虑,数据只存储id和注册时间。其余两个字段可以算出来。

    补充:
    DRY不是只代码重复,而是“知识”的重复,意思是指业务逻辑。例如由于沟通不足,两个程序员用两种不同的方法实现同样功能的校验。
    DRY is about the duplication of knowledge, of intent. It’s about expressing the same thing in two different places, possibly in two totally different ways.

    当代码的某些地方必须更改时,你是否发现自己在多个位置以多种不同格式进行了更改? 你是否需要更改代码和文档,或更改包含其的数据库架构和结构,或者…? 如果是这样,则您的代码不是DRY。

    when some single facet of the code has to change, do you find yourself making that change in multiple places, and in multiple different formats? Do you have to change code and documentation, or a database schema and a structure that holds it, or…? If so, your code isn’t DRY.

    参考:
    The Pragmatic Programmer: your journey to mastery, 20th Anniversary Edition (2nd Edition)
    展开
     6
     41
  • 岁月
    2019-12-20
    加油啊感觉更新太慢了一个下午就看完了..,一个星期至少更新10课吧.
     7
     18
  • 啦啦啦
    2019-12-20
    产品经理有时候设计产品功能的时候也会重复
    
     9
  • magict4
    2019-12-20
    > 重复执行最明显的一个地方,就是在 login() 函数中,email 的校验逻辑被执行了两次。一次是在调用 checkIfUserExisted() 函数的时候,另一次是调用 getUserByEmail() 函数的时候。这个问题解决起来比较简单,我们只需要将校验逻辑从 UserRepo 中移除,统一放到 UserService 中就可以了。

    这样处理会有一个问题:如果别的 xxxService 也需要用到 UserRepo,而且没有对 email 跟 password 进行校验,直接调用了 UserRepo.checkIfUserExisted() ,会产生异常。

    一种方法是约定,所有关于 User 的操作都只能通过 UserService 进行,不能直接调用 UserRepo。

    另一种方法是“强制” xxxService 进行校验。我们可以把 UserRepo.checkIfUserExisted 的方法签名改成

    UserRepo.checkIfUserExisted(Email email, Password password)

    并且把 validation 的逻辑封装在 Email 跟 Password 类的构造函数中。这样 xxxService 必须先把 email 跟 password 从 String 类型转成对应的 Email/Password 类,才能调用 UserRepo,validation 的逻辑会在转换中被强制执行。
    展开
    
     6
  • 李小四
    2019-12-20
    设计模式_20

    # 作业:
    想到的只有文档和注释的重复了,比如两个不同功能的文档,同时描写一个细节时,可能“负责”的产品经理会各自清清楚楚地写一遍。然后:
    - 看的人就会懵,(描述相同时)写了两个地方,看一下是不是还有别的地方有描述;(描述不同时),应该以哪个为准。
    - 改的人也会懵,很容易忘记修改更新,更何况文档不更新程序又不会报错。。。


    #感想:
    回到“少干活 和 少犯错”的宗旨,重复的代码不仅写的时候会多些一遍,改的时候也要多看很多地方,多想很多差异性,多改很多地方,这样就违背了“少干活”;改的时候,容易忘记一些地方,维护多种逻辑实现的同一个逻辑,也容易疏忽而出错,这样就违背了“少出错”。

    说句题外话,文中提到“Rule of Three”时,原来外国人也用“三”表示多个,而且表示的还是2个。。。
    展开
    
     3
  • 岁月
    2019-12-23
    看完最后这个Rlue of three , 我感觉把可扩展填进去也是有道理的, 一开始不一定写得出扩展性很好的代码, 所以可以先简单来, 后面需求明确了再慢慢重构把代码变得更加可以扩展?
    
     2
  • blacknhole
    2019-12-20
    1,提个小问题:

    “实现逻辑重复”一节的代码是不是有点问题啊?

    if (!(c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.') {}似乎应该改为if (!((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.')) {}。

    2,说个小体会:

    “可复用性、可扩展性、可维护性……”与“复用性、扩展性、维护性……”,加不加“可”,其实没有本质差别。我以为,在通常的语境中(或者几乎任何情况下),两者都是可以通用的。

    比如,可复用性高,说明能够复用,与当前是否已经复用无关。复用性高,是指当前已经大量复用,说明在这之前可复用性高。已经大量复用时,依然可以更多地复用,也即:复用性高,意味着可复用性依然高。

    通常的语境中,也即通常提到“复用性”时,人们几乎只关注能不能复用,而不是已经复用了多少。所以,可以认为,可复用性高等同于复用性高。
    展开

    作者回复: 嗯嗯 确实有点问题 已经安排在改了

     2
     2
  • 黄林晴
    2019-12-20
    “Rule of Three”中的“Three”并不是真的就指确切的“三”,这里就是指“二”。😂
    这句话看了好几遍

    作者回复: 😂

     5
     2
  • 花颜
    2019-12-30
    老师,我有个问题,在大型多人协作项目当中,类、功能都是分散给不同的人开发的,不同的开发者质量良莠不齐,而实现逻辑重复有代码重复率校验工具可以做检测,而功能语义重复和代码执行重复其实不是那么容易能够发现,即使通过有效的codeReview,有没有什么工具可以辅助我们查找功能语义重复和代码执行重复这两类重复,以及在大型团队项目下,如何应用这些原则呢?毕竟靠自觉总是很难的

    作者回复: 好像只能靠人本身 工具很难去断定是否符合某一设计原则

    
     1
  • AaronChun
    2019-12-24
    数据库转换对象beanDb和数据展现beanVo,从属性定义上来看可能存在大量重复,但从业务或系统分层来看,却是职责明确,功能单一的对象,所以这并不违反DRY原则。相反如果将两者共性部分抽离提取,后期倘若业务变更,修改就会牵扯到前台和后台,不符合单一职责和接口隔离原则。
    
     1
  • 哈喽沃德
    2019-12-20
    啥时能出设计模式的教程,我的大刀早已饥渴难耐了
     1
     1
  • DullBird
    2019-12-20
    课堂讨论没有想到其他的了。
    理解一下DRY,总结就是抽取统一“逻辑”,还有相似逻辑的简化统一,
    为的就是同一“逻辑”,维护一块地方就行了。
    
     1
  • plain
    2019-12-20
    设计每个模块、类、函数,都要像设计外部api一样去思考,隐藏可变的细节、暴露不变的接口。
    
     1
  • 墨雨
    2019-12-20
    整体来说我们要做的是不写"重复"代码,同时考虑代码的复用性,但要避免过度设计。
    这几点说起来简单其实做起来还是有些难度的,在平常写代码的时候需要多思考,写完之后要反复审视自己的代码看看有没有可以优化的地方。说起来我感觉我还算是对代码有些追求的……但是真的需求来了为了赶需求基本就一遍过了……😂,对于一些脚本代码更是过程编程,惭愧啊
     2
     1
  • 小晏子
    2019-12-20
    老师概括的很全面了,提一个看看,
    数据定义重复,比如数据库里定义了两个schema几乎相同的数据表,然后数据表映射到代码里的结构体或xml也几乎相同,没有把公共部分剥离。
    
     1
  • 张文浩@有赞
    2020-02-09
    在开发新项目时,需要建新表,然后每次都需要在工程里,对新加的Repository增加add、select、update方法,逻辑大都差不多,这个感觉也是一个重复,有什么好的方法可以解决这类重复吗?
    
    
  • 杨成龙
    2020-01-29
    老师,咨询一个场景问题。
    问题描述:我经常在写代码的时候碰到这样的场景,在service类有多个方法,做同样的状态校验,然后我就把状态校验抽取成了一个公共方法放在本service类里,但是后来发现其他的service类也有这样的校验,我就想把这个校验方法抽出去,但是又觉得这个代码无处安放。。。
    困惑:1、如果在这些service类之外,独立一个类出来的话,又不知道如何命名这个类,也不知道这个类应该放在哪个包里?
    2、还是说把这个校验方法放到对应的业务bo或者domain里呢?

    这种场景老师建议如何处理呢?
    展开
    
    
  • helloworld
    2020-01-15
    2. 给我印象深刻的一点:『实现逻辑重复,但功能语义不重复的代码,并不违反 DRY 原则』。主要考虑的是如果将这些代码合并后,在将来如果各自的业务逻辑修改时,代码不够灵活
    3. 在写代码的过程中不要刻意地去做代码的复用性设计,当遇到代码复用的问题时再进行代码复用性的设计
    
    
  • evalcony
    2020-01-08
    DRY,我的理解是,让代码在哪个角度(维度)上进行解耦/独立/正交。
    使代码“积木化”。
    
    
  • 柴柴777
    2020-01-06
    我 之前就有个问题就说 我们如果用了组件化 每个模块算是单独的 尽管可能会写一个单独的util模块但是 还是存在着 重复代码,但是这些重复代码不在一个module里,那这样的到底算不算重复呢,,这些简单的部分的少量的重复不值得去单独加一个module

    作者回复: 有点重复是问题不大的,开发软件本身就没有绝对的对与错,也不是非黑即白,怎么合适怎么来,怎么舒服怎么来,不行就再重构。

    
    
我们在线,来聊聊吧