您在Spring MVC应用程序中使用什么命名约定?
我坚持在弹簧应用程序中弄清楚服务层的一个好的命名约定。 对于服务层中的每个类,我首先编写它应该实现的接口,然后编写实际的类。 所以例如我有以下接口:
public interface UserAccountManager{ public void registerUser(UserAccount newUserAccount); public void resetPassword(UserAccount userAccount); ... }
然后是实现类…
在这里有什么错误是UserAccountManager是一个实现类的好名字,所以我不得不给它一个愚蠢的名字,如SimpleUserAccountManager或UserAccountDbManager。 到目前为止,您使用的一些惯例是什么? 把实现类放在一个不同的包中并给它们起一个和接口一样的名字是个好主意? 你还有什么想在以Service结尾的名字上使用以Manager结尾的名字?
Spring本身提供了接口的通用名称,然后根据实现的细节命名类。 这是一个想到的例子:
interface: Controller abstract classes: AbstractController, AbstractCommandController, SimpleFormController, MultiActionController
我不认为像SimpleUserAccountManager或UserAccountDbManager这样的名称是愚蠢的,因为它们传达了有关pipe理器/服务的实现的一些信息。
我觉得愚蠢的是在实现类中添加“Impl”后缀的常见约定:
my/package/UserAccountManager my/package/impl/UserAccountManagerImpl
有些人喜欢这个。
这是我们使用的:
- XxxDAO(数据访问对象) – 负责直接与EntityManager,JDBC DataSource,文件系统等进行交互。应该只包含持久性逻辑,如SQL或JPA-QL,但不包含(或尽可能less的)业务逻辑。 只能从pipe理者访问。
- XxxManager – 在业务级别pipe理实体 ,通常执行CRUD操作,但添加所需的业务逻辑。
- XxxService – 业务逻辑所在的层。 应该尽量“简单地”说“串”,“整数”等。
- XxxController – UI交互层。 只应该对服务说话。
- XxxUtilities / XxxUtils – Helper无状态方法不应该依赖于系统中的任何服务。 如果您需要这样的依赖性,请将实用程序类转换为服务或将服务结果作为参数添加。
为了实现,我们添加Impl后缀(XxxServiceImpl),将其从接口中区分出来,如果有几个实现或者我们想要添加额外的信息,我们将它添加为前缀(JdbcXxxDaoImpl,GoogleMapsGeocodingServiceImpl等)。 这些类的名字有点长,但是非常具有描述性和自我logging。
对于你给的例子,我将使用反映类如何执行操作的实现名称,如HibernateUserAccountManager,JPAUserAccountManager或JDBCUserAccountManager等,或者也许只是UserAccountManagerDAO。
class级名字本身是以“经理”还是“服务”结尾,这本身显然并不重要。 一般来说,重要的是名字准确地传达了正在build模的东西。 这就是问题的症结所在:“服务”或“经理”并不是我们试图在软件对象中build模的真实世界的对象。 相反,它们是我们收集大量方法的地方,这些方法不能满足我们需要/想要build模的任何对象的责任。
就我个人而言,我更喜欢“服务”,但只是因为“pipe理者”似乎是一个可以模拟的东西,也就是说,我们的“pipe理者”所代表的可能是现实世界的pipe理者。 但是这一点完全是学术性的,我立即承认这没有实际的区别。
真正重要的是通常比这样的细节更基本:要有一个被所有参与发展的人所熟知的模型。 如果我的经验是什么,那很less如此。 对于那些询问“经理人”还是“服务人员”是正确的比喻的人,我的build议是:翻转硬币,确保每个人都知道这个惯例,并花时间思考和讨论重要的事情!
我觉得Service vs. Manager命名后缀纯粹是一种偏好。 “服务”唯一导致我们混淆的时候,就是我们也有Web服务位于服务层之上。 在一些项目中,我们只是将Web服务类作为经纪人来引用,因为他们所做的只是将Web服务调用翻译成代理服务或调用服务层。
我同意kgiannakakis后缀“Impl”你的实现不是一个好方法。 我也遇到了编码的最佳做法,提到不这样做。 在抽象之后命名界面是公认的最佳实践。 命名实现类后,接口与其目的或types的一些指标,如kgiannakakisbuild议,似乎是普遍接受的方法。
当我们有基于Web服务的DAO和基于ORM的DAO时,我们使用包和类名来区分实现类和它们的接口。 我认为把这些实现放在不同的包中,取决于你在包里有多less个类,它们实现的方式有多不同,以及你想要分割多less个东西。
您也可以命名接口IUserAccountManager(例如,在Eclipse RCP中使用此约定),然后使用UserAccountManager作为默认实现。
对我来说,一个服务类是关于实现一个用例,所以我根据服务代表什么样的用户来命名它。 因此,如果我有一个具有不同angular色的应用程序,比如Customers,Order Fullfillment people,Data entry people和Admins,那么我可能有一个CustomerService,一个OrderFulfillmentService,一个DataEntryService和一个AdminService。 我认为根据所获取的数据types来命名服务是一种反模式。 所以猜测UserAccount操纵将是一个pipe理员的领域,我可能会称之为“AdminService”。
相关的经理和服务之间的区别:我会说尽可能长的一层用于业务逻辑(服务层或pipe理器层)。
一旦这个层变得复杂(假设你使用了服务),你可以添加pipe理员负责委派一个服务或另一个服务,但是保持业务逻辑在服务之内。
所以我会保持服务简单,使用经理来pipe理服务,并保持业务逻辑内的服务。
我也同意避免实现的Impl后缀和避免接口的后缀。 作为一个例子,命名接口“Controller”并命名实现“SimpleController”或“UserController”对我来说听起来更好。
假设这些是用于REST服务的,我认为你的URI命名约定比底层实现服务的名字更重要,因为后者在很大程度上不会被客户看到。 当然,你想要内部一致的命名,但它不是至关重要的。
我们使用的一些REST指南: http : //soaprobe.blogspot.co.uk/2012/10/soa-rest-service-naming-guideline.html (我的博客)