文档章节

软件开发中的形式主义--基于接口的编程

loveczp
 loveczp
发布于 2013/09/20 12:18
字数 1101
阅读 493
收藏 17

形式主义说白了就是徒有其表,或金玉其外败絮其中。用我的话来说就是装逼。

程序猿相对来说是个比较实在的群体,通常都低调朴素踏实可靠。但其实这只是表象,这群人装起逼来也让人不忍直视,这群人装起逼来不易被发现,很少被曝光,但这完全不影响他们装逼的恶心程度。程序猿每天的工作就是写代码,所以他们装的逼通常都与代码有关,显然这种装逼不为行外人理解。

装逼第一弹,面向接口的编程。

有过java编程经验的人,应该没人没听说过这个东西。面向接口的编程是要解决“实现和使用”相分离的问题,比如编写数据库访问的代码时,只需要关心jdbc的接口就完了,至于jdbc接口的mysql或oracle实现我们可以不关心,再比如,我们编写web代码时,我们只需要关心servlet接口就好了,至于servlet的tomcat实现或jetty实现我们可以不关心。还有比如collection接口,输入输出流接口等等。

很显然这样的基于接口的编程有两个好处,

  1. 可以轻松的更换实现。比如写Web代码的时候,本机调试用jetty,这样启动快和IDE能很好集成,而线上运行用jboss,运行快,稳定。

  2. 降低学习成本。比如写web代码是只需要了解servlet接口规则就好,编写数据库访问,只需要了解jdbc接口就好。这样避免学习oracle或mysql特定api的必要,只需要学习jdbc  api就可以了。


------------ but  分割线  --------------

从上面可以看出面向接口编程是一种非常好的实践。但这么好的编程实践到了程序装逼犯那里就被他们糟蹋蹂躏了。他们一听说这么个好东西就到处用,不用就好像不足以显示他们的专业和高深。

一般的项目都会有个数据库访问层也就是DAO层,还有一个业务逻辑层或者叫服务层service层。相关的代码写在dao,service目录里面就好了,但是神奇的是dao,service下面都会有一个名字为impl的目录。实际情况是dao,service目录下只有接口,而实际的实现都在impl下面。

于是会出现下面的目录结构

├─dao
│  │  UserDao.java
│  │
│  └─impl
│          UserDaoImpl.java
│
└─service
    │  UserManageService.java
    │
    └─impl
            UserManageServiceImpl.java

而且更神奇的是我接手过的5、6个项目都是这样的目录结构,换了一家公司之后发现还是这样的目录结构。问了一下项目负责人,为什么必须先定义接口然后把实现放在另外一个类里面。他们给我的答案是

  1. 申明接口,可以让使用方明确知道,哪些方法是给外部用的,哪些是给内部用的。   我去,这件事情不是访问修饰符public  private protected  该干的事吗? 怎么轮到接口去干去了。

  2. 以后的实现类可能会替换或修改,申明了接口可避免上层代码的变动。我待过的这些项目中,没有一个有替换service或dao实现类的需求,通常情况都是实现类和接口一起改,或者是实现类方法内部修改。

但是我想他们真正这样做的原因是,大家都在这么做,所以他们随大流而已,或者只是想实践一下面向接口的编程的方法,为了实践而实践。

其实这么做完全没有必要,这么做只能带来下面的问题,

  1. 增加代码行数,

  2. 增加修改成本(增加一个方法要修改两个类)

  3. 增加目录里的文件数量

求求大家以后别这么不分青红皂白的使用接口,行么。这让我想起了哪些很爱带粗金链子,镶金牙的山西煤老板,本来他们是为达到汤姆克鲁斯的效果,但哪些金链子金牙齿让他们达到的是城乡结合部洗剪吹的效果。

© 著作权归作者所有

共有 人打赏支持
loveczp

loveczp

粉丝 13
博文 7
码字总数 6427
作品 1
武汉
程序员
私信 提问
加载中

评论(11)

xz2001
xz2001

引用来自“loveczp”的评论

引用来自“xz2001”的评论

你不是爱因斯坦,不要总以为自己才是对的。你不喜欢可以换种方式。既然你自己都说接了几个项目都是这种结构,难道还说明不了优点么?

我没有总认为自己是对的,但我起码我觉得这件事情我还是对的,如果不对请用强大的逻辑和充足的证据来说服我。
对不对这事,不是人多说了就算数的。

你的文章标题就具有片面性!
p
peterzhai
只能说你接触的都是小项目……没有体现出作用……存在即合理……
loveczp
loveczp

引用来自“lfl”的评论

接口配合配置文件才能体现其强大,更改配置就能动态更换实现,不用重新编译原有程序,实现热插把啊

说的有道理。

但貌似我说的跟您说的不是一回事。
lfl
lfl
接口配合配置文件才能体现其强大,更改配置就能动态更换实现,不用重新编译原有程序,实现热插把啊
淡茗
淡茗

引用来自“loveczp”的评论

引用来自“淡茗”的评论

Service定义成接口还是有必要的,跨包引用时就不能用访问域修饰符来限定了。还有现在是本地实现,说不定哪天改成RPC了,这时接口的作用就体现出来了。

“跨包引用时就不能用访问域修饰符来限定” 为什么???
就算是改用rpc,直接更换一个实现类就可以了,为什么一定要加个interface在中间插一杠子。

跨包引用必须是public,这样方法就暴露了。rpc是将接口提供给远程调用者,这样的场景是必须用接口的,接口并不是像你说的一无是处,只是凡事都有个度,别滥用
loveczp
loveczp

引用来自“淡茗”的评论

Service定义成接口还是有必要的,跨包引用时就不能用访问域修饰符来限定了。还有现在是本地实现,说不定哪天改成RPC了,这时接口的作用就体现出来了。

“跨包引用时就不能用访问域修饰符来限定” 为什么???
就算是改用rpc,直接更换一个实现类就可以了,为什么一定要加个interface在中间插一杠子。
loveczp
loveczp

引用来自“ForJustice”的评论

同感!

知音啊
loveczp
loveczp

引用来自“xz2001”的评论

你不是爱因斯坦,不要总以为自己才是对的。你不喜欢可以换种方式。既然你自己都说接了几个项目都是这种结构,难道还说明不了优点么?

我没有总认为自己是对的,但我起码我觉得这件事情我还是对的,如果不对请用强大的逻辑和充足的证据来说服我。
对不对这事,不是人多说了就算数的。
淡茗
淡茗
Service定义成接口还是有必要的,跨包引用时就不能用访问域修饰符来限定了。还有现在是本地实现,说不定哪天改成RPC了,这时接口的作用就体现出来了。
xz2001
xz2001
你不是爱因斯坦,不要总以为自己才是对的。你不喜欢可以换种方式。既然你自己都说接了几个项目都是这种结构,难道还说明不了优点么?
一个基于可重用构件的软件开发过程模型

摘要:基于构件的开发(CBD)观念已广泛应用于软件开发中,便于构件的重用。众所周知的CBD体系结构有 ActiveX, CORBA, RMI以及 SOAP 等。文章主要通过与传统软件开发方法的比较研究支持基于C...

青夜之衫
2017/12/05
0
0
嵌入式系统定制开发的分层与专业的分类

嵌入式系统这个名词还是比较难以准确定义的,一般把“用于控制、监视或者辅助操作机器和设备的装置”称为嵌入式系统,系统包括一系列软硬件设施等,比如:手机的系统开发(Android、IOS等),...

gunser
05/31
0
0
读书笔记:A Philosophy of Software Design (二)

接着上次的分享 设计两次 这里“设计两次”的意思是无论设计一个类,模块还是功能,在设计的时候仔细思考,除了当前的方案,还有那些其它的选择。在众多设计中比较,列出各自的优缺点,然后选...

naughty
09/02
0
0
[翻译]使用PHPUnit进行测试驱动开发

发表在我的博客:http://starlight36.com/post/tdd-with-phpunit 翻译自PHPUnit官方文档 单元测试在软件开发过程中举足轻重,测试先行编程(Test-First Programming),极限编程(XP)和测试...

烫烫烫烫烫烫
2013/08/04
0
0
Java 程序员的错

编者注:可以喷语言,但不要搞人身攻击! BTW:我也是一名 Java 程序员,哈哈! Java程序员是有问题的。我使用Java编程已经有10多年的历史。同时,我还有过大量的使用其它语言开发的经历,比...

oschina
2014/07/29
7.8K
92

没有更多内容

加载失败,请刷新页面

加载更多

Go 使用channel控制并发

前言 channel一般用于协程之间的通信,channel也可以用于并发控制。比如主协程启动N个子协程,主协程等待所有子协程退出后再继续后续流程,这种场景下channel也可轻易实现。 场景示例 总结 ...

恋恋美食
22分钟前
1
0
Apache Flink 漫谈系列 - 持续查询(Continuous Queries)

摘要: 实际问题 我们知道在流计算场景中,数据是源源不断的流入的,数据流永远不会结束,那么计算就永远不会结束,如果计算永远不会结束的话,那么计算结果何时输出呢?本篇将介绍Apache Fl...

阿里云官方博客
26分钟前
3
0
斐波那契堆的理解,节点mark属性和势函数

斐波那契堆 看了好多博客,都是照搬算法导论的内容,没有自己的理解,比如为什么有mark属性,势函数的作用,以及为什么叫斐波那契堆,下面说说鄙人的理解。 势函数 势函数是根节点个数加上2...

杨喆
27分钟前
2
0
NIO源码详解

阻塞io和无阻塞io: 阻塞io是指jdk1.4之前版本面向流的io,服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒 ...

沉稳2018
31分钟前
0
0
如何把已经提交的commit, 从一个分支放到另一个分支

在本地master提交了一个commit(8d85d4bca680a5dbcc3e5cfb3096d18cd510cc9f),如何提交的test_2分之上? git checkout test_2git cherry-pick 8d85d4bca680a5dbcc3e5cfb3096d18cd510cc9f......

stephen_wu
35分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部