Clean Code – Chapter 3: Functions
- Small- Blocks and Indenting- The blocks within - ifstatements,- elsestatements,- whilestatements, and so on should be one line long. Probably that line should be a function call.- Functions shouldn't be large enough to hold nested structures. The indent level of a function should not be greater than one or two. 
 
- Do One Thing- Functions should do one thing. They should do it well. They should do it only. - Describe a function as a brief TO paragraph to see, if a function does only those steps that are one level below the stated name of the function. - Sections within Functions- Functions that do one thing cannot be reasonably divided into sections. 
 
- One Level of Abstraction per Function- Reading Code from Top to Bottom: The Stepdown Rule
 
- Switch Statements- Make sure that each - switchstatement is buried in a low-level class and is never repeated. (Do this with polymorphism .)
- Use Descriptive Names- The smaller and more focused a function is, the easier it is to choose a descriptive name. - A long descriptive name is better than a long descriptive comment. - Be consistent in your names. 
- Function Arguments- The ideal number of arguments for a function is zero(niladic). - Arguments are hard. They take a lot of conceptual power. - Arguments are even harder from a testing point of view. - Output arguments are harder to understand than input arguments. - Common Monadic Forms- Ask a question about that argument: - boolean fileExists("myFile").- Operate on that argument, transform it into something else and return it: - InputStream fileOpen("myFile").- (less common)Interpret the function call as an event and use the argument to alter the state of the system: - void passwordAttemptFailedNtimes(int attempts).
- Flag Arguments- Passing a boolean into a function is a truly terrible practice. It proclaims that this function does more than one thing. 
- Dyadic Functions- Ordered components of a single value: - Point(x, y).
- Argument Objects- When a function seems to need more than two or three arguments, it is likely that some of those arguments ought to be wrapped into a class of their own. 
- Argument Lists- If the variable arguments are all treated identically, then they are equivalent to a single argument of type - List.
- Verbs and Keywords- In the case of a monad, the function and argument should form a very nice verb/noun pair: - write(name).- Encode the names of the arguments into the function name: - assertExpectedEqualsActual(expected, actual).
 
- Have No Side Effects- Avoid temporal couplings and order dependencies. - Output Arguments- If function must change the state of something, have it change the state of its owning object: - public void appendFooter(StringBuffer report)==>- report.appendFooter.
 
- Command Query Separation- Functions should either do something or answer something, but not both. Either your function should change the state of an object, or it should return some information about that object. - e.g. - Bad code: - public boolean set(String attribute, String value)... 
 ...
 if(set("username", "unclebob"))...- Good code: - if(attributeExists("username")){
 setAttribute("username", "unclebob");
 }
- Prefer Exceptions to Returning Error Codes- Extract Try/Catch Blocks- Extract the bodies of the - tryand- catchblocks out into functions of their own.
- Error Handing Is One Thing- A function that handles errors should do nothing else. 
- The Error.java Dependency Magnet- Use exceptions rather than error codes, then new exceptions are derivatives of the exception class. They can be added without forcing any recompilation or redeployment. 
 
- Don't Repeat Yourself- Duplication may be the root of all evil in software. 
- Structured Programming- Every function, and every block within a function, should have one entry and one exist. Following these rules means that there should only be one - returnstatement in a function, no- breakor- continuestatements in a loop, and never, ever, any- gotostatements. (used in larger functions)
Writing software is like any other kind of writting. Get your thoughts down first, then massage it until it reads well.
附上本章最后的一个类文件的源代码,读起来真的犹如一篇优美的文章。
// Clean Code
// Listing 3-7
// SetupTeardownIncluder.java package fitnesse.html; import fitnesse.responders.run.SuiteResponder;
import fitnesse.wiki.*; public class SetupTeardownIncluder {
private PageData pageData;
private boolean isSuite;
private WikiPage testPage;
private StringBuffer newPageContent;
private PageCrawler pageCrawler; public static String render(PageData pageData) throws Exception {
return render(pageData, false);
} public static String render(PageData pageData, boolean isSuite)
throws Exception {
return new SetupTeardownIncluder(pageData).render(isSuite);
} private SetupTeardownIncluder(PageData pageData) {
this.pageData = pageData;
testPage = pageData.getWikiPage();
pageCrawler = testPage.getPageCrawler();
newPageContent = new StringBuffer();
} private String render(boolean isSuite) throws Exception {
this.isSuite = isSuite;
if (isTestPage())
includeSetupAndTeardownPages();
return pageData.getHtml();
} private boolean isTestPage() throws Exception {
return pageData.hasAttribute("Test");
} private void includeSetupAndTeardownPages() throws Exception {
includeSetupPages();
includePageContent();
includeTeardownPages();
updatePageContent();
} private void includeSetupPages() throws Exception {
if (isSuite)
includeSuiteSetupPage();
includeSetupPage();
} private void includeSuiteSetupPage() throws Exception {
include(SuiteResponder.SUITE_SETUP_NAME, "-setup");
} private void includeSetupPage() throws Exception {
include("SetUp", "-setup");
} private void includePageContent() throws Exception {
newPageContent.append(pageData.getContent());
} private void includeTeardownPages() throws Exception {
includeTeardownPage();
if (isSuite)
includeSuiteTeardownPage();
} private void includeTeardownPage() throws Exception {
include("TearDown", "-teardown");
} private void includeSuiteTeardownPage() throws Exception {
include(SuiteResponder.SUITE_TEARDOWN_NAME, "-teardown");
} private void updatePageContent() throws Exception {
pageData.setContent(newPageContent.toString());
} private void include(String pageName, String arg) throws Exception {
WikiPage inheritedPage = findInheritedPage(pageName);
if (inheritedPage != null) {
String pagePathName = getPathNameForPage(inheritedPage);
buildIncludeDirective(pagePathName, arg);
}
} private WikiPage findInheritedPage(String pageName) throws Exception {
return PageCrawlerImpl.getInheritedPage(pageName, testPage);
} private String getPathNameForPage(WikiPage page) throws Exception {
WikiPagePath pagePath = pageCrawler.getFullPath(page);
return PathParser.render(pagePath);
} private void buildIncludeDirective(String pagePathName, String arg) {
newPageContent
.append("\n!include ")
.append(arg)
.append(" .")
.append(pagePathName)
.append("\n");
}
}
Clean Code – Chapter 3: Functions的更多相关文章
- Clean Code – Chapter 4: Comments
		“Don’t comment bad code—rewrite it.”——Brian W.Kernighan and P.J.Plaugher The proper use of comments ... 
- Clean Code–Chapter 7 Error Handling
		Error handling is important, but if it obscures logic, it's wrong. Use Exceptions Rather Than Return ... 
- Clean Code – Chapter 6 Objects and Data Structures
		Data Abstraction Hiding implementation Data/Object Anti-Symmetry Objects hide their data behind abst ... 
- Clean Code – Chapter 5 Formatting
		The Purpose of Formatting Code formatting is about communication, and communication is the professio ... 
- Clean Code – Chapter 2: Meaningful Names
		Use Intention-Revealing Names The name should tell you why it exists, what it does, and how it is us ... 
- “Clean Code” 读书笔记序
		最近开始研读 Robert C.Martin 的 “Clean Code”,为了巩固学习,会把每一章的笔记整理到博客中.而这篇博文作为一个索引和总结,会陆续加入各章的笔记链接,以及全部读完后的心得体会 ... 
- 《Clean Code》一书回顾
		<Clean Code>一书从翻开至今,已经差不多两个月的时间了,尽管刨去其中的假期,算下来实在是读得有点慢.阅读期间,断断续续的做了不少笔记.之前,每每在读完了一本技术书籍之后,其中的诸 ... 
- [转]Clean Code Principles: Be a Better Programmer
		原文:https://www.webcodegeeks.com/web-development/clean-code-principles-better-programmer/ ----------- ... 
- 代码整洁之道Clean Code笔记
		@ 目录 第 1 章 Clean Code 整洁代码(3星) ?为什么要整洁的代码 ?什么叫做整洁代码 第 2 章 Meaningful Names 有意义的命名(3星) 第 3 章 Function ... 
随机推荐
- Quartz Sheduler 入门
			Quartz Sheduler 入门 原文地址:http://www.quartz-scheduler.org/generated/2.2.2/html/qtz-all/ 下载地址:http://qu ... 
- SQL2008附加数据库提示错误:5120
			前几天在附加数据库时,出现了这个错误 在win7 x64系统上使用sql2008进行附加数据库(包括在x86系统正在使用的数据库文件,直接拷贝附加在X64系统中)时,提示无法打开文 ... 
- Collection和Collections的区别
			Collection 是集合类的上级接口,继承它的接口主要有set和list.Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索,排序,线程安全化等操作. 
- 《javascript高级程序设计》对象图
			1.原型链图 2.作用域链图 3.继承 
- 自适应网页设计(Responsive Web Design)(转)
			随着3G的普及,越来越多的人使用手机上网. 移动设备正超过桌面设备,成为访问互联网的最常见终端.于是,网页设计师不得不面对一个难题:如何才能在不同大小的设备上呈现同样的网页? 手机的屏幕比较小,宽度通 ... 
- java随机生成字符串并排序
			package com.Imooc; import java.util.ArrayList; import java.util.Collections; import java.util.List; ... 
- 年度十佳 DevOps 博客文章(前篇)
			如果说 15 年你还没有将 DevOps 真正应用起来,16 年再不实践也未免太落伍了.国内 ITOM 领军企业 OneAPM 工程师为您翻译整理了,2015 年十佳 DevOps 文章,究竟是不是深 ... 
- Android 共享文件的 Runtime 权限
			在开发 Android 应用时,总会涉及到获取打电话.地理位置.网络等敏感的用户信息的权限,在 Android 中,联系人.当前位置等这些敏感信息都是由 permissions 保护的,Android ... 
- 关于CPU亲和性的测试
			今天看到运维的同事在配置nginx的CPU亲和性时候,运维同事说他在所有的机器上都是按照8核的方式来配置worker进程的CPU亲和性的. 但我觉得就是有点不太对劲,就查了一下nginx的处理work ... 
- QML嵌入到QWidget中方法
			简介 嵌入方法有两种一种是直接拖控件,另一种是cpp代码动态生成, 控件方式 动态代码生成 QQuickWidget *m_quickWidget=new QQuickWidget(); QUrl s ... 
