尴尬的COC


Convention Over Configuration大家都已经耳熟能详了, 这东西好不好那? 好, 绝对是好, 不过, 还要看用的人到底怎么用, 或者说是否真的理解了它到底是怎么回事, 说两三个小场景…

发现某个框架虽声称COC是其主打特色, 但某些功能模块在实现的时候却没有将COC执行彻底, 比方说, 大部分情况下可以根据URL取得的信息, 现在依然要求开发人员在某个配置文件中进行统一配置, 虽然这个功能侧重就是统一配置和管理某些URL映射, 但key和value都一样的情况下, 完全可以让框架根据某一Convention自动提取, 而没必要重复配置这些key和value的值, 实际上,只有说key和value不同的时候,进行一下配置就可以了, 你说,这里的COC尴尬不?

JUnit4之后引入了@Test用于标注测试用例的测试方法, 这东西好不好? 好, 让你可以在一处管理所有的信息, 而且像强类型支持, IDE的支持等等好处都可以享受到, 再也不会因为把testXXX拼错成tsetXXX之类并导致测试用例的“怪异”行为而头疼了,不过, 事情真的像宣称的或者说看起来的那么美嘛? 你用@Test标注的测试方法依然需要声明吧?测试方法依然需要有一个表意清晰的名称吧? 按理说, 每个测试方法的名称以test开头不就是个Convention嘛? 现在使用@Test代替这个Convention, 那COC是不是又感觉很尴尬呀? 我怎么就觉得直接敲方法名要比敲方法名和@Test这个Annotation更便捷那? 拼写错误? come on, 数数大家还是会的吧? 上一次跑了12/12个测试方法,你添加个新的测试方法之后,run的时候还是12/12, 你难道不知道问题出在哪里嘛?

部门另一个架构师开发了个GenericDao框架,用于简化大家的日常开发,提高开发效率, 好东西吧? 绝对好东西, 不过, 在用的时候,发现点儿不方便的地方。当然了,这个不方便不是框架设计者本身的问题,可能更多是局限于现有的技术前提条件。其实, 几年前就有过类似的想法, 打个比方, 假设我声明如下接口定义:

public interface XXXDao<T>  {  
    List<T> findByProperty1AndProperty2(String propertyOne, String propertyTwo);  
}

那么,按照我最初的想法, GenericDao框架内部就应该直接根据参数名称构建个map,然后传给sqlmap作为调用的参数(假设采用IBatis做数据访问),也就是说, 按照某种Convention, 方法参数的名称与sqlmap中的参数名称是一一对应的, 这样,开发人员只需要声明个数据访问方法就可以了,简单直接, 不是嘛?

不过那,现实是残酷的,呵呵,编译的时候, 参数名称这样的信息在编译的时候, 默认是忽略掉的, 这也就是为啥通过反射API只能得到个参数类型,而得不到参数名称。虽然新的java版本一直吵吵着要加入这个信息,但目前来看,还是不行,所以, 我们就只能变通一下, COC中的第一个C(Convention)搞不定了, 只能启用一下第二个C(Configuration), 通过某个Annotation,比如@Param(“name”), 来告知框架怎么关联方法调用与sqlmap调用参数之间的映射关系。你说, 这里的COC尴尬不?我觉得最尴尬了,绕都绕不过去, 除非你再加个Post-Compile的过程或者Pre-Compile的过程, 在Java Source的基础上做做手脚,然后带到编译后的成果物中去(class文件中,或者自动生成的某种配置信息中)。

不过那,最理想的还是从“根儿”上解决这个问题, 你JavaClassFormat都把三个规则中的两个默认 1启用了,为啥就不启用这最后一个 2那?如果怕编译后的class文件膨胀,那咱权宜一下,只对interface类型做这个事情好不?

嗯, 就说这么些了, 套用当下已经用烂了的一句话, “COC自己其实一点儿都不尴尬,只是寂寞”, 哈哈


  1. line number tables for each method和the name of the source file↩︎

  2. local variable tables for each method)↩︎


>>>>>> 更多阅读 <<<<<<


「福强私学」来一个?

「福强私学」, 一部沉淀了个人成长、技术与架构、组织与管理以及商业上的方法与心法的百科全书。


开天窗,拉认知,订阅「福报」,即刻拥有自己的全模态人工智能。

订阅「福报」