如何写好代码
来源:互联网 发布:网络维护 资质要求 编辑:程序博客网 时间:2024/05/01 20:04
前言
最近在接手别人的项目,看人家的代码是痛苦的,尤其是写的不怎么样的代码。想到之前看了一本《代码整洁之道》,对我影响深远,便想作此文舒缓一下心情。
如果你是大牛请忽略本文。
什么是好代码
书中说:好的代码就是它恰好为解决某一问题而存在。
听人说:好的代码就是给一个应届毕业生也可以看懂。
我现在深深的秉承 单一职责原则,就这一条足以写出我认为漂亮的代码。
作为一个无名小卒,为了梦想,就算为了后人能看懂,必须好好写代码。
好代码是什么样子的
举个抽象的例子,如果代码写成这样,把所有的逻辑按照顺序都堆砌在这个方法中,那么这段代码或许思路清晰,路径考虑周全,效率非常高,但是这并不算好的代码。
public class MechandiseManager{ private static final Integer TYPE_ONE = 1; private static final String CODE_EXAMPLE_DELICIOUS = "delicious"; private static final String MAP_KEY_EXAMPLE = "key"; private static volatile boolean running = false; @Autowired private static SomeService someService;public static GoodsParam setGoodParam(String code,Integer id, Float price, Integer type) throws Exception{ GoodsParam goodParam = new FoodParam(); goodParam.setCode(code); goodParam.setXXId(id); if(type.equals("1")){ if(){ //shit mass }else{ //shit mass } for(int i=0;i<SOME;i++){ map.get("field1"); } }else{ String val = someDataMap.get(obj.getSomeField()); if(val==SOME || ((CONDITION2)&&(CONDITION3))){ //shit mass Data data = someService.selectSomeData(); for(){ } }else{ //shit mass if(){ } } } if(){ //businsess } return goodParam ; }}
分析代码
代码中if条件语义不是非常人性化,分支混乱,本来是处理Goods的参数的,混杂太多条件,写的人或许过一段时间再来,就看的云里雾里,更别指望别人来给他改BUG。不过,该代码值得参考的地方在于设置了一些可读性强的常量。
改进代码
public static GoodsParam setGoodParam(String code,Integer id, Float price, Integer type) throws Exception{ GoodsParam goodParam = new FoodParam(); goodParam.setCode(code); goodParam.setXXId(id); if(type.equals(TYPE_ONE)){ processSomething(goodParam); }else{ String val = someDataMap.get(MAP_KEY_EXAMPLE); processAnotherThing(goodsParam,val); } if(){ //businsess } return goodParam ;}
再次改进
public static GoodsParam setGoodParam(String code,Integer id, Float price, Integer type) throws Exception{ GoodsParam goodParam = new FoodParam(); goodParam.setCode(code); goodParam.setXXId(id); if(isTypeONE(type)){ processSomething(goodParam); }else{ processAnotherThing(goodsParam,val); } thenProcessSomeThing(); return goodParam ;}public static boolean isTypeONE(Integer type){ return type.equals(TYPE_ONE);}
终极改进
public static GoodsParam setGoodParam(String code,Integer id, Float price, Integer type) throws Exception{ GoodsParam goodParam = new FoodParam(); goodParam.setCode(code); goodParam.setXXId(id); processType(goodParam ); thenProcessSomeThing(); return goodParam ;}
多学习开源项目
以下节选自Spring框架的内部源码:
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } }
再看一个DispatcherServlet的源码:
protected void onRefresh(ApplicationContext context) throws BeansException { initStrategies(context); } /** * Initialize the strategy objects that this servlet uses. * <p>May be overridden in subclasses in order to initialize * further strategy objects. */ protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); }
有没有觉得非常清晰,一步一步,非常震撼,当时见到的时候真的觉得自己写的代码写的就是Shit…
总结
个人总结:写代码并不是一下子就能写出那么漂亮而简洁的代码,在写的过程中,要像写文章一样思考,而不是记流水账一样,想到哪里就写到哪里,先把逻辑写完,然后回顾代码,看看能不能把那些分支,循环尽可能简化,例如把每一个判断都尽可能让人看懂,用一个函数表达他的含义,这样函数调用函数,层次分明,看着就知道哪一步是做什么,哪一步又需要处理什么,一目了然。以后再查看自己的代码或者别人维护你的代码时,自顶向下,由主干要枝叶,条理清晰,神清气爽。
在下无名小卒,但愿能 make you impressive.
- 如何写好代码
- 如何写好代码
- 如何写好代码
- 如何写好代码
- 如何写好代码
- 如何写好代码
- 如何写好代码
- 如何写好代码
- 如何写一手好代码
- 如何写好代码----java代码优化
- 程序员的基本原则 /如何写好代码
- 程序员的基本原则 /如何写好代码
- 好的程序员如何写代码
- 老生常谈之如何写好的代码
- 转发别人的 如何写好代码
- 如何写好的代码注释
- 如何写好优质的代码
- 如何写好代码中的函数?
- 装载、显示、存储---创建与复制------ROI-----掩码
- 【NOIP2016提高A组集训第16场11.15】兔子
- jacoco 原理篇
- Android事件分发机制概括
- 模拟银行全部功能
- 如何写好代码
- iOS 视频的每一帧图片关键帧
- C#的async和await
- Error creating assembly archive pack: You must set at least one file.
- 研究生开题总结
- 【转载】session 生命周期,cookie详解
- wxpython的常用方法
- 多态
- Java面向对象-单例设计模式