建议16:易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP,Ruby,Groovy.Javascript等,这些入侵者都有一个共同特征:全是同一类语言-----脚本语言,它们都是在运行期解释执行的.为什么Java这种强编译型语言会需要这些脚本语言呢?那是因为脚本语言的三大特征,如下所示: 灵活:脚本语言一般都是动态类型,可以不用声明变量类型而直接使用,可以再运行期改变类型. 便捷:脚本语言是一种解释性语言,不需要编译成二进制代码,也不需要像Java一样生成字节码.它的…
原文:编写高质量代码改善C#程序的157个建议[1-3] 前言 本文主要来学习记录前三个建议. 建议1.正确操作字符串 建议2.使用默认转型方法 建议3.区别对待强制转换与as和is 其中有很多需要理解的东西,有些地方可能理解的不太到位,还望指正. 建议1.正确操作字符串 字符串应该是所有编程语言中使用最频繁的一种基础数据类型.如果使用不慎,我们就会为一次字符串的操作所带来的额外性能开销而付出代价.本条建议将从两个方面来探讨如何规避这类性能开销: 1.确保尽量少的装箱 2.避免分配额外的内存空间…
建议122:以<Company>.<Component>为命名空间命名 建议以<Company>.<Component>为程序集命名,比如Microsoft.Windows.Design.这有助于唯一地标识我们的命名空间. 另外一种有效且肯定是唯一的表示命名空间的方式是使用域名.假设我们的域名是www.microsoft.com,那么命名空间应该命名为Com.Microsoft.<Component>.使用域名命名自己的程序的方法在Java世界中…
建议2: 使用默认转型方法 除了字符串操作外,程序员普遍会遇到的第二个问题是:如何正确地对类型实现转型.在上一个建议中,从int转型为string,我们使用了类型int的ToString方法.在大部分情况下,当需要对FCL提供的类型进行转型时,都应该使用FCL提供的转型方法. 这些转型方法包括: 使用类型的转换运算符. 使用类型内置的Parse.TryParse,或者如ToString.ToDouble和ToDateTime等方法. 使用帮助类提供的方法. 使用CLR支持的转型. 下面分别对这些…
原文发表在我的博客主页,转载请注明出处! 建议二十八:区别对待可变对象和不可变对象 python中一切皆对象,每一个对象都有一个唯一的标识符(id()).类型(type())以及值,对象根据其值能否修改分为可变对象和不可变对象,其中数字.字符串.元组属于不可变对象,字典以及列表.字节数组属于可变对象. 来看一段程序: class Student(object): def __init__(self,name,course=[]): self.name = name self.course = c…
原文发表在我的博客主页,转载请注明出处! 建议四十一:一般情况下使用ElementTree解析XML python中解析XML文件最广为人知的两个模块是xml.dom.minidom和xml.sax,作为主要解析XML方法的两种实现,DOM需要将整个XML文件加载到内存中并解析为一棵树,简单但是内存消耗大:SAX是基于事件驱动的,虽不需要全部装入XML文件,但是处理过程复杂.一般情况下选择ElementTree便可以,cElementTree是其Cython实现,速度更快,消耗内存更少,性能上更…
编写高质量代码改善python程序91个建议学习 第一章 建议1:理解pythonic的相关概念 狭隘的理解:它是高级动态的脚本编程语言,拥有很多强大的库,是解释从上往下执行的 特点: 美胜丑,显胜隐,简胜杂,杂胜乱,平胜陡,疏胜密 python定义 #python排序 def quicksort(arr): less=[];greater=[] if len(arr)<=1: return arr pivot=arr.pop() for x in arr: if x<=pivot: less…
最近读了陆敏技写的一本书<<编写高质量代码  改善C#程序的157个建议>>书写的很好.我还看了他的博客http://www.cnblogs.com/luminji . 前面部分选择什么,该怎么用我没有怎么消化.看了他写的一篇关于自动化测试的工具,能够录下人的操作,然后可以在多台机器上调用,因为是windows开发的,我没有亲手实验,先记录在这里,以后要用可以找,"Code UI Automation" 文中大量都是通过对比IL代码,来区分哪个方案更好.我在看&…
建议157:从写第一个界面开始,就进行自动化测试 如果说单元测试是白盒测试,那么自动化测试就是黑盒测试.黑盒测试要求捕捉界面上的控件句柄,并对其进行编码,以达到模拟人工操作的目的.具体的自动化测试请学习Code UI Automation,这里不再介绍. 转自:<编写高质量代码改善C#程序的157个建议>陆敏技 到此,<编写高质量代码改善C#程序的157个建议>的笔记已经全部完成. 转载请注明出处: 作者:JesseLZJ出处:http://jesselzj.cnblogs.com…
建议156:利用特性为应用程序提供多个版本 基于如下理由,需要为应用程序提供多个版本: 应用程序有体验版和完整功能版. 应用程序在迭代过程中需要屏蔽一些不成熟的功能. 假设我们的应用程序共有两类功能:第一类功能属于单机版,而第二类的完整版还提供了在线功能.那么,在功能上,需要定制两个属性“ONLINE”和“OFFLINE”.在体验版中,我们只开放“OFFLINE”功能.要实现此目的,不应该提供两套应用程序,而应该通过最小设置.为一个应用程序输出两个发布版本.这一切,可以通过.NET中的特性(At…
建议155:随生产代码一起提交单元测试代码 首先提出一个问题:我们害怕修改代码吗?是否曾经无数次面对乱糟糟的代码,下决心进行重构,然后在一个月后的某个周一,却收到来自测试版的报告:新的版本,没有之前的版本稳定,性能也更差了,Bug似乎也变多了.也就是说,重构的代码看上去质量更高了,可实际测试结果却不如人意. 几乎每个程序员都因为此类问题纠结过.我们要修改的代码也许来自某些不负责任或经验欠佳的程序员,也许这些代码是自己一年前写的,但是看上去已经惨不忍睹.我们想要修改这些代码,却担心重构出别的问题.…
建议154:不要过度设计,在敏捷中体会重构的乐趣 有时候,我们不得不随时更改软件的设计: 如果项目是针对某个大型机构的,不同级别的软件使用者,会提出不同的需求,或者随着关键岗位人员的更替,需求也会随个人意志有所变更. 如果竞争对手增加了新需求,我们也不得不为正在研发的新产品调整设计方案. 刚开始的架构太糟糕了,这可能源于设计经验的不足或者架构师的不负责任. 以上分别从外部和内部描述了必须修改需求和设计的几种场景.也就是说,在软件开发过程中,变化几乎总会发生. 为了捕捉需求上的不断变化,软件开发必…
建议153:若抛出异常,则必须要注释 有一种必须加注释的场景,即使异常.如果API抛出异常,则必须给出注释.调用者必须通过注释才能知道如何处理那些专有的异常.通常,即便良好的命名也不可能告诉我们方法会抛出那些异常,在这种情况下,使用注释是最好的手段. /// <summary> /// 注释 /// </summary> /// <param name="value">输入参数注释</param> /// <returns>返…
建议152:最少,甚至是不要注释 以往,我们在代码中不写上几行注释,就会被认为是钟不负责任的态度.现在,这种观点正在改变.试想,如果我们所有的命名全部采用有意义的单词或词组,注释还有多少存在的价值. 即便再详细的注释也不能优化糟糕的代码.并且注释往往不会随着代码的重构自动更新,有时候我们可能会在修改代码后忘记更新那段用来表达最初意图的文字了.所以,尽量抛弃注释吧,除非我们觉得只有良好的代码逻辑和命名仍旧不足以表达意图. 当然,有些注释可能不得不加,如一些版权信息.另外,如果我们正在开发公共API…
建议151:使用事件访问器替换公开的事件成员变量 事件访问器包含两部分内容:添加访问器和删除访问器.如果涉及公开的事件字段,应该始终使用事件访问器.代码如下所示: class SampleClass { EventHandlerList events = new EventHandlerList(); public event EventHandler Click { add { events.AddHandler(null, value); } remove { events.RemoveHa…
建议150:使用匿名方法.Lambda表达式代替方法 方法体如果过小(如小于3行),专门为此定义一个方法就会显得过于繁琐.比如: static void SampeMethod() { List<string> list=new List<string>(){"Mike","Rose","Steve"}; var mike = list.Find(new Predicate<string>(HaveLength…
建议149:使用表驱动法避免过长的if和switch分支 随着代码变得复杂,我们很容易被过长的if和switch分支困扰. 一个类枚举类型Week如下: enum Week { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday } 如果要把Week的元素值用中文输出,简单而丑陋的方法也许是封装一个GetChineseWeek方法: static string GetChineseWeek(Week week) { swi…
建议148:不重复代码 如果发现重复的代码,则意味着我们需要整顿一下,在继续前进. 重复的代码让我们的软件行为不一致.举例来说,如果存在两处相同的加密代码.结果在某一天,我们发现加密代码有个小Bug,然后修改了它,却又忘记了角落里的某处存在着一份相同的代码,那么这个Bug就会隐藏起来. 让我们重现这个例子: void PagerEncrypt() { //加密代码 } void AnswerEncrypt() { //相同的加密代码 } 在这段代码中,方法PagerEncrypt和AnswerE…
建议147:重构多个相关属性为一个类 若存在多个相关属性,就应该考虑是否将其重构为一个类.查看如下类: class Person { public string Address { get; set; } public string ZipCode { get; set; } public string Mobile { get; set; } public string Hotmail { get; set; } //其他省略 } 上面代码中的这四个属性全部跟联系方式有关,所以,我们应该重构一…
建议146:只对外公布必要的操作 那些没有必要公开的方法和属性要声明成private.如果需要公开的方法和属性超过9个,在VS默认的设置下,就需要滚屏才能显示在Intellisense中,如图: SampleClass类: class SampleClass { private int field1; private int field2; private int field3; public int MyProperty1 { get; set; } public int MyProperty…
建议145:避免过长的方法和过长的类 如果违反“一个方法只做一件事”及类型的“单一职责原则”,往往会产生过长的方法和过长的类. 如果方法过长,意味着可以站在更高的层次上重构出若干更小的方法.以行数作为指标,有人建议一个方法不要超过10行,有人建议不要超过30行.当然,这没有唯一标准.在我看了,一个方法在VS中需要滚屏才能阅读完,那么就肯定有些过长了,必须想办法重构它. 对于类型,除非有非常特殊的理由,类型的代码不要超过300行.如果行数太多了,则要考虑是否重构. 转自:<编写高质量代码改善C#程…
建议144:一个方法只做一件事 “单一职责原则”(SRP)要求每一个类型只负责一件事情.我们将此概念扩展到方法上,就变成了:一个方法只做一件事. 回顾上一建议的代码,LocalInit和RemoteInit方法是两件事情,但是在同一抽象层次上,在类型这个层次对外又可以将其归并为“初始化”这一件事情上.所以,“同一件事”要看抽象所处的地位. 转自:<编写高质量代码改善C#程序的157个建议>陆敏技…
建议143:方法抽象级别应在同一层次 看下面代码: class SampleClass { public void Init() { //本地初始化代码1 //本地初始化代码2 RemoteInit(); } void RemoteInit() { //远程初始化代码1 //远程初始化代码2 } } Init方法本意要完成初始化动作,而初始化包括本地初始化和远程初始化.这段代码中,Init方法内部代码的组织结构是本地初始化直接运行在方法内部,而远程初始化代码却被封装为一个方法在这里被调用.这显然…
建议142:总是提供有意义的命名 除非有特殊原型,否则永远不要为自己的代码提供无意义的命名. 害怕需要过长的命名才能提供足够的意义?不要怕,其实我们更介意的是在代码的时候出现一个iTemp. int i 这样的命名只能出现在循环中(如for循环),除此之外,我们找不到任何理由在代码的其他地方出现这样的无意义命名. 例如,以下命名都是良好的典范: private CultureInfo m_CurrentCulture; private CultureInfo m_CurrentUICulture…
建议141:不知道该不该用大括号时,就用 如果if条件语句只有一行语句,要不要使用大括号? 答案是:建议使用.一个括号不会增加多少代码,但是却让代码看上去增加了一致性.括号本身只会让代码更具条理性. 转自:<编写高质量代码改善C#程序的157个建议>陆敏技…
建议140:使用默认的访问修饰符(我不太赞成作者的这个观点,这样减少的代码基本可以忽略不计,但是,如果把访问修饰符补充完整,反而会使代码更加易读.我认为自己写代码时应该尽量加上访问修饰符,看别人写的代码时能看懂就可以了.以下是作者的观点) 代码整洁的要求之一,就是尽量减少代码,我们从使用默认的访问修饰符开始. 类型成员的修饰符默认是private,即下面的代码: class SampleClass { string name; void SampleMethod(){} } 等同于: class…
建议139:事件处理器命名采用组合方式 所谓事件处理器,就是实际被委托执行的那个方法.查看如下代码: public MainWindow() { InitializeComponent(); Button button = new Button(); button.Click += button_Click; button.SizeChanged += button_SizeChanged; button.MouseDown += button_MouseDown; } void button_…
建议138:事件和委托变量使用动词或形容词短语命名 事件和委托使用场景是调用某个方法,只不过这个方法由调用者赋值.这决定了对应的变量应该以动词或形容词短语命名. 关于事件和委托变量妥当的命名示例如下: public event RoutedEventHandler Click; public event SizeChangedEventHandler SizeChanged; 这两个例子是WPF中Button类型,它们实际不是作为类型的字段出现的,而是作为事件访问器出现的: public eve…
建议137:委托和事件类型应添加上级后缀 委托类型本身是一个类,考虑让派生类的名字以基类名字作为后缀.事件类型是一类特殊的委托,所以事件类型也遵循本建议. 委托和事件的正确的命名方式有: public delegate void HttpContinueDelegate(int statusCode, System.Net.WebHeaderCollection httpHeaders); public delegate bool ValidateValueCallback(object val…
建议136:优先使用后缀表示已有类型的新版本 加后缀在某些情况下是很奇怪的形式,我们都不愿意看到OrderProcessor2这样的类型.但是,有的时候仍旧有必要这样做.最典型的是FCL中关于数字证书操作的X509Certificate和X509Certificate2这两个类型. X509Certificate类型最早出现在FCL 1.0/1.1版本中,后来在FCL2.0版本中出现了一个后续的版本:类型X509Certificate2.这个后续的版本不是一个先前版本的子类,而是作为替代版本出现…