2010-04-08 2 views
21

저는 Hibernate in Action을 읽었으며 저자는 비즈니스 로직을 우리의 도메인 모델로 옮겨야한다고 제안합니다 (306 페이지). 예를 들어,이 책에 제시된 예제에서 우리는 Item, BidUser이라는 엔티티를 가지고 있으며 저자는 Item 클래스에 placeBid(User bidder, BigDecimal amount) 메소드를 추가 할 것을 제안합니다."비즈니스 로직 코드를 도메인 모델로 마이그레이션"하는 것이 좋은 생각입니까?

대개 비즈니스 로직을위한 별도의 레이어 (예 : Manager 또는 Service 클래스의 봄)를 고려하면 트랜잭션 제어 등이 가장 좋은 조언입니까? 우리 사업체에 비즈니스 논리 방법을 추가하지 않는 것이 낫지 않습니까?

미리 감사드립니다.

+1

확인 http://techblog.bozho.net/?p=180 – Bozho

+0

관련 스레드보기 : http://stackoverflow.com/questions/2333307/should-enterprise-java-entities-be-dumb –

답변

10

으로는

우리는

도메인 기반 설계 (DDD)는 도메인 모델 내에서 비즈니스 로직을 넣어야 상태 비즈니스 로직 (보통 전화 서비스 계층)에 대한 별개의 레이어가 말했다 . 그리고, 저를 믿으세요, 정말 좋습니다. 그것은 사용 사례가

@Service 
public class BidServiceImpl implements BidService { 

    @Autowired 
    private ItemRepository itemRepository; 

    public void placeBid(Integer itemId, User bidder, BigDecimal amount) { 

     Item item = itemRepository.getById(itemId); 

     if(amount.compareTo(new BigDecimal("0.00")) <= 0) 
      throw new IllegalStateException("Amount must be greater than zero"); 

     if(!bidder.isEnabled()) 
      throw new IllegalStateException("Disabled bidder"); 

     item.getBidList().add(new Bid(bidder, amount)); 
    } 

} 

전에

  • 그것은 정의 할 수 있습니다 트랜잭션 경계
  • 을 구동

    • 서비스 계층에 대한 작업 책에서 POJO에 의해 말했듯 도메인 기반 설계를 사용하는 경우

      @Entity 
      public class Item implements Serializable { 
      
          private List<Bid> bidList = new ArrayList<Bid>(); 
      
          @OneToMany(cascade=CascadeType.ALL) 
          public List<Bid> getBidList() { 
           return this.bidList; 
          } 
      
          public void placeBid(User bidder, BigDecimal amount) { 
      
           if(amount.compareTo(new BigDecimal("0.00")) <= 0) 
            throw new IllegalStateException("Amount must be greater than zero"); 
      
           if(!bidder.isEnabled()) 
            throw new IllegalStateException("Disabled bidder"); 
      
           /** 
            * By using Automatic Dirty Checking 
            * 
            * Hibernate will save our Bid 
            */ 
           item.getBidList().add(new Bid(bidder, amount)); 
          } 
      
      } 
      

      을 다음과 같이 9,

      도메인 로직은 비즈니스 로직은 바로 이곳에 살고 쇼입니다. 그러나 가끔 인 경우 서비스 계층 내에 비즈니스 로직을 정의하는 것이 좋습니다.

      "빈혈 도메인 모델"마틴 파울러에 의해이에서 가장 인용 기사의

    +3

    이유 아이템이 입찰을하기위한 규칙에 대해 알고 있습니까? 규칙을 처리하는 다른 모듈에이를 넣고 입찰을 진행하는 과정에서 추상화합니다. 나는 규칙을 진화시킬 때마다 Item 클래스를 변경하려고하지 않을 것이다. 하지만 여전히 그 Item.placeBid (...) 메서드 내부 규칙을 호출합니다. –

    +1

    흥미 롭습니다. 내가이 코드를 볼 때, 그것은 여전히 ​​나에게 거꾸로 보인다. 나는 DDD를 읽고 내가 생각하는 것을보아야 할 것이다. 마지막 링크를 통해 "때로는"서비스 레이어를 사용하는 이유에 대한 정보를 제공하고 싶습니다. 그렇기 때문에 내가 완전히 미친 것은 아닙니다. –

    +0

    위의 Before/After 예제와 대부분의 중요하지 않은 프로젝트가 "때때로"범주에있는 경험을 살펴보면 Entity 객체를 비즈 니스 로직 코드에서 깨끗하게 유지하는 것이 좋습니다. 지금까지 DDD를하지 않았습니다. – Behrang

    8

    하나는 왜 here를 참조하십시오. 글쎄요 읽을만한 가치가 있습니다 : http://martinfowler.com/bliki/AnemicDomainModel.html

    도메인 모델이 순전히 작동하지 않는 데이터 인 경우 일반적인 디자인의 많은 이점을 잃어 버렸습니다.

    는 또는 인용합니다 :

    "일반적으로, 당신은 서비스에서 찾을 더 많은 행동이 더 가능성이 도메인 모델의 혜택 자신을 강탈 할 모든 로직이 서비스에있는 경우. 너는 장님을 털었다. "

    0

    개인적으로 나는 빈혈 모델을 좋아합니다. 데이터는 데이터이고, 코드는 코드입니다. 하지만 예외가 있습니다.

    '밀도'로 나타납니다. 몇 가지 도메인 개체와 상호 작용하는 많은 서비스가있는 경우, 도메인 모델에 비즈니스 로직 중 일부를 입력하면 서비스의 일부가됩니다. 많은 도메인 객체와 상호 작용하는 몇 가지 서비스가 있다면 풍부한 도메인 객체에 대한 빈혈 모델을 선호하십시오.

    여러 도메인 (예 : 클라이언트 측과 서비스 측에서 동일한 도메인 개체를 사용함)에서 비즈니스 로직이 자주 발생한다는 사실을 발견했습니다. 이는 적용 가능해야하기 때문에 모든 맥락에서

    +1

    그래서 당신은 OOP를 좋아하지 않지만 절차적인 코드를 좋아합니다. 희망 당신은 싱글 톤 구성 요소에 비즈니스 로직을 작성하지 않습니다 ... – lnrdo

    관련 문제