本文基于对一般编程习惯的一些个人见解,并不涉及方法论层面. 但是,只要经验丰富且实用,它也可能会吸引许多不同的观点. 让我们从熟悉的界面编程开始
在最初的软件设计中,接口编程的概念似乎是宇宙的真相(在软件世界中没有真相部门),对此的解释是
具体类包含实现细节,而抽象类仅表示概念
当然非常合理和权威.
但是界面的前提是什么?在设计与外部系统交互的API的情况下. 例如,如果您想向外界提供用户注册界面,则可以在该界面上共同同意
无效寄存器(字符串用户名,字符串密码)抛出RegistrationException;
并且此接口应该是稳定的,然后每个实现或完成呼叫细节,即使实现未完成,也可以通过Mock对呼叫端进行单元测试.
但是,在实践中,对面向接口编程的理解很容易成为任何非工具类. 数据类首先声明一个链接到单个实现类的接口,并且该类的结构类似于以下内容
.
├──道
│├──UserDao.java
│└──UserDaoImpl.java
└──服务
├──UserService.java
└──UserServiceImpl.java
使用Java时,用于接口编程的接口等同于Java的接口. 实际上,此接口不是另一个接口. 有三个原因
此UserDao界面实际上并未与外界交互. 它可能是与外界交互的RESTful API,并且此RESTful API是接口编程的接口. 通常,接口或抽象类表示存在多个实现,而实现类以UserDaoImpl编写的命名方法基本上承认它是唯一的实现. 从语义上讲,UserDao和UserDaoImpl之间没有区别. 将UserDao编写为IUserDao或UserDaoIf是否更难看?如果说UserDao下的两个实现是DbUserDao和FileUserDao,则据说过去UserDao和UserService并未与外界交互,因此它们的定义不稳定. 例如,在UserDao中预定义了一种方法
列表<用户> findUsersByFirstName(字符串名字);
它也在UserDaoImpl中实现. 后来发现实现中还需要其他方法
列表<用户> findUsersByLastName(字符串姓氏);
因此,我在UserDao界面中添加了此新方法,后来又实现了更多方法,然后继续将方法添加到UserDao界面中. 在这种情况下,即使将UserDao视为一个接口,我们所做的也不是先定义该接口,然后再实现细节. 但要让接口根据实现需要任意发展. 随着时间的推移,将不可避免地导致UserDao中的方法定义不足. 清晰而混乱,不会是它的界面.
因此,由于UserDao不是外部接口,并且只有一个实现,所以为什么不创建一个具体的类UserDao. 对于UserDao的实现,请编写足够的测试用例. 如果UserDao和UserService都只有一个实现,则可以将它们放在同一包中,而无需区分dao和Service包. 类名暗示了他们的行为.
当将来UserDao需要不同的实现时,例如,原始UserDao基于针对接口编程,可以将其更改为DbUserDao,然后创建FileUserDao. 然后该考虑抽象两个公共接口或基类UserDao了. 请记住,通过足够的测试,您可以使用这种重构操作来完成任何您想做的事情. 同时,随着类关系变得越来越复杂,Dao和Service类也被适当地组织为dao和service包.
Spring为什么喜欢UserDao + UserDaoImpl的形式,这是Spring提倡的接口编程针对接口编程,所以即使只有一个实现类,标语中的接口也将更改为Java接口接口成为固定模式. 这也使该方法难以在IDE中导航. 直接单击该方法将转到接口方法,并且您需要按其他键. Spring可以使用动态代理来实现Java接口方面的原因可能还有另一个原因,而效率会更高. 如果直接是类,则必须使用CGLib修改字节码以实现方面. 实际上,无论如何,这是一次启动的行为.
Java中软件包的命名标准建议颠倒域名,后跟与项目相关的级别. 例如,如果在Peoplesoft的数据服务部门下有一个erp项目,则该项目中dao实现类的程序包名称应为
com.peoplesoft.dataservice.erp.dao
这可能是一个很小的项目,只有几个类别,每个类别都挂在这个长包装名称下. 不仅IDE或VCS中的导航很奇怪,而且感觉很沉重. 因此,程序包名称越向前,就越多余. 例如,如下所示,包前缀通常是负担.
─com.peopsoft.dataservice.erp
├──主要
├──UserDao
└──UserService
Java包命名标准考虑到该类可能在Internet上传播,因此,通过域名部分,您可以基本上确保类的完全限定名称是唯一的. 但是,绝大多数是什么?您的班级仅在此项目中使用,该部门中的其他项目或公司的其他部门都可以使用. 通过引用PlayFramework创建的项目包的名称很简单,即app {controllers,models,service}很简单,只有一个级别的包名称. 因此,我们还应该在可能被引用的类的范围内定义以下程序包名称
dao只适合这个项目
erp.dao可能会在该部门的其他项目中使用
dataservice.erp可能会被我们公司的其他部门使用
类似于从私人到公共的可见性,并且可以随时重建. 它并不仅是搬家,还可以说是世界上最伟大的建筑.
“此代码首先保留(先注释掉),以后可以使用. ”这不再是保留无用代码的原因,否则就不再使用版本控制系统. 这类似于旨在支持所有类型的过度设计,一般系统可以更改任何. 该代码应该看起来干净. 如果不需要,则必须立即将其删除. 如果将来真的有用,请向VCS索取. 这很重要. 预先标记它,然后再搜索.
有机会在编程中删除很多以前写的东西,实际上是一件很高兴的事情. 一般而言,这意味着我们已经找到了一种更简单的解决方案来完成这些艰巨的任务.
IntelliJ IDEA可以帮助我们识别从未调用的未使用变量或方法. 对于此灰色区域(Int??elliJ IDEA查找未使用的变量或以灰色显示的方法)可以被杀死. 尤其是数据类是最严重的. 遵循JavaBean的原始规范,在声明字段之后立即生成getter / setter方法,并且可能有很多getter / setter方法,甚至某些属性本身根本不感兴趣. 有必要吗? JavaBean是制作样板代码的不好的地方,并且JavaBean规范不再适用于函数式编程的不变性要求.
IntelliJ IDEA最令人讨厌的默认模板配置之一是它将自动向创建的文件中添加标题注释
/ **
*由Xxx在17年6月6日创建.
* /
IntelliJ IDEA是一种擅长重构的IDEA,但要注意敏捷IDEA,但这是默认设置. 每次看到这样的文件头注释,我都会感到有些哭泣和大笑. 这不是VCS管理的问题吗?创建者是否在写声明对代码负责或警告他人不要打扰我的代码?实际上,该代码归团队所有. 直接删除此标题注释似乎很不礼貌. 无论如何,通用代码已更改,最终它可能与创建者无关. 无论如何,每次我安装新的IDEA时,都首先删除了文件头模板.
来自Yanbin Blog的本文链接
本文来自本站,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-255129-1.html
……