在许多项目中,我所做的是定义一个“接口”,该接口不仅定义了字段,还定义了字段的“契约”。
此前在这个主题中提出的使用abstract
基类的建议有一个严重的限制。在Java的有限形式的多重继承中,具体类可以实现多个接口,但是...它只能extend
一个基类。这意味着基类方法仅适用于需要字段契约的一个接口。
以用例的方式来看,假设我想要为几种领域对象定义合同/接口:
- 带有到期日期的对象
- 带有审计跟踪(由谁创建,创建日期等)的对象
我可能有一些对象可以过期,但不需要审计跟踪。我可能有其他对象则相反:它们需要审计跟踪,但没有到期日期。
基类不允许在其中进行“挑选和选择”。任何基类都必须同时定义两者,或者您必须拥有所有组合的基类。
这是我的解决方案,它已经运作得非常好:我在接口中将setter和getter定义为抽象方法。您将实现留给具体类。
public interface Auditable<USER_TYPE> {
Instant getCreatedOn();
void setCreatedOn(Instant)
USER_TYPE getCreatedBy();
void setCreatedBy(USER_TYPE creator);
一个同时具有 Audtiable(使用
String
来标识用户)和 Expirable 特性的具体类应该长这样(我使用了 Lombok)。
@Getter @Setter
public AuditableExpirableObject implement Auditable<String>, Expirable {
private String createdBy
private Instant createdOn;
private Instant expirationDate;
这使得具体对象可以选择使用哪些接口。您确实需要定义字段,但通常在具体类型中定义它们并实现接口的契约是一件“好事”。一个例子是允许每个具体类确定以下内容:
- 数据类型(如
Auditable
的用户类型)
- 用于持久化或序列化的注释(Hibernate、JPA、Jackson、Gson等)
- 自定义初始化或保护级别