如何写好代码

来源:互联网 发布:网络维护 资质要求 编辑:程序博客网 时间: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.

1 0
原创粉丝点击