- 浏览: 2600600 次
- 来自: 杭州
文章分类
- 全部博客 (1190)
- webwork (4)
- 网摘 (18)
- java (104)
- hibernate (1)
- Linux (85)
- 职业发展 (1)
- activeMQ (2)
- netty (15)
- svn (1)
- webx3 (12)
- mysql (81)
- css (1)
- HTML (6)
- apache (3)
- 测试 (2)
- javascript (1)
- 储存 (1)
- jvm (5)
- code (13)
- 多线程 (12)
- Spring (18)
- webxs (2)
- python (119)
- duitang (0)
- mongo (3)
- nosql (4)
- tomcat (4)
- memcached (20)
- 算法 (28)
- django (28)
- shell (1)
- 工作总结 (5)
- solr (42)
- beansdb (6)
- nginx (3)
- 性能 (30)
- 数据推荐 (1)
- maven (8)
- tonado (1)
- uwsgi (5)
- hessian (4)
- ibatis (3)
- Security (2)
- HTPP (1)
- gevent (6)
- 读书笔记 (1)
- Maxent (2)
- mogo (0)
- thread (3)
- 架构 (5)
- NIO (5)
- 正则 (1)
- lucene (5)
- feed (4)
- redis (17)
- TCP (6)
- test (0)
- python,code (1)
- PIL (3)
- guava (2)
- jython (4)
- httpclient (2)
- cache (3)
- signal (1)
- dubbo (8)
- HTTP (4)
- json (3)
- java socket (1)
- io (2)
- socket (22)
- hash (2)
- Cassandra (1)
- 分布式文件系统 (5)
- Dynamo (2)
- gc (8)
- scp (1)
- rsync (1)
- mecached (0)
- mongoDB (29)
- Thrift (1)
- scribe (2)
- 服务化 (3)
- 问题 (83)
- mat (1)
- classloader (2)
- javaBean (1)
- 文档集合 (27)
- 消息队列 (3)
- nginx,文档集合 (1)
- dboss (12)
- libevent (1)
- 读书 (0)
- 数学 (3)
- 流程 (0)
- HBase (34)
- 自动化测试 (1)
- ubuntu (2)
- 并发 (1)
- sping (1)
- 图形 (1)
- freemarker (1)
- jdbc (3)
- dbcp (0)
- sharding (1)
- 性能测试 (1)
- 设计模式 (2)
- unicode (1)
- OceanBase (3)
- jmagick (1)
- gunicorn (1)
- url (1)
- form (1)
- 安全 (2)
- nlp (8)
- libmemcached (1)
- 规则引擎 (1)
- awk (2)
- 服务器 (1)
- snmpd (1)
- btrace (1)
- 代码 (1)
- cygwin (1)
- mahout (3)
- 电子书 (1)
- 机器学习 (5)
- 数据挖掘 (1)
- nltk (6)
- pool (1)
- log4j (2)
- 总结 (11)
- c++ (1)
- java源代码 (1)
- ocr (1)
- 基础算法 (3)
- SA (1)
- 笔记 (1)
- ml (4)
- zokeeper (0)
- jms (1)
- zookeeper (5)
- zkclient (1)
- hadoop (13)
- mq (2)
- git (9)
- 问题,io (1)
- storm (11)
- zk (1)
- 性能优化 (2)
- example (1)
- tmux (1)
- 环境 (2)
- kyro (1)
- 日志系统 (3)
- hdfs (2)
- python_socket (2)
- date (2)
- elasticsearch (1)
- jetty (1)
- 树 (1)
- 汽车 (1)
- mdrill (1)
- 车 (1)
- 日志 (1)
- web (1)
- 编译原理 (1)
- 信息检索 (1)
- 性能,linux (1)
- spam (1)
- 序列化 (1)
- fabric (2)
- guice (1)
- disruptor (1)
- executor (1)
- logback (2)
- 开源 (1)
- 设计 (1)
- 监控 (3)
- english (1)
- 问题记录 (1)
- Bitmap (1)
- 云计算 (1)
- 问题排查 (1)
- highchat (1)
- mac (3)
- docker (1)
- jdk (1)
- 表达式 (1)
- 网络 (1)
- 时间管理 (1)
- 时间序列 (1)
- OLAP (1)
- Big Table (0)
- sql (1)
- kafka (1)
- md5 (1)
- springboot (1)
- spring security (1)
- Spring Boot (3)
- mybatis (1)
- java8 (1)
- 分布式事务 (1)
- 限流 (1)
- Shadowsocks (0)
- 2018 (1)
- 服务治理 (1)
- 设计原则 (1)
- log (0)
- perftools (1)
最新评论
-
Aqu415:
,默认是netty还是hassion?
dubbo入门 -
siphlina:
课程——基于Python数据分析与机器学习案例实战教程分享网盘 ...
Python机器学习库 -
san_yun:
leibnitz 写道hi,我想知道,无论在92还是94版本, ...
hbase的行锁与多版本并发控制(MVCC) -
leibnitz:
hi,我想知道,无论在92还是94版本,更新时(如Puts)都 ...
hbase的行锁与多版本并发控制(MVCC) -
107x:
不错,谢谢!
Latent Semantic Analysis(LSA/ LSI)算法简介
有意义的命名
1.名副其实,体现本意。
int d; //时间,天计算
int elapsedTimeIndDays;
2.言简意赅,避免废话的命名
比如Product,还有一个ProductInfo或者ProductData。区别何在? 比如下面这个方法:
getActiveAccount();
getActiveAccountInfo();
程序员应该调用哪个方法?
3.类名应该是名词或者名称短语,如Customer,VikiPage,Account,AddressPaser。避免使用Manager,Processor,Data这样的类名,类名不应该是短语。
而方法名应该是动词或者动词短语,如postPayment,deletePage。
4.一种概念统一用一种命名规则。
对于每个抽象概念选一个词,并且一以贯之。列入,使用get,load,query,find来给不同的DAO定义同样的方法。你怎么记得住那个类中哪个方法。你只能去看看详细看看方法原型,返回值是什么,注释是什么,然后才知道应该调用哪个方法。
方法
1.避免写过于复杂的函数。service的代码大部分都非常短小,但是我还是找到一个,下面这段截取自DefaultFormService的代码:
public void init() throws ServiceInitializationException {
initFormKeys();
ResourceLoaderService resourceLoader = (ResourceLoaderService) getService(ResourceLoaderService.SERVICE_NAME);
formConfig = new FormConfig(this);
// 防止重复装入同一文件
Set loadedDescriptors = new HashSet();
StringBuffer rundataKey = new StringBuffer("form" + getInstanceName());
for (Iterator i = getConfiguration().getList(FORM_DESCRIPTORS).iterator(); i.hasNext();) {
String descriptor = (String) i.next();
URL descriptorURL;
try {
descriptorURL = resourceLoader.getResourceAsURL(descriptor);
} catch (ResourceNotFoundException e) {
throw new ServiceInitializationException("Invalid URI broker descriptor: " + descriptor);
}
rundataKey.append(descriptorURL);
if (!loadedDescriptors.contains(descriptorURL)) {
loadDescriptor(descriptorURL);
loadedDescriptors.add(descriptorURL);
}
}
this.rundataKey = rundataKey.toString();
// 处理group的继承关系
processGroups();
super.init();
}
也许你会花3分钟时间开懂这段代码,或者在一分半钟已经没有耐心看懂这段代码。这里面有太多的细节一下子展现在我们面前。有太多的不同层级的抽象。奇怪的字符串和函数调用。不过只要简单的方法抽离和重命名,就能让代码清晰很多,下面这段代码,好理解了吗?
重构之后:
public void init() throws ServiceInitializationException {
initFormKeys();
this.formConfig = new FormConfig(this);
this.rundataKey = getRundataKey();
// 处理group的继承关系
processGroups();
super.init();
}
private String getRundataKey(){
ResourceLoaderService resourceLoader = (ResourceLoaderService) getService(ResourceLoaderService.SERVICE_NAME);
// 防止重复装入同一文件
Set loadedDescriptors = new HashSet();
StringBuffer rundataKey = new StringBuffer("form" + getInstanceName());
for (Iterator i = getConfiguration().getList(FORM_DESCRIPTORS).iterator(); i.hasNext();) {
String descriptor = (String) i.next();
URL descriptorURL;
try {
descriptorURL = resourceLoader.getResourceAsURL(descriptor);
} catch (ResourceNotFoundException e) {
throw new ServiceInitializationException("Invalid URI broker descriptor: " + descriptor);
}
rundataKey.append(descriptorURL);
if (!loadedDescriptors.contains(descriptorURL)) {
loadDescriptor(descriptorURL);
loadedDescriptors.add(descriptorURL);
}
}
}
定义方法最基本的两条定律:第一规则短小,第二规则还是短小。代码应该短到多少合适?最多不能超过一个屏。最好能三行四行搞定。
2.函数内的代码应该保持同一抽象层次。
什么是抽象层次?原生的java API应该是最低抽象层次,比如
StringBuffer sb = StringBuffer(“form”);
然后我们框架在上面封装属于中间抽象层次,比如:
ResourceLoaderService resourceLoader = (ResourceLoaderService) getService(ResourceLoaderService.SERVICE_NAME);
最上面抽象层次是领域里面的业务方法。比如
initFormKeys();
之前的代码之所以复杂是因为不同抽象层次的代码混合在一起,导致在阅读代码的时候会有思维跳跃。代码层次越低需要了解的细节越多。我们读书看报都是先看看目录,提纲,最后再看感兴趣的章节,而不会一股脑的全出来所有的内容?代码也是如此。
3. 只做一件事情
最前面的代码显然做了不只一件事情。函数应该只做一件事情,做好这一件事情。关键是那件事情是什么?代码只做了一件事情,对吧?其实也很容易看成五件事:
1. 初始化initFormKeys。
2. 初始化FormConfig。
3. 初始化getRundataKey。
4. 处理group的继承关系。
5. 初始化父类。
如果函数做的那件事情其实应该是函数命名的那件事,比如postComplaint()应该做的事情就是发起投诉,发起投诉可能有很多步骤,第一步要检查参数是否有效。第二步要通知诚保,第三部要保存到数据库。如果函数只是做了该函数名下同一抽象层上的步骤,则函数还是只做了一件事情。
4.函数参数
1.标识flag参数。
标识参数抽离不堪,向函数中传入一个字符串判断等A做什么行为,等于B做什么行为?不如定义两个函数: doForA(),doForB();
2.如果函数有三个,或者三个以上的参数,就说明其中一些参数应该封装为类了。以前我对于这种做法非常粗暴,把所有参数都封装成一个类,这是非常不可取的。需要思考一下,把合适的参数封装到类里面。
有时候会纠结于函数的参数无法封装。比如投诉中方法A需要投诉方ID,被投诉方ID,交易单号,交易类型,投诉类型,而有的地方取不需要投诉类型,且投诉类型和交易信息不应该封装在一个VO里面。
3.无副作用
4.分割操作和询问
函数要么做什么事情,要么回答什么事情,但二者不可兼得。看看这个例子:
public boolean setXXX(String attribute,String value);
应函数设置某个属性,如果成功就返回true。如果不存在这个属性就返回false,这样导致如下语句:
if(set(“username”,”unclebob”))..
好的方式是应该把操作和询问分开。
If(attributeExist(“username”)){
setAttribute(“username”,”unclebob”);
}
6. 如何做到
Robert说他也无法做到一开始就按照这些规则写函数,一开始也是冗长而复杂,过长的参数列表,名称随意取的,也会有重复代码。但是他会配上一套单元测试,覆盖到每行丑陋的代码,最后打磨这些代码,分解函数,同时保持单元测试通过。
注释
1. 不要为了注释而注释。
2. 注释不能美化糟糕的代码。
3. 好的注释:
a) 法律信息
b) 提供信息
c) 对设计意图的解释
d) 警示
e) TODO 注释
4. 坏的注释
a) 多余的注释
b) 注释掉的代码
c) 归属和署名(这个属于SVN源代码管理工具轻易提供的功能)
格式
1. 变量的定义和变量的使用不要隔的太远。
2. 相关函数放在一起,若某个函数调用了另外一个,就应该把他们放在一起。而且调用者应该尽可能的放在被调用者的上面。这样程序就有了一个自然的顺序。若坚定地遵守这条约定,读者就能够确信函数声明再起调用后很快出现。
数据结构
异常处理
单元测试
相关推荐
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.5</version> <executions> <execution> <id>add-source</id> ...
ait descriptors parsing<br/><br/>2003.01.19:<br/> - fixed bug for ait section parsing<br/> - started code clean up and consolidation for easy porting<br/><br/>2003.01.13:<br/> - added initial ait ...
The goal is clean code that<br/>works, and for a whole bunch of reasons:<br/>• Clean code that works is a predictable way to develop. You know when you are<br/>finished, without having to worry ...
</modules> packaging节点只能指定为pom,modules节点说明由几个模块组合,上面是把我们经常使用的架构分层模式分成一个个组件进行开发dao->service->web层。此pom文档经常还被用来进行一些依赖管理和插件管理,...
<groupId>org.nutz.boot</groupId> <artifactId>nutzboot-maven-plugin</artifactId> <version>${nutzboot.version}</version> </plugin> </plugins> </build> 打包jar文件 mvn clean package nutzboot:shade ...
mvn clean install -Dmaven.test.skip=true <br/> ssm-parent<br/> 父模块,其他模块会继承该模块,引入公共的依赖<br/> ssm-model<br/> 模型层模块,提供各种POJO。包括与数据库表对应的模型、传输模型等。提供给...
从Internet上学习到的,也让他回归internet.<br><br> <br><br>文件结构:<br><br>cpp文件: iisidqoverflow.cpp 和 SkShellCodeFunc.cpp <br>头文件: SkShellCodeFunc.h <br>功能文件: WSAStart.cpp和SnakeSocket.cpp...
extended scan code E0<br> 0004h = extended scan code E1<br>6 2 Not used<br>8 4 Device specific information<br><br><br><br>The Save Window<br><br>The Save button saves all captured data to the ...
<name>Clean Logs</name> <triggers> <!-- run once per day. ForceBuild is required if there is no source code change --> <intervalTrigger seconds="86400" buildCondition="ForceBuild" /> </...
<filter-name>struts-cleanup</filter-name> <filter-class> org.apache.struts2.dispatcher.ActionContextCleanUp </filter-class> </filter> <filter-mapping> <filter-name>struts-cleanup</filter-name> ...
... 根据文档将go-cqhttp的上报方式修改为Array 克隆并执行mvn clean install 创建你的 springboot 项目并引用依赖 <dependency> ... <version>1.0.0</version> </dependency> 在启动类上加注解@EnableBot
微软书籍Write Clean Code 微软书籍Write Clean Code 微软书籍Write Clean Code 微软书籍Write Clean Code
<filter-name>struts-cleanup</filter-name> <filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class> filter> <filter> <filter-name>sitemesh</filter-name> <filter-class>...
现在,Microsoft已经比我刚进公司时大了九倍。很难设想,倘若没有准确的指南,公司怎样才能将出错率降低到原来的水平。尤其是在Windows和Macintosh的应用越来越复杂的情况下...<br><br>Steve Maguire<br>西雅图,华盛顿
./blue<br>3) put your device in \'discovery mode\',<br>4) select \'search\' on textual menu,<br>5) select your device to connect with,<br>First time you are requested to enter pin code.<br>6) select ...
mvn clean install -Dmaven.test.skip=true依赖<dependency> <groupId>org.nanoframework</groupId> <artifactId>nano-server</artifactId> <version>1.3.13</version> </dependency> ...快速启动示例...
<br>By Michael Fitzgerald<br>First Edition July 2007 <br>Pages: 176 <br>Series: Pocket References<br>ISBN 10: 0-596-51481-6 | ISBN 13: 9780596514815<br><br>出版社:O’Reilly<br><br>...
编译工具和辅助工具:<br>ADS1.2<br>ADS12_update_842.exe<br>MSYS-1.0.10.exe<br>MinGW-3.1.0-1.exe<br>ImageMagick-6.2.5-5-Q16-...<br>make custom=proj gprs new<br>其中,命令可以为 clean, update, remak<br>
<br/><br/>编写优化、高效、无错地代码 <br/><br/>编程精粹<br/>─── Microsoft 编写优质无错C 程序秘诀<br/><br/>Writing Clean Code<br/>─── Microsoft Techniques for Developing Bug-free C Programs<br/>...
/// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> //...