OO之美4(好代码与坏代码)
前言:写代码不仅仅要做到能与机器交流,更要做到能和人交流
编码规范:编码规范就是最佳实践,是前辈在编码这件事上的积累和总结,是智慧的延续和工业的实践,如下:
⑴命名规范
⑵避免行数过多的方法
⑶代码缩进
⑷异常规范
⑸设计规范
⑹注释规范
⑺文件的组织规范
⑻配置规范
⑼发布与部署规范
⑽测试规范
⑾SQL规范
以上规范都有N条法规,没有规范的编码,一定是有问题,潜伏着坏代码的幽灵.
⑴命名规范
对于命名规则,通常可选择的体系主要有:
⒈Pascal Casing 混合使用大小写字母,每个单词的首字母必须是大写,例如 FirstName
⒉Camel Casing 混合使用大小写字母,第一个单词必须是小写,其他单词首字母则必须是大写,例如:firstName
⒊匈牙利命名法,通过属性,类型和对象描述混合来表示,例如frmMainWindows
不过,对于不同的语言体系而言,一般有着不同的命名规范和体系,很多不同的语言对于命名规范的选择也有差别.以c#为例,最基本的命名规则包括:
⒈以Pascal Casing 风格定义命名空间,类极其成员,接口,方法,事件,枚举等
⒉以Camel Casing 规范定义参数,私有成员
⒊避免适用匈牙利命名法
⒋以Atrribute作为特性的后缀
⒌以Delegate作为委托的后缀
⒍以Exception作为异常的后缀
代码的规范最主要来自于平时对于代码的理解和运用.
⑵多注释,少废话
代码是给人看的,而代码本身的逻辑又决定于方法,类型和依赖的关系之中,所以,必要的注释,是必需且必要的.通过注释的进一步解释,来辅助性地告知代码的逻辑,算法或者流程,不仅仅是好习惯,更是好代码.另一方面,注释不是无病呻吟,没有必要要表述那些显而易见的逻辑或者说明,同时注意区分单行注释和多行注释的应用.
在.NET中,XML格式的注释还肩负了另一项重要使命,那就是根据注释生成代码文档.在VS中,可以通过Properities-->Build来设置"XML documentation files"选项输出生成XML信息.
通过SandCastle工具就可以基于上述信息生成标准统一的文档信息,基于此方式就可以建立类似于MSDN文档的项目帮助文件,大大简化了这项"复杂"的工作.
⑶用命名空间组织你的代码
命名空间,是逻辑上的组织单元,通过命名空间建立对代码的有机组织,是现代语言的一大"创举",<>作者蔡学镛说:一个语言是否适合大型开发,可以从它对模块,命名空间(或类似概念)支持的方向看的出来.从这个意义上说,命名空间并不是大型开发或者团队开发最重要的概念.但却是加分的必要因素.关于命名空间,可以多关注一下 using
⑷切勿模式而模式
设计模式是好的,而模式滥用是不好的.了解和熟悉设计模式,是需要实践和思考的过程,模式并不是一切问题的灵丹妙药,而且大多时候的滥用反而造成更多的问题.滥用模式体现在两个方面:
①不慎误用,在不适合的场合应用不适合的模式,例如不是所有场合都需要引入工厂解耦对象创建;对于依赖于执行状态的场合,并非只有状态模式一种选择,工作流或许能带来更好的控制
②过度应用,模式的引入都会或多或少地介入了中间层或者中间代码,过度的模式应用将导致代码复杂度的直线上升,除了会带来性能上的问题还有逻辑上的混乱.
⑸线性安全很重要
线性安全是重要的,在数据共享或同步的场合应将线程安全作为必须考虑的因素,不安全的代码将在多线程运行造成严重的问题.例如,单例模式就是这样一个特别需要注意的例子:
public sealed class Singleton
{
Singleton();//构造函数私有化
public static Singleton Instance()
{
get
{
if(instance==null)
{
instance=new Singleton();
}
return instance;
}
private static Singleton instance=null;
}
因此,你可以通过考虑"双锁"机制来保证线程的安全,不过在.NET平台还可以有更简单的实现方式:
public sealed class Singleton
{
static Singleton(){}
Singleton(){}
public static Singleton Instance()
{
get
{
return instance;
}
}
static readonly Singleton instance=new Singleton();
}
}
以上是利用了静态构造函数只能被执行一次且在运行库加载类成员时的特点,保证了Instance的线性安全,避免了不必要的锁检查开销.关于静态构造函数,还需要多研读研读.线程安全是个大课题,需要仔细咀嚼.
⑹不断重复思考
软开发就像爬山,而有意思的事情在于,我们爬的并不是一座山,而是一座又一座的山,似乎永无尽头.所以爬山的过程其实是这样,爬了一座,又从这座下来,接着爬上另一座,并且继续如此反复,才能达到最高的巅峰.
不断的思考,应该勇于尝试代码重构,这样才会不断完善和进步.而重构在<>一书中有详细的讨论:
⑴以单元测试驱动
⑵提取类,方法,接口或者子类等
⑶重新组织数据
⑷简化函数调用
⑸借助重构工具
⑺扩展无处不在
扩展性是衡量一个软件产品的重要尺度之一.通过合适的设计为软件系统赋予一定程度的扩展,是架构师着手设计的重要考虑因素.
架构的考量:功能性,安全性,易用性,扩展性,高效性,可靠性
在语言层,考量扩展性的指标遍布于.NET语言特性的各个细节:
①基于类的继承,组合和多态
②面向接口和抽象类
③基于委托和事件回调.回调是一种扩展良好的实现机制,提供动态扩展性的表现,使得框架能够以委托来调用用户代码
private void btnLogin_Click(object sender ,RoutedEventArgs e)
{
MessageBox.Show("Hello,Windows Phone.");
}
就像给框架提供了一个"钩子"来动态地将用户代码扩展到框架的逻辑,在单击按钮的时候,执行用户代码的流程逻辑,并将这个流程注入到框架行为中.在.NET中,可以通过委托实现线程的安全回调,而事件正是这种模式的最佳实践,具体的请关注委托,匿名,Labmda表达式.
④以部分类延伸组织,在很多情况下,为了便于组织和物理上的方便,将一个类分布在多个独立的文件,是一种合适的处理方式;另一方面,对于越来越多的自动生成代码,部分类提供了"手动"扩展支持.例如,LINQ TO SQL作为数据访问层架构时,通常可以通过Visual Studio自动生成实体类.
⑤通过反射注入.反射特性是.NET平台非常有吸引力的语法游戏,通过反射可以实现动态注入设计,在面向对象世界里转转中"依赖的哲学"有写.
⑥基于DLR实现动态扩展.在.NET4.0中,巨大的变革既是动态编程,为静态语言插上动态的翅膀,让动态扩展无处不在,以后会写到
⑦让扩展可配置.在ASP.NET整体架构中,将Web请求的处理设计为管道模型,模型中的重要元素包括HttpApplication,HttpModule和HttpHandler等,而对于这些管道中的过滤器(HttpModule)和处理器(HttpHandler)则通过配置实现可插拨的扩展想性设计.
示例:
⑧基于ConfigurationManager的配置扩展.一般来说,配置是为扩展而准备的,而扩展可通过配置注入.在.NET框架中提供非常优秀的配置支持,开发者完全可以通过这套完美的配置框架实现自定义的配置扩展.
⑨硬编码总是不好的.任何时候都尽可能将变化的部分从代码中分离,以配置或者其他方式加载,为扩展提供机会.
扩展无处不在,软件设计师的职责,在于将这种无处不在深入到软件系统的各个环节,为各种可能提供基础与准备.
⑻性能是一把尺子
性能,永远是任何软件产品衡量的标准,就像一把标准的千分尺,可以精度准确地为产品打上分数,在.NET中性能的指标体现在语言的各个方面,以后也会详谈性能的多方探讨
⑼信赖的是测试,不是自己
质量的保证,一直是复杂软件的软件开发的软助,为了保证软件产品的完美,测试是整个开发流程中最重要的部分.现代软件开发也衍生出很科学的测试方法,方式和制度,不管是黑盒的还是白盒的,只要逮住BUG,就是好测试.
于传统测试相比较,测试驱动开发(Test Driven Development,TDD) 已经被证明是非常靠谱和科学的开发方式.TDD至少在两个方面为软件开发注入活力:1,保证质量,驱动设计
因此,测试驱动是值得提倡和普及的,将由人的信任测试,转变为由代码的信任测试,信任的是测试,而不是开发者自己.
⑽是进度还是质量,平衡是关键(没有完美的设计,只有适合当下的设计)
具体怎么平衡,百度一下,谷歌一下
结论:
破的窗,将导致更多的窗户被打破,是<>一书阐释的"破窗效应".
而盲羊补牢,未为晚也,养成良好的代码习惯意识,学会独立地思考和重构,远远重要于在破的窗补破的局.
OO之美4(好代码与坏代码)的更多相关文章
- 《你必须知道的.NET》读书笔记三:体验OO之美
此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.依赖也是哲学 (1)本质诠释:“不要调用我们,我们会调用你” (2)依赖和耦合: ①无依赖,无耦合 ...
- 代码的坏味道(14)——重复代码(Duplicate Code)
坏味道--重复代码(Duplicate Code) 重复代码堪称为代码坏味道之首.消除重复代码总是有利无害的. 特征 两个代码片段看上去几乎一样. 问题原因 重复代码通常发生在多个程序员同时在同一程序 ...
- 代码的坏味道(9)——异曲同工的类(Alternative Classes with Different Interfaces)
坏味道--异曲同工的类(Alternative Classes with Different Interfaces) 特征 两个类中有着不同的函数,却在做着同一件事. 问题原因 这种情况往往是因为:创 ...
- 【重构】 代码的坏味道总结 Bad Smell (一) (重复代码 | 过长函数 | 过大的类 | 过长参数列 | 发散式变化 | 霰弹式修改)
膜拜下 Martin Fowler 大神 , 开始学习 圣经 重构-改善既有代码设计 . 代码的坏味道就意味着需要重构, 对代码的坏味道了然于心是重构的比要前提; . 作者 : 万境绝尘 转载请注明出 ...
- Bad Smell (代码的坏味道)
sourcemaking 如果一段代码是不稳定或者有一些潜在问题的,那么代码往往会包含一些明显的痕迹.正如食物要腐坏之前,经常会发出一些异味一样, 我们管这些痕迹叫做 "代码异味" ...
- 重构 之 总结代码的坏味道 Bad Smell (一) 重复代码 过长函数 过大的类 过长参数列 发散式变化 霰弹式修改
膜拜下 Martin Fowler 大神 , 开始学习 圣经 重构-改善既有代码设计 . 代码的坏味道就意味着需要重构, 对代码的坏味道了然于心是重构的比要前提; . 作者 : 万境绝尘 转载请注明出 ...
- Refactoring之——代码的坏味道(一)过长方法
1 代码的坏味道 重构一书中提到了22种代码的坏味道,大致可以分为几类. 识别代码的坏味道,有助于发现代码的潜在问题,从而可以有的放矢的修改现有代码,使之不断完善. 1.1 Bloaters(臭鲱,暂 ...
- Chapter 3 :代码的坏味道
"如果尿布臭了,就换掉它." --Beck奶奶,论保持小孩清洁的哲学 代码的坏味道这一章集中论述该何时重构.具体的重构方法在后面的章节. "没有任何度量规矩比得上见识广博 ...
- 消灭 Java 代码的“坏味道”
消灭 Java 代码的“坏味道” 原创: 王超 阿里巴巴中间件 昨天 导读 明代王阳明先生在<传习录>谈为学之道时说: 私欲日生,如地上尘,一日不扫,便又有一层.着实用功,便见道无终穷,愈 ...
随机推荐
- VSPM虚拟串口使用
(1)打开虚拟串口工具,当你设置好你程序中的串口信息后,打开程序中的串口,然后虚拟串口中所显示的就是程序的所提供的串口信息 (2)选中其中一个串口,修改管理信息,点击”重新连接“ , 直接在管理那里, ...
- TYVJ P1046 Blast Label:dp
描述 设有字符串X,我们称在X的头尾及中间插入任意多个空格后构成的新字符串为X的扩展串,如字符串X为“abcbcd”,则字符串“abcb□cd”,“□a□bcbcd□”和“abcb□cd□”都是X的扩 ...
- 【POJ】3261 Milk Patterns
http://poj.org/problem?id=3261 题意:一个长度为n的串,要求最长的子串的长度且这个子串的出现次数不少于k次.(1<=n<=20000, 2<=k< ...
- UOJ#35 后缀排序
这是一道模板题. 读入一个长度为 n 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置.位置编号为 1 到 n. 除此之外为 ...
- Spring Aop实例
一.XML方式 1. TestAspect:切面类 package com.spring.aop; import org.aspectj.lang.JoinPoint; import org.aspe ...
- [转载] c++ cout 格式化输出浮点数、整数及格方法
C语言里可以用printf(),%f来实现浮点数的格式化输出,用cout呢...? 下面的方法是在网上找到的,如果各位有别的办法谢谢留下... iomanip.h是I/O流控制头文件,就像C里面的格式 ...
- ArcEngine开发 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
if(pFeature!=null) { IPoint pnt = pFeature.Shape as IPoint; pntArray.Add(pnt); } 调试是pntArray.Add(pnt ...
- cookie 换肤
jquery.Cookies.js /** * Cookie plugin * * Copyright (c) 2006 ziqiu.zhang * Dual licensed under the M ...
- OpenCV学习笔记——图像的腐蚀与膨胀
顺便又复习了一下cvcopy如何进行图像拼接(最近觉得打开多幅图像分别看不如缩小掉放拼接到一幅图像上对比来的好) 首先把拼接的目标图像设置兴趣区域ROI,比如我有一个total,要把a.b.c分别从左 ...
- von Neumann architecture
COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION 3.1 COMPUTER COMPONEN ...