原文

The Once and Only Once principle can be thought of as a subset of the Don’t Repeat Yourself principle, and is one of the most fundamental principles of software development.

Duplication of behavior is one of the most common sources of bugs in software systems, since it becomes increasingly likely that changes to behavior defined in one location may not be propagated to all locations where this behavior is defined.

Eliminating the duplication caused by not following the Once and Only Once principle is one of the primary reasons for refactoring and is also at the core of many design patterns.

原文2

One of the main goals (if not the main goal) when ReFactoringcode.

Each and every declaration of behavior should appear OnceAndOnlyOnce.

Conceptually analogous to normalization in the RelationalModel. See also DontRepeatYourself.

Code wants to be simple.

If you are aware of CodeSmells, and duplicate code is one of the strongest, and you react accordingly, your systems will get simpler.

When I began working in this style, I had to give up the idea that I had the perfect vision of the system to which the system had to conform.

Instead, I had to accept that I was only the vehicle for the system expressing its own desire for simplicity.

My vision could shape initial direction, and my attention to the desires of the code could affect how quickly and how well the system found its desired shape,

but the system is riding me much more than I am riding the system. -- KentBeck, feeling mystical, see MysticalProgramming

Beware of introducing unnecessary coupling (CouplingAndCohesion) when refactoring for OnceAndOnlyOnce.

Refactoring is the moving of units of functionality from one place to another in your program. Refactoring has as a primary objective getting each piece of functionality to exist in exactly one place in the software. -- RonJeffries

It's not OAOO, and this comment probably ought to be somewhere else, but doesn't refactoring also cover replacing one piece of code with another, simpler piece of code that has the same external "appearance" and function?

Yes - good point. Note Ron's subtle use of "a primary objective" instead of "the primary objective". I personally use two "first tier" refactoring rules - OnceAndOnlyOnce and SeparateTheWhatFromTheHow (my name - the common name is ComposedMethod)

OnceAndOnlyOnce is a profound concept, but difficult to apply. I've spent my entire professional life (25 years) learning how to apply it to programs. This page [many versions ago] ... was rewritten to make OnceAndOnlyOnce seem like a simple rule to apply, instead of a prime principle. OnceAndOnlyOnce is NOT easy! And it was wrong to refactor this page so that all hints of tension and disagreement are removed from it.

OnceAndOnlyOnce is not a pattern. A pattern is something you can teach someone to do in a fairly short amount of time. A day, usually. Perhaps a few weeks.

But learning how to refactor classes to form a TemplateMethod does not help you see how to use XML to represent your user interfaces (a recent OnceAndOnlyOnce technique applied to Squeak), or how to make a good virtual machine. These are patterns; OnceAndOnlyOnce is not a pattern. OnceAndOnlyOnce is a principle. -- RalphJohnson

Well said. OnceAndOnlyOnce is not just a simple rule, but one of the core goals of all software design. It's why functions were invented. Remember that your program could have been written as a single long function using only ifs, whiles, and try/catch blocks for flow control, and primitives for all the data. Consider what that would look like. For "hello world", it's the default.

I once saw Beck declare two patches of almost completely different code to be "duplication", change them so that they WERE duplication, and then remove the newly inserted duplication to come up with something obviously better. -- RonJeffries, from the XpMailingList

or, the long version...

I recall once seeing Beck look at two loops that were quite dissimilar: they had different for structures, and different contents, which is pretty much nothing duplicated except the word "for", and the fact that they were looping - differently - over the same collection.

He changed the second loop to loop the same way the first one did. This required changing the body of the loop to skip over the items toward the end of the collection, since the previous version only did the front of the collection.

Now the for statements were the same. "Well, gotta eliminate that duplication, he said, and moved the second body into the first loop and deleted the second loop entirely.

Now he had two kinds of similar processing going on in the one loop. He found some kind of duplication in there, extracted a method, did a couple of other things, and voila! the code was much better.

That first step - creating duplication - was startling. -- RonJeffries, from the XpMailingList

It isn't so startling. That technique is necessary for the more powerful space optimizations of program code: you reduce everything as much as possible, then you find two subgraphs that are similar, you add conditional nodes to them until they're identical (and inject the proper conditions), then you combine them. Repeat until the apparent gains aren't worth the resource cost to acquire them. Beck is just doing it by hand.

It is also frequently used to allow consistent idiomatic expressions to emerge. This allows bugs to be detected via inspection for all cases where the idiom was not followed properly. This is more than superficial coding standards. For example: a loop guard of < n or <=n will behave differently if n starts at 0 vs starting at 1. It is best to pick one idiom and stick with it. I suspect the duplication here was semantic in nature and culling it out allowed a reuse opportunity to emerge.

-- MarcGrundfest

It isn't so startling. That technique is necessary for the more powerful space optimizations of program code: you reduce everything as much as possible, then you find two subgraphs that are similar, you add conditional nodes to them until they're identical (and inject the proper conditions), then you combine them. Repeat until the apparent gains aren't worth the resource cost to acquire them. Beck is just doing it by hand.

It is also frequently used to allow consistent idiomatic expressions to emerge. This allows bugs to be detected via inspection for all cases where the idiom was not followed properly. This is more than superficial coding standards. For example: a loop guard of < n or <=n will behave differently if n starts at 0 vs starting at 1. It is best to pick one idiom and stick with it. I suspect the duplication here was semantic in nature and culling it out allowed a reuse opportunity to emerge.

-- MarcGrundfest

编码原则 之 Once and Only Once的更多相关文章

  1. S.O.L.I.D 是面向对象设计(OOD)和面向对象编程(OOP)中的几个重要编码原则

    注:以下图片均来自<如何向妻子解释OOD>译文链接:http://www.cnblogs.com/niyw/archive/2011/01/25/1940603.html      < ...

  2. 编码原则实例------c++程序设计原理与实践(进阶篇)

    编码原则: 一般原则 预处理原则 命名和布局原则 类原则 函数和表达式原则 硬实时原则 关键系统原则 (硬实时原则.关键系统原则仅用于硬实时和关键系统程序设计) (严格原则都用一个大写字母R及其编号标 ...

  3. Web前端安全之安全编码原则

    随着Web和移动应用等的快速发展,越来越多的Web安全问题逐渐显示出来.一个网站或一个移动应用,如果没有做好相关的安全防范工作,不仅会造成用户信息.服务器或数据库信息的泄露,更可能会造成用户财产的损失 ...

  4. Python写业务逻辑的几个编码原则

    作为一个写业务逻辑的boy,我需要专注的就是把业务逻辑写好.写业务逻辑并不复杂,就是把编程最基础的东西使用好,有变量.循环.流程控制.函数.数据库等. 但是写出的逻辑要通俗易懂.易于理解,避免炫技.晦 ...

  5. Web开发者不可不知的15条编码原则

    HTML已经走过了近20的发展历程.从HTML4到XHTML,再到最近十分火热的HTML5,它几乎见证了整个互联网的发展.但是,即便到现在,有很多基础的概念和原则依然需要开发者高度注意.下面,向大家介 ...

  6. zg项目 应用系统编码原则

    一.编码说明: 1.系统编码采用三码为原则,通常两码简称之. 1>.子系统或类型 2>.系统小分类 3>.系统大分类 如 IPMS领域业务群: DA 应用软件发展管理系统 DE公用副 ...

  7. Web 开发者不可不知的15条编码原则

    HTML 已经走过了近20的发展历程.从HTML4到XHTML,再到最近十分火热的HTML5,它几乎见证了整个互联网的发展.但是,即便到现在,有很多基础的概念和原则依然需要开发者高度注意.下面,向大家 ...

  8. 中文字符utf-8编码原则

    UTF-8是一种变长字节编码方式.对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0:如果是 多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字 ...

  9. 编码原则:必须使用的 TODO

    结构 // TODO:JS ParentId 不要使用硬编码. var parentId = record.get('ParentId'); var parentNode = me.getStore( ...

  10. dubbo作者讲编码原则

    刚看到梁飞谈到dubbo为保证代码质量开发人员必须要注意的,其实也是开发人员应该做的. 1. 防止空指针和下标越界 这是我最不喜欢看到的异常,尤其在核心框架中,我更愿看到信息详细的参数不合法异常, 这 ...

随机推荐

  1. js 自动类型转换

    js自动类型转换 1.==符号在判断左右两边数据是否相等时,如果数据类型一致,直接比较值即可 2.==符号左右数据类型不一致时,如果两方数据为布尔型.数值型.字符串型时,不为数字的那一方自动调用Num ...

  2. Python3学习之路~9.2 操作系统发展史介绍、进程与线程区别、线程语法、join、守护线程

    一 操作系统发展史介绍 参考链接:http://www.cnblogs.com/alex3714/articles/5230609.html 二 进程与线程 进程: 对各种资源管理的集合 就可以称为进 ...

  3. 2018-2019-2 网络对抗技术 20165236 Exp6 信息搜集与漏洞扫描

    2018-2019-2 网络对抗技术 20165236 Exp6 信息搜集与漏洞扫描 一.实验内容 1.实践目标 掌握信息搜集的最基础技能与常用工具的使用方法. 2.实践内容 (1)各种搜索技巧的应用 ...

  4. 2018-2019-2 20165236 《网络对抗技术》Exp4 恶意代码分析

    2018-2019-2 20165236 <网络对抗技术>Exp4 恶意代码分析 一.1.实践目标 1.1是监控你自己系统的运行状态,看有没有可疑的程序在运行; 1.2是分析一个恶意软件, ...

  5. C#返回JSON格式数据

    又类的属性生成json格式数据 using System; using System.Collections.Generic; using System.Linq; using System.Web; ...

  6. 【Vagrant】-NO.130.Vagrant.2 -【Error:the filesystem "vboxsf" is not available】

    Style:Mac Series:Java Since:2018-09-10 End:2018-09-10 Total Hours:1 Degree Of Diffculty:5 Degree Of ...

  7. 关于Android中使用BottomNavigationView切换横屏导致返回主页的问题

    问题: 如图,"发现"页即为主页,然后我们切换到"我"页,一切正常. 那么问题来了,如果切换到"我"页后把手机横屏,则会出现下面的情况. 嗯 ...

  8. kali在vbox上运行设置共享文件夹

    mount -t vboxsf VBoxShared /root/Desktop/vbox 0x00 使用共享文件夹的前提 需要自行安装增强功能:https://jingyan.baidu.com/a ...

  9. unittest报告出现dict() -> new empty dictionary错误解决办法

    unittest报告出现dict() -> new empty dictionary错误解决办法 说一下原因,这是由于unittest中采用了ddt驱动.  由于版本问题导致 问题如图: 解决办 ...

  10. 图表管理账单的NABCD

    首先,我们团队的项目目标是记账本.就我个人理解,记账本中心功能有两项,第一,记录:第二,显示.而本篇博客主要描述用各种不同的图表来显示的NABCD. 首先是N(need),用户的需求就是我们的动力!利 ...