간단한 소프트웨어 디자인에 대한 질문이 있습니다. 데이터베이스에 유지되는 엔티티 (= 도메인 오브젝트)를 약간 불변으로 만들고 싶습니다. 수단 : 엔티티는 이어야하며은 서비스에서 생성되고 응용 프로그램의 모든 다른 부분은 게터 메소드 만 가진 interface
으로 작동합니다.스프링 서비스, 저장소, 엔티티 디자인 패턴 어드바이스가 필요합니다.
예 : myService.getMyEntityById(5)
MyService
가를 요청합니다 :
MyController
개체를 얻기 위해MyService
를 요청하는id=5
MyController
와MyEntity
를 검색 할root |--- service | |--- MyService.java | |--- MyServiceImpl.java | | | |--- MyEntity.java | |--- MyEntityImpl.java | | | |--- MyEntityRepository.java | | |------- web |--- MyController.java
아이디어 : 10
MyService
가MyEntityInterface
MyController
에 패키지 디자인을 반환 DB에서 개체를 가져 나의 첫번째 아이디어가 있었다
단순히 백팩 사용 MyEntityImpl
에서 kage로 보호되는 생성자를 사용할 수 있지만이 방법은 내가 사용하고있는 다른 라이브러리 (예 : Orika). 따라서 public
이어야합니다.
다음 아이디어는 MyEntity
인터페이스를 사용하는 것이 었습니다. 하지만 지금은 약간의 문제가 생겼어요 :
문제 :MyService(Impl)
라는 방법이 있습니다 updateMyEntityData(MyEntity e, Data data)
합니다. 이제는 내 서비스 내에서이 MyEntity
개체가 실제로 MyEntityImpl
의 인스턴스라는 것을 확신 할 수 없습니다. 물론 if(e instanceof MyEntityImpl) ...
을 할 수는 있지만 정확히 이 아니며을 원한다.
다음 문제는 :이 서비스 메서드는 MyEntityImpl
개체를 저장 및 검색 할 수 있지만 MyEntity
인터페이스를 처리 할 수없는 MyEntityRepository
을 사용합니다. 해결 방법으로 나는 추가 DB 쿼리를 할 수 있지만, 다시는 내가 원하는하지 내용은 다음과 같습니다
void updateMyEntityData(MyEntity e, Data data) {
MyEntityImpl impl = repo.findOne(e.getId());
impl.setData(data);
repo.saveToDB(impl);
}
내가 MyEntity
이 MyEntityImpl
의 인스턴스 인 것을 알고 때문, 불필요한 DB 쿼리이며이었다 이 서비스로 작성된 는 DB의 개체이어야합니다.
void updateMyEntityData(MyEntity e, Data data) {
MyEntityImpl impl = (MyEntityImpl) e;
impl.setData(data);
repo.saveToDB(impl);
}
요약 : 만 서비스가 MyEntityImpl
MyService(Impl)
나중에 MyEntityImpl
의 필드를 수정 할 수 있어야합니다 구성 할 수있다
- (의미 다른 가능성은 캐스트를 사용하는 것입니다 : 설정자가 있어야 함)
- 불필요한 DB 쿼리를 피하십시오.
미리 감사드립니다.
패키지 보호 설정? 상속보다 컴포지션을 사용할 수도 있습니다. 즉, MyEntityImpl 및 MyEntity를 래핑하는 클래스를 반환 할 수 있습니다. DAO가 유지하는 데 사용할 수있는 패키지 전용 'getMyEnitityImpl' 메소드를 제공해야합니다. [Lombok] (http://projectlombok.org/)을 사용하는 경우 [@Delegate] (http://projectlombok.org/features/Delegate.html) 코드의 3 줄에서이 작업을 수행 할 수 있습니다. –
' 이 문제를 과소 평가하고 이점을 거의 또는 전혀 얻지 않으면 서 복잡성을 도입해야합니다. 일단 개체가 생성되면 불변성의 다양한 이점이 발생합니다. 이러한 구성은이 작업과 관련하여 거의 중요하지 않습니다. 서비스를 강제로 도메인 객체를 생성하는 데 사용하면 응용 프로그램의 결합이 증가합니다. 왜냐하면 도메인 클래스에 의존하는 대신 서비스를 전달하게 될 것이기 때문입니다. 인터페이스와 impl 사이의 도메인 클래스를 비슷하게 분할하면 코드 기반의 복잡성이 추가되고 imho는 불필요합니다. –
흠 ... 내 초기 생각은 : * 그것없이, 일부 컨트롤러 또는 다른 서비스는'MyEntity'의 인스턴스를 생성하고'myService.updateMyEntityData (...)'*를 호출 할 수 있습니다. 그렇다면 전달 된 객체가 실제로 DB의 객체인지 또는 다른 곳에서 만들어진 객체인지 확실하지 않습니다. –