2010-01-19 4 views
17

나는 빈혈 도메인 모델을 중심으로 내 애플리케이션을 디자인하기 위해 많은 리치 객체를 가지고 있었고, 커다란 트랜잭션 인식 서비스 레이어에 주입했다. 이 패턴을 트랜잭션 스크립트라고합니다. 절차 코드로 이어지기 때문에 좋은 방법으로 간주되지 않으므로 도메인 중심 디자인으로 이동하고 싶었습니다.도메인에서 구동되는 디자인과 스프링 환경에서의 트랜잭션

웹에서 기사 몇 편을 읽은 후 Chris Richardson의 Parleys에 대한 이야기를 듣고 POJO의 DDD 챕터 읽기에서 나는 큰 그림을 얻었습니다.

문제는 내 응용 프로그램에서 트랜잭션을 구성하는 방법입니다. 그의 책 Chis 리처드슨 상태 :

프리젠 테이션 계층은 I 이전 장에서 설명 된대로 외관을 통해 직접 또는 간접적으로 도메인 모델을 호출하여 사용자의 브라우저에서 HTTP 요청을 처리 중 하나 POJO이다 또는 EJB. InfoQ article 상태에

지금까지 좋은

하지만 Srini Penchikala :

일부 개발자들은 가난한 디자인입니다 DAO 클래스의 트랜잭션을 관리하는 것을 선호합니다. 따라서 트랜잭션이 여러 도메인 객체로 확장되는 유스 케이스를 관리하는 유연성을 제공하지 않는 너무 세밀한 트랜잭션 제어가 발생합니다. 서비스 클래스는 트랜잭션을 처리해야합니다. 이 방법은 트랜잭션이 여러 도메인 객체에 걸쳐있는 경우에도 대부분의 사용 사례에서 Service 클래스가 제어 흐름을 처리하므로 서비스 클래스가 트랜잭션을 관리 할 수 ​​있습니다.

그래, 내가 올바르게 이해한다면, 저장소 클래스는 트랜잭션이 아니어야한다. 서비스 계층 (이제는 훨씬 더 얇은)은 트랜잭션 스크립트 패턴으로 사용되기 때문에 트랜잭션 적이다. 그러나 도메인 객체가 표현 계층에 의해 직접 호출되면 어떻게 될까요? 내 도메인 객체가 트랜잭션 동작을 가져야한다는 의미입니까? Spring 또는 EJB 환경에서이를 구현하는 방법은 무엇입니까?

이것은 나에게 이상한 것 같아서 누군가가 분명히 밝히면 행복 할 것입니다. 고맙습니다.

+0

모든 종류의 DI + ORM을 고려하기 때문에 자바 태그를 추가했습니다. (자바뿐만 아니라 귀하의 컨텍스트도 마찬가지입니다.) – Bozho

답변

8

DDD를 Spring과 Hibernate에 적용하는 개인적 취지는 지금까지 Stateless 트랜잭션 서비스 계층을 가지며이를 통해 도메인 객체에 액세스하는 것입니다. 따라서 도메인 모델은 트랜잭션에 대해 전혀 알지 못합니다. 서비스에서 전적으로 처리됩니다.

보기에 도움이 될 수있는 example application이 있습니다. 에릭 에반스가 그것을 창조 한 것처럼 보입니다.

+0

답변 해 주셔서 감사합니다. 예를 들어 엔티티를 유지하려면 service.save (entity)를 호출합니다. 내 목표는 entity.save()를 호출하여 엔티티를 지속시키는 것입니다 (http://groups.google.ca/group/EtoE/browse_thread/thread/cac1eafe15f06f5b/ – semberal

+0

). 맞습니다. 내 코드는 않습니다. service.save (엔티티)와 같은 것들. 'entity.save()'접근법에 신경 쓰지 않고 내가 링크 된 기사를 읽고 설명과 함께 내 대답을 편집 할 것입니다.) –

+1

service.save (엔티티)의 경우 도메인 개체? – Bozho

5

this extremely useful blog-post을 참조하십시오. Spring 및 JPA의 기능을 잃지 않으면 서 원활한 DDD를 수행하는 방법을 설명합니다. 그것은 @Configurable 주석을 중심으로합니다.

이러한 문제에 대한 제 의견은 약간 비평영입니다. 빈혈 데이터 모델은 실제로 잘못이 아닙니다. 하나의 객체에 데이터 + 연산이있는 대신 두 개의 객체가 있습니다. 하나는 데이터가 있고 다른 하나는 연산이 있습니다. DDD를 하나의 개체로 볼 수 있습니다. 예를 들어 DDD를 만족시킬 수 있지만 사용하기 쉽도록 물리적으로는으로 구분됩니다. 논리적으로 그들은 동일합니다.

예, 이것은 캡슐화를 중단하지만 목표를 달성하기 위해 '마법'(aop + 자바 에이전트)을 사용하지는 않습니다.

트랜잭션의 경우 - 트랜잭션 전파라고하는 것이 있습니다. Spring은 @Transactional(propagation=Propagation.REQUIRED)으로 지원한다. See this, point 9.5.7. 트랜잭션을 여러 오브젝트의 여러 메소드로 확장하려면 전달 속성을 적절하게 변경할 수 있습니다.

적절한 경우 서비스 레이어에 @Transactional을 사용할 수도 있지만 "저장"과 같은 간단한 단일 단계 작업을 사용하려는 경우 많은 보일러 서비스 클래스가 도입 될 수 있습니다.

+0

안녕하세요, 답변 해 주셔서 감사합니다. 나는 이미 그 기사를 읽었습니다. 제안 된 첫 번째 두 가지 해결책은 용납되지 않습니다. 나는 최대 절전 모드 인터셉터를 가진 해결책을 좋아하지 않는다. 왜냐하면 (내가 이해할 수있는 한) 최대 절전 모드로 구현 된 콩의 주입 만 해결하기 때문이다. AspectJ 솔루션은 꽤 괜찮은 것처럼 보인다. @Configurable 클래스에서 트랜잭션을 사용하는 방법 만 알아 내면됩니다. 그러나 내 도메인 모델이 트랜잭션이어야하는지 여부와 상관없이 질문에 대답하지 않습니다. 그렇지 않은 경우, 거래는 어디에 있어야합니다. – semberal

+0

거래에 관한 단락을 추가했습니다. – Bozho

+0

나도 알아,하지만 @Configurable 클래스가 @Transactional에서 작동하지 않는다는 내용의 기사가있다. – semberal

0

DDD와 Spring을 시작하는 쉬운 방법 중 하나는 Spring Roo과 함께 제공되는 샘플 앱 중 하나를 살펴 보는 것입니다. Roo는 DDD 원칙을 따르는 코드를 작성합니다. 그것은 AspectJ에 크게 의존한다. SpringSource의 거물 인 Ramnivas Laddad (in this talk)가 제안한 아이디어를 바탕으로 구현 된 것으로 판단됩니다.

관련 문제