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 )原则的更多相关文章
- DRY
DRY(Don't Repeat Yourself )原则 凡是写过一些代码的程序猿都能够意识到应该避免重复的代码和逻辑.我们通过提取方法,提取抽象类等等措施来达到这一目的.我们总能时不时的听到类 ...
- PHP精选数组函数
编程怎么能少的了数组呢,以下是学习PHP时常用的数组处理函数.在编程中要遵循一个原则就是DRY(Don`t Repeat Yourself)原则,PHP中有大量的函数,都记住这些函数不太现实,但常用的 ...
- Django 1.10 中文文档------3.2.2 查询操作making queries
3.2.2 查询操作 6.15章节包含所有模型相关的API解释. 后面的内容基于如下的一个博客应用模型: from django.db import models class Blog(models. ...
- 关于JavaScripting API您不知道的5件事
现在,许多 Java 开发人员都喜欢在 Java 平台中使用脚本语言,但是使用编译到 Java 字节码中的动态语言有时是不可行的.在某些情况中,直接编写一个 Java 应用程序的脚本 部分 或者在一个 ...
- Instagram的技术架构
http://blogread.cn/it/article/5497 Instagram 被 Facebook 以10亿美金收购.团队规模:13 人.而在被Facebook收购前的一个月,整个团队才7 ...
- 查询操作 -- Django从入门到精通系列教程
该系列教程系个人原创,并完整发布在个人官网刘江的博客和教程 所有转载本文者,需在顶部显著位置注明原作者及www.liujiangblog.com官网地址. Python及Django学习QQ群:453 ...
- 《InsideUE4》UObject(六)类型系统代码生成重构-UE4CodeGen_Private
读的不如写的快 引言 在之前的<InsideUE4>UObject(四)类型系统代码生成和<InsideUE4>UObject(五)类型系统收集章节里,我们介绍了UE4是如何根 ...
- 你不知道的JavaScript--Item17 循环与prototype最后的几点小tips
1.优先使用数组而不是Object类型来表示有顺序的集合 ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序. 但是在使用for..in循环对Object中的 ...
- Django:安装和启动
最近在学习利用python语言进行web站点开发,使用的框架是Django.这篇博客主要介绍Django的安装和简单使用. 一.Django介绍 Django是一个开源的Web应用框架,由Python ...
随机推荐
- Win10 UI入门RelativePanel(2)
自适应 1) Gif: 添加动画 2)
- mysql导出excel文件的几种方法
方法一 用mysql的命令和shell select * into outfile './bestlovesky.xls' from bestlovesky where 1 order by id d ...
- Java 之 数据库
1.SQL--结构化查询语言 a.分类:①DDL--数据定义语言 ②DQL--数据查询语言 ③DML--数据操作语言 ④DCL--数据控制语言 b.DDL:包括对数据库的创建.使用.删除,对表的创建. ...
- SSH框架整合(全注解)
全部jar包 目录结构 配置案例 package cn.yzu.Tbook.action; import javax.annotation.Resource; import org.apach ...
- NXP恩智浦P89V51RB2/RC2/RD2单片机解密芯片破解方法!
NXP恩智浦P89V51RB2/RC2/RD2单片机解密芯片破解 P89V51RB2/RC2/RD2是一款80C51微控制器,包含16/32/64kB Flash和1024字节的数据RAM. P89V ...
- hdu3534 树的直径变形
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3534 题意:n 之后 n-1条边,l,r,w:求出树上的最长路径以及最长路径的条数. // ...
- Unity3D 脚本编译器无法关联VisualStudio2012解决办法
开发环境:Win8 + Unity 4.34f1 +Visual Studio2012 旗舰版 解决办法: 1.创建一个start.bat文件,内容为:[start "" %* ...
- 网站开发网页广告条不显示,出现ERR_BLOCKED_BY_CLIENT
原因: 原因很简单,是因为被360浏览器的ad block给屏蔽掉了. 现象: 解决方案: 更换图片文件名,去掉ad,改成其他的字符.
- html设置透明度
在html中,设置元素的透明度 在css相应元素中添加下面两行代码即可. filter:alpha(opacity=50); /*仅在ie中支持*/ opacity:0.5; /*不支持ie*/ op ...
- 【BZOJ】4245: [ONTAK2015]OR-XOR
题意 给定一个长度为\(n(1 \le n \le 500000)\)的序列\(a_i(0 \le a_i \le 10^{18})\),将它划分为\(m(1 \le m \le n)\)段连续的区间 ...