Keep your code clean
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Keep your code clean

on

  • 1,665 views

clean code

clean code

Statistics

Views

Total Views
1,665
Views on SlideShare
1,665
Embed Views
0

Actions

Likes
3
Downloads
52
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Keep your code clean Presentation Transcript

  • 1. Keep Your Code Clean ——如何编写整洁代码 2011年 7月
  • 2. “ 任何一个傻瓜都可以写出计算机可以理解的代码。唯有写出人类 ”容易理解的代码,才是优秀程序员。 -- Martin Fowler《重构》
  • 3. 1 命名: 有意义2 方法: 有层次3 类: 合理封装4 注释: 够简洁5 格式: 能统一6 重构: 持续改进
  • 4. 整洁代码的标准
  • 5. 什么才是整洁代码可读性 可维护性 可扩展性
  • 6. 好命名带来高效率(code once, read more)
  • 7. 名副其实就不需要注释/** * 用来处理买家付 款之 后, 将sku从一个换成另外 一个, 同时减库存, 这里会导致商品 的库 存 被多 减 * * @param itemId 掉 的库 * @param quantity 需 要 减 掉的 库 存 * @param skuId 要 替 换 成的 目 标 sku 要替 成 的 目标 * @param bizOrderId * @param sellerId * @return * @throws IcException */ public UpdateAuctionQuantityResultDOupdateAuctionQuantityAndSku( itemId,updateAuctionQuantityAndSku(final long itemId, final intquantity, skuId, bizOrderId, final long skuId, final long bizOrderId, final longsellerId) IcException;sellerId) throws IcException;
  • 8. 避免命名之间的混淆
  • 9. 我碰到的一些例子StdCategoryDO getCategory(long catID) long catID)StdCategoryDO getCategory(int categoryId); int categoryId);StdCategoryDOgetCategoryThrowExceptionIfNull(int intcategoryId);categoryId);
  • 10. 请抵制缩写的诱惑
  • 11. 名称长度与作用范围成正比for(for(int i = 0; i < array.length; i++) { //do something}/** 小 二 删 除 的 状 态 */public static final int DELETED_BY_XIAOER = -4;/** 小 二 下 架 的 状 态 */public static final int INSTOCK_BY_XIAOER = -3;
  • 12. 取个好名字是一种艺术鸟宿池中树,僧推(敲)月下门。 推
  • 13. 一些命名借鉴add/remove up/down send/receive lock/unlock first/last start/stopopen/close next/previous show/hide source/target old/new insert/delete min/max begin/end Factory Template Composite Proxy VisitorCommand Builder Adapter Decorator Observer Strategy
  • 14. 如何改善已有代码中的命名 ?
  • 15. 一个很常见的例子List<int int[]> theList; intpublic List<intint[]> getThem(){ int List<intint[]> list1 = new ArrayList<int int int[]>(); int for(int[] x : theList) { for(int if (x[0] == 4) { list1.add(x); } } return list1;}
  • 16. 做第一次改进后的结果private static final int FLAGGED = 4;private static final int STATUS_VALUE = 0;List<int int[]> gameBoard; int ;public List<int int[]> getFlaggedCells(){ int (){ List<int int[]> flaggedCells = new ArrayList<int[]>(); int int[] cell : gameBoard) { for (int ) if (cell[STATUS_VALUE] == FLAGGED) { flaggedCells.add(cell); } } return flaggedCells; ;}
  • 17. 再一次重构后的结果class Cell{ int status; private static final int FLAGGED = 4; boolean isFlegged() { return status == FLAGGED; }}List<Cell> gameBoard;public List<Cell> getFlaggedCells(){ List<Cell> flaggedCells = new ArrayList<Cell>(); for (Cell cell : gameBoard) { if (cell.isFlagged()){ flaggedCells.add(cell); } } return flaggedCells;}
  • 18. 一个方法只做一件事情
  • 19. 借鉴Shell Shell脚本编程原则 Shellegrep (Operation|Method)Exception -B1/home/admin/itemcenter/logs/hsf.log | fgrep 执行 HSF服 务 [ | sed s/]时 出 现 未 知 异 常 : 未 找 到 需要 调 用 的 方 法 : [a-zA-Z]+; | sort | uniq |fgrep -v === | sort | uniq -c
  • 20. 如何判断”一个方法只做一件事”?能用”为了..., 需要...” 来描述这个方法
  • 21. 保持同一抽象层级
  • 22. 保持同一抽象层级public void increaseItemQuantity(… ) throws IcException { … // 判断宝贝是 否 需 要 被 更 新 if (isNotModified(… )) { return; } doIncreaseItemQuantity(… ); // 如果下架的 是 拍 卖 的 商 品 ,则 更 新 快 照 updateSnapIfAuction(… ); // 清缓存 itemTairCacheService.removeItemDO(itemId); // 发送notify消息 sendModifyQuantityNotify(… ); // 更新实时搜 索 updateModifyQuantityDocument(… );}
  • 23. 参数越少越好: 0>1>2>3 (参数封装类)
  • 24. 参数的顺序最好反应被使用的顺序
  • 25. 标识参数表明函数不止做一件事
  • 26. 尽量将异常处理从主流程中分离出来
  • 27. 一个异常的使用例子private ProcessResultDO updateItemAndSkuQuantity(… ) throws IcException { // 获 取 卖 家 信 息 BaseUserDO seller = getUser(sellerId); if (seller == null){ … return result; } //获 取 宝 贝 以 及宝 贝 的SKU ItemDO dbItem = getItemWithSku(itemId); if (dbItem == null){ … return result; } //校 验 是 否 允 许更 改 库存 stepCheckModifyQuantity(… ); //更 新 宝 贝 库 存 doModifyItemQuantity(… );}
  • 28. 重构之后private ProcessResultDO updateItemAndSkuQuantity(… ) throws IcException { final ProcessResultDO result = new ProcessResultDO(); try { // 获 取 卖 家 信 息 BaseUserDO seller = getUserThrowExceptionIfNull ThrowExceptionIfNull(sellerId); ThrowExceptionIfNull //获 取 宝 贝 以 及 宝 贝 的SKU ItemDO dbItem = getItemWithSkuThrowExceptionIfNull ThrowExceptionIfNull(itemId); ThrowExceptionIfNull //校 验 是 否 允 许 更 改 库存 stepCheckModifyQuantity(… ); //更 新 宝 贝 库 存 doModifyItemQuantity(… ); }catch catch(ErrorCodeException e) { catch return injectErrorCodeTo(result, e); }catch catch(Exception e) { catch throwIcException(e); }
  • 29. 封装的内容太多, 就拆分它
  • 30. 对外暴露内容太多, 封装 封装它public Map<String, String> getFeatures() { return features;}features = item.getFeatures();if (features == null) {… … }features.get(“ prop” );item.getFeatures().get(“ prop” )public String getPropertyFeature(){… }
  • 31. 那些令人喷饭的注释 //当我写这段代码的时候,只有老天和我自己知道我在做什么。 //现在,只剩老天知道了。//我不对以下代码负责。//是他们逼我写的,是违背我意愿的。
  • 32. 注释尽量做到简洁绅士的演讲,应该像女人的裙子,越短越好。 --林语堂
  • 33. 最好不写注释写注释说明表达意图的失败糟糕代码是注释存在的动机之一
  • 34. 必须写的注释警告他人版权协议公共API
  • 35. 写注释的注意事项无法自注释的情况(副作用)注释与代码同步注释只说明Why
  • 36. “ 对代码采用一致的格式, 这不是浪费时间的愚蠢修饰, 而是一种重浪费时间的愚蠢修饰,要的交流工具。 ” --Andy Hunt《程序员的思维修炼》
  • 37. 像报纸一样, 头版只放重要信息,细节放里面
  • 38. 选择一款赏心悦目的字体
  • 39. 代码排版的注意事项紧密相关的代码放在一起保持代码短小(width:80)合理的运用空行和空格保持格式统一一致
  • 40. 允许先写肮脏的代码, 但必须重构它
  • 41. 尽量借助工具重构, 避免人为错误
  • 42. 持续改进, 避免破窗效应
  • 43. 类 注释 方法 格式 整洁命名 重构 代码
  • 44. 参考资料