DRY(Don't Repeat Yourself )原则

凡是写过一些代码的程序猿都能够意识到应该避免重复的代码和逻辑。我们通过提取方法,提取抽象类等等措施来达到这一目的。我们总能时不时的听到类似这样的话:”把这些公用的类放到shared项目去,别的项目还要使用。。。“,什么算是公用(重复)的代码?是不是公用(重复)的代码就要放到一个叫shared的地方?

为什么说重复的代码和逻辑会带来问题呢?

你从一个类中复制了一段代码到另一个类中,但是这段代码足够的稳定,百年不变,这样的重复会带来问题吗?

也许不会。

如果这段代码需要时不时的修改,那么你就要花时间去修改所有包含这段逻辑的代码,这样无形中增加了维护成本和发生bug的几率。这时候就要着手消除和抽取重复的代码。

对于消除重复的代码有一个三次法则(rule of three):

1.第一次先写了一段代码。

2.第二次在另一个地方写了一段相同的代码,你已经有消除和提取重复代码的冲动了。

3.再次在另一个地方写了同样的代码,你已忍无可忍,现在可以考虑提取和消除重复代码了。

这一法则也适应于对重构时机的把握,过早的重构可能会引入新的问题,三次法则给了你一个重构依据。当然,随着你经验的增长,你可能在第二阶段已经能非常有信心的预料到问题所在。

什么样的代码算是重复的?

DRY is about Knowledge一文中给了这样一个实例:

<?php // example 1
final class Basket
{
    private $products;

    public function addProduct($product)
    {
        if (3 == count($this->products)) {
            throw new Exception("Max 3 products allowed");
        }
        $this->products[] = $product;
    }
}

final class Shipment
{
    private $products;

    public function addProduct($product)
    {
        if (3 == count($this->products)) {
            throw new Exception("Max 3 products allowed");
        }
        $this->products[] = $product;
    }
}

这两段代码中都有一个相同的方法addProduct,这两段代码算是重复的吗?他们违反DRY原则吗?

作为一个领域驱动的实践者,我们可以从业务的角度来分析这一代码,第一段代码似乎是一个用户在购物,但是我们最多允许用户购买三件商品。在第二段代码的场景中,我们想要给所有用户提供相同的机会并限制用户最大购买数量。

这一分析说明了这两段代码所描述的领域(Domain)、业务(Business)、知识(Knowledge)、边界(Boundary)、职责(Resposibility)不同,这两段代码之所以相同完全属于巧合。对这样的代码进行提取和消除重复是错误的。

我之前待的team维护了一个北美的项目,如果让我指出这一项目最大的设计问题,就是将一些本不应该提取的代码(各种Model、数据访问)抽取到了一个叫做Shared的工程中,这一举动导致开发人员在后期不敢再修改Shared工程中的任何代码,以至于开发人员宁可重新添加一个方法也不敢修改之前的代码。

DRY看似初级人员都要掌握的能力,如果使用不当会造成非常严重的后果,正是因为我维护了这样的项目才有感而发,希望大家引以为戒,当然大家若是有不同的看法可以一起讨论。

DRY(Don't Repeat Yourself )原则

时间: 2024-10-05 06:05:28

DRY(Don't Repeat Yourself )原则的相关文章

DRY

DRY(Don't Repeat Yourself )原则 凡是写过一些代码的程序猿都能够意识到应该避免重复的代码和逻辑.我们通过提取方法,提取抽象类等等措施来达到这一目的.我们总能时不时的听到类似这样的话:”把这些公用的类放到shared项目去,别的项目还要使用...“,什么算是公用(重复)的代码?是不是公用(重复)的代码就要放到一个叫shared的地方? 为什么说重复的代码和逻辑会带来问题呢? 你从一个类中复制了一段代码到另一个类中,但是这段代码足够的稳定,百年不变,这样的重复会带来问题吗?

程序集

什么是程序集? ---程序集是.net中的概念. ---.net中的dll与exe文件都是程序集.(exe与dll的区别?) ---程序集(Assembly).可以看做是一堆相关类打一个包,相当于Java中的jar包(*). 使用程序集的好处? --程序中只引用必须的程序集,减少程序的尺寸. ---程序集可以疯转一些代码,只提供必要的访问接口. 如何添加程序集的引用? ---添加路径.项目引用.GAC(全局程序集缓存) ---不能循环添加引用 (我们调用的类都是位于各个程序集中,如果调用的类没在

MDU某产品OMCI模块代码质量现状分析

说明 本文参考MDU系列某产品OMCI模块现有代码,提取若干实例以说明目前的代码质量. 本文旨在就事论事,而非否定前人(没有前人的努力也难有后人的进步).希望以史为鉴,不破不立,最终产出高质量的代码. 一  质量现状 不考虑业务实现,现有的OMCI模块代码质量不甚理想.无论是理解上手.修改扩展和测试排障,可以用举步维艰形容.尤其是二层通道计算相关代码,堪比令史前动物无法自拔的"焦油坑". 本节将不考虑流程设计,仅就函数粒度列举目前存在的较为突出的代码质量问题. 1.1 巨型函数 通过S

PHP精选数组函数

编程怎么能少的了数组呢,以下是学习PHP时常用的数组处理函数.在编程中要遵循一个原则就是DRY(Don`t Repeat Yourself)原则,PHP中有大量的函数,都记住这些函数不太现实,但常用的函数还是要熟练使用的,大部分的函数的使用方法可以通过查询PHP的手册来使用.在编程中查手册是少不了的,所以要会学着使用已有的东西,就如PHP中的数组处理函数已经有排序函数了,为什么还要在写东西是费着劲去写冒泡或者堆排或者快排呢. 编程是间接的过程,也是重用的过程,要写出好的代码是少不了设计模式来做支

进程锁

这里的进程锁与线程锁.互斥量.读写锁和自旋锁不同,它是通过记录一个PID文件,避免两个进程同时运行的文件锁.进程锁的作用之一就是可以协调进程的运行,例如crontab使用进程锁解决冲突提到,使用crontab限定每一分钟执行一个任务,但这个进程运行时间可能超过一分钟,如果不用进程锁解决冲突的话两个进程一起执行就会有问题.后面提到的项目实例Run也有类似的问题,通过进程锁可以解决进程间同步的问题.使用PID文件锁还有一个好处,方便进程向自己发停止或者重启信号.Nginx编译时可指定参数 --pid

20135119_涂文斌 实验三 敏捷开发与XP实践

北京电子科技学院(BESTI) 实  验  报  告 课程: Java        班级:1351           姓名:涂文斌          学号:20135119 成绩:               指导教师:娄嘉鹏    实验日期:2015.6.2 实验密级:         预习程度:             实验时间:15:30~18:00 仪器组次:         必修/选修:选修       实验序号:(三) 实验名称:敏捷开发与XP实践 实验目的: 1.XP基础 2.

Effective JavaScript Item 50 优先使用遍历方法而非循环

优先使用遍历方法而非循环 在使用循环的时候,很容易违反DRY(Don't Repeat Yourself)原则.这是因为我们通常会选择复制粘贴的方法来避免手写一段段的循环语句.但是这样做回让代码中出现大量重复代码,开发人员也在没有意义地"重复造轮子".更重要的是,在复制粘贴的时候很容易忽视循环中的那些细节,比如起始索引值,终止判断条件等. 比如以下的for循环就存在这个问题,假设n是集合对象的长度: for (var i = 0; i <= n; i++) { ... } //

django1.8.2-django框架整体的简单了解

django简介 Django是一个由Python写成的开放源代码的Web应用框架.它最初是被开发来用于管 理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是CMS(内容管理系统)软件.并于2005年7月在BSD许可证下发布.这套框架是以比利时的吉 普赛爵士吉他手Django Reinhardt来命名的. 核心组件: 用于创建模型的对象关系映射 为最终用户设计的完美管理界面 一流的 URL 设计 设计者友好的模板语言 缓存系统. 采用MTV的设计思想 Django设计的初衷: 简便.快速的开

关于JavaScripting API您不知道的5件事

现在,许多 Java 开发人员都喜欢在 Java 平台中使用脚本语言,但是使用编译到 Java 字节码中的动态语言有时是不可行的.在某些情况中,直接编写一个 Java 应用程序的脚本 部分 或者在一个脚本中调用特定的 Java 对象是更快捷.更高效的方法. 这就是 javax.script 产生的原因了.Java Scripting API 是从 Java 6 开始引入的,它填补了便捷的小脚本语言和健壮的 Java 生态系统之间的鸿沟.通过使用 Java Scripting API,您就可以在您