Bar*_*son 7 java architecture design-patterns jpa
我正在根据Clean Architecture重构微服务:
框架应该在最顶层。所以我使用了Adapter Pattern和Dependency Inversion把它放在
org.springframework.data.repository.CrudRepository了最上层。但我怎么能使用@Entity(从Ĵ AVA P ersistence一个PI)坚持我的实体,如果实体是在中央和框架是在极其层?
示例:演示实体:
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
@Entity
public class Demo implements Serializable {
@Id
@GeneratedValue
private long id;
@NotNull
private String foo;
}
Run Code Online (Sandbox Code Playgroud)
GenericRepostioryInterface(在用例层)
public interface CrudRepositoryInterface<S,T> {
public <U extends S> U save(U u) ;
public <U extends S> Iterable<U> saveAll(Iterable<U> itrbl) ;
public Optional<S> findById(T id) ;
public boolean existsById(T id) ;
public Iterable<S> findAll() ;
public Iterable<S> findAllById(Iterable<T> itrbl) ;
public long count() ;
public void deleteById(T id) ;
public void delete(S t);
public void deleteAll(Iterable<? extends S> itrbl) ;
public void deleteAll() ;
}
Run Code Online (Sandbox Code Playgroud)
一些用例:
@Autowired
private CrudRepositoryInterface<Demo,Long> demoRepository;
...
private void deleteAll(){
this.demoRepository.deleteAll();
}
...
Run Code Online (Sandbox Code Playgroud)
适配器(数据库层)
public interface DemoRepositoryAdapter extends CrudRepository<Demo,Long>,CrudRepositoryInterface<Demo,Long>{
}
Run Code Online (Sandbox Code Playgroud)
注入配置(我也把它放在数据库包/层中)
@Configuration
public class InjectRepositoryConfig {
@Bean
public CrudRepositoryInterface<Demo,Long> animalOwnerRepository(@Autowired DemoRepositoryAdapter demoRepositoryAdapter){
return demoRepositoryAdapter;
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,这工作正常,但我不确定如何从核心层中删除/替换/重构 JPA?
我认为这里的普遍混淆是由于术语实体的重载,它在不同的上下文中具有不同的语义。在 JPA 的上下文中,实体是表示表和 ORM 中行的持久性抽象。在 Clean Architecture 的上下文中,Entity 是业务域抽象,完全独立于持久性。
它们可以在 Clean Architecture 中共存,但它们各自都有不同的用途。尝试在您的业务领域实体中组合它们并利用 JPA 功能违反了清洁架构的原则,并将您的领域与您的持久性实现结合起来。
小智 6
如果你真的想遵循干净的架构,那么你的域类中不应该引用外部库。为了克服这个问题,可以采用以下几种策略:
这种方法的缺点是,您的域仍然需要实现Serializable,并且其中大多数需要为其字段设置 setter/getter,或者强制 hibernate/jpa 忽略 Java 限制并访问私有字段。此外,您可以对 XML 无法使用的注释执行某些操作,或者解决方法存在问题。它可以工作,但您的域层仍然看起来像简单的 DTO。
最后一种方法使您的项目很容易改变。您可以随时更改持久层,但这样做需要集成一个全新的数据存储层。假设您想更改为 cassandra,您将需要一个新的 DTO DemoDataCassandra、它与 Demo 之间的映射器、映射的新注释等。