“在笔者看来,编程思想与语言种类无关,它也应当是跨语言的,只不过可能在底层实现的细节不一样,仅此而已。平时也接触过很多的技术开发,但很少遇到一个代码写的非常棒的,有的是代码不美观,不规范,有的是不会利用语言特性简化抽象自己的代码….等等。我们编写一个软件始终要思考的一个问题是怎么能降低软件复杂性?而并不是一味的命令式编程,徒增软件复杂性,最后导致的结果就是开发人员累个半死,解决的bug还存在治标不治本的问题。也还存在不想看自己写的代码等等问题。诸如此类的问题。我们怎么去解决这种开发人员的编码水平瓶颈问题。所以笔者自问自答几个问题:
1 你觉得自己的代码看起来干净舒适吗?
2 命令式编程真的好吗?
3 怎么降低编码成本问题?
4 怎么解决程序耦合度过高的问题?
个人觉得如果能对上面的4个问题做一个诠释,也许我们的编码水平的瓶颈问题得以解决。当然这只是最基础的也是最重要的,更高层级的编程思想会在下文中再次进行阐述。
”
01
—
编程规范
关于编程规范太重要了,包括我们对于变量的命名,包名的命名也应当统一英文,避免中文式英文,这也可能意味着之后的你愿不愿意读自己写的代码。个人推荐一个github项目,谷歌开发规范。https://jervyshi.gitbooks.io/google-java-styleguide-zh/content/。
正确示例
注释编写到位,格式统一,包括空格。
代码分段落划分层次。
将需要标注关联类进行链接进来方便查看。
编写好javadoc方便维护时阅读,最好将自己编码的思路编写进去。
将可能出现的异常进行标注。
变量命名做到无拼音,无中式英文。
02
—
命令式编程
个人所理解的命令式编程即记流水账,流水账越多越不好去维护,编写正确的程序我们应当给程序的原子化操作进行分组,分阶段,分状态,分主次….等等。在这个拆分的过程中可以简单抽象出两个概念,第一个概念是保存这些操作的存储器,第二个概念是执行器,负责联动每个模块进行制定次序执行。这样去做会降低命令式编程的概率,也能将程序进行原子化封装,我们封装的原子化的东西越多,越利于程序扩展,因为在调度层我们自由组装的可能性会大大增加。举个小例子,在用户登录一个系统的时候,登录操作为主,初始化其他信息为次,在主业务代码里面我们只需要关心怎么做好登录逻辑,而次要代码我们可以封装一个一个有序的List的存储次要操作,然后再进行定义执行器执行List中的每个次要操作,我们也要分状态,登陆成功一种状态,失败一种状态,执行器需要按照每个模块的状态进行决定是否需要执行或者事后需要调整执行次序。比如Spring中的AOP,AOP的基层改变了java的类加载机制,虽然降低了性能,但程序的耦合度降低了。
03
—
编码成本
工作中的60%以上几乎全是机械化工作,怎么在机械化操作中解放自己?这也就是个人所提到的编码成本问题,愿景是最少的代码,实现更容易维护的功能。比如某程序要做一个数据库数据加密的功能,如果项目已经成型,第一种办法就是先找出所有存数据和取数据的地方,分别做加密解密,这种办法出错率太高,成本太高。第二种办法是我们如果使用了mybatis或者mp框架的情况下,我们可以使用拦截器做代理,查询的数据进行解密,存储的数据加密,这样子就实现了一个加解密的功能,成本极低,也易维护,那如果没有使用这种框架怎么办?怎么给SQL做代理,个人的建议是阅读对应数据库的driver的源码,使用包装器的模式做一个代理,那怎么知道需要对那些数据加解密?个人建议是使用注解形式标明加密字段。因为在java中一个pojo对应一个表格,我们在查询哪些表格完全可能通过表名称或者其他手段进行获取,
04
—
程序解耦
事实上,解耦是个相对的概念,并不存在完全程度的解耦。从上述可以看出,其目的都是转移了耦合点,通过耦合点的转移,使得原先的对象之间耦合性得到了降低。而之所以可以去转移,原因是当发生实现更换时,新的耦合点更方便修改,并且影响范围更小。那么,究竟什么时候,我们可以大声宣称对象之间实现解耦了呢?通常而言,当发生实现更换时,达到如下之一的要求即可:
1 不需要重现编译代码,而是通过修改配置文件或者系统属性即可达到目标。
2 客户端的代码不需要修改并重新编译,例如只需要修改或者更新库文件即可。
最生动的一个例子就是观察者模式,也就是大家平常所见到的mq类似模式,数据提供端不需要知道消费端的逻辑结构,消费端也无需知道数据提供端的逻辑。观察者模式涉及到事件,事件源,监听器,监听器通过事件进行解析具体逻辑。而事件源则像阻塞队列事件,笔者在设计snackDB数据库的时候数据落盘的代码使用观察者模式实现,即每一个修改数据的操作都会产生一个刷盘事件,产生刷盘事件之后会将事件扔到事件源中进行存储,监听器通过事件源阻塞队列中拿到事件,根据事件中的具体数据进行数据落盘。这样就做到了转移耦合点。