4

내 애플리케이션이 완전한 DDD 설정을 보증하지 않는다고 가정하면 리포지토리가 여전히 유용할까요? 나는 그들이 구현 세부 사항 (Entity Framework 사용과 같은)으로부터 보호하는 방식을 좋아한다. 그러나 리포지토리는 골격에 묶여있는 경향이 있습니다. 개념은 정의에 따라 여전히 성배입니다.리포지토리는 도메인 기반 디자인없이 유용합니까?

일반적인 3 계층 응용 프로그램이 있고 비즈니스 계층 외관이 DDD와 같이 기능을 기반으로하는 "논리적 그룹화"클래스로 구성된 경우 TradingManager 및 ContactsManager처럼 "논리적 그룹화"저장소를 만드는 것도 의미가 있습니다. 또는 아마도 데이터 액세스 개체 (Aggregate root requirement가없는 리포지토리와 같다고 생각합니다). 물론 레이어간에 위아래로 전달되는 모델 (EF POCO)은 여전히 ​​갖게됩니다.

또한 방금 설명한 내용이 트랜잭션 스크립트 방식으로 간주됩니까? DDD가 아니라 Active Record입니다. Active Record가 Nhibernate와 같이 EF4와 함께 존재하는지 확실하지 않습니다.

DDD를 따르지 않을 때 다른 사람들이 n 계층 응용 프로그램을 어떻게 구성하는지 이해하려고합니다.

답변

5

당신이 암시 한 것처럼, 그것은 DAO에 대한 더 많은 것 같이 들립니다. DAO는 데이터 영역 기술을 완전히 추상화하려는 비 DDD 프로젝트에서 매우 유용하다고 생각합니다.

트랜잭션 스크립트가 실행되는 한 데이터 영역 디자인과 직각을 이룹니다. 트랜잭션 스크립트는 각 비즈니스 운영이 절차 적 호출로 그룹화된다는 것을 의미합니다. 예 : 트랜잭션 스크립트 패턴은 서버 측 WCF 서비스 호출에서 자주 사용되며 각 서비스 메소드는 트랜잭션 스크립트 패턴을 따릅니다. 이 방법으로 생각해보십시오. 트랜잭션 스크립트를 사용하면 실제 비즈니스 논리가 객체에 있지 않고 트랜잭션 스크립트 프로 시저 호출에 직접 기록됩니다. 공통 비즈니스 로직은 트랜잭션 스크립트간에 공유 될 수 있지만 일반적으로 정적 메소드, 헬퍼 등을 통해 수행되며 "순수한"OO가 아닙니다.

여기에 의사 코드

// traditional transaction script 
public class MailService 
{ 
    public void UpdateEmail(string userName, string newEmail)() 
    { 
     if(db.UserExists(userName)) 
     { 
      if(EmailHelper.ValidateEmailFormat(newEmail)) 
      { 
      db.UpdateEmail(userName, newEmail); 
      } 
     } 
    } 
} 

// transaction script with anemic domain objects 
public class MailService 
{ 
    public void UpdateEmail(string userName, string newEmail)() 
    { 
     var userDAO = new UserDAO(); 
     var emailDAO = new EmailDAO(); 

     var existingUser = userDAO.GetUserByName(userName);  

     if(existingUser != null) 
     { 
      if(EmailHelper.ValidateEmailFormat(newEmail)) 
      { 
      emailDAO.UpdateEmail(existingUser, newEmail); 
      } 
     } 
    } 
} 

// More of an OO/DDDish approach 
public class MailService 
{ 
    public void UpdateEmail(string userName, string newEmail)() 
    { 
     var userRepository = new Repository<User>(); 

     var userToUpdate = userRepository.Where(x => x.UserName = userName).FirstOrDefault(); 

     if(userToUpdate != null) 
     { 
      userToUpdate.Email = newEmail; 

      if (user.IsValid()) 
      { 
       userRepository.Update(userToUpdate); 
      } 
     } 
    } 
} 

의 비트가 분명히 첫 번째 예는 전혀 OO되지 않습니다이다. 두 번째 예제는 모든 비즈니스 로직이 MailService 호출에서 발생하므로 객체 지향보다 객체 기반입니다. 세 번째 예는 전통적인 OO입니다. 서비스 호출에서는 제어 흐름 만 발생합니다. 모든 비즈니스 로직은 User.IsValid() 메소드에서 처리됩니다.

비즈니스 논리를 어디에 두는 것까지 모두 중요합니다.

+0

당신은 정말로 트랜잭션 스크립트를 만드는 것에 대해 좀 더 자세히 설명 할 수 있습니까? 내가 말한이 디자인은 DDD가 아니며 Active Record가 아닙니다. 그래서 무엇입니까? 내 중간 계층/계층 메서드 (WCF 서비스이든 BLL 호출이든)는 ContactManager가 실제 엔터티가 아닌 전자 메일, 주소, 전화에서 작업을 수행하는 논리적 그룹 인 ContactsManager.AddEmail (전자 메일)과 같은 것으로 가정합니다. 예를 들어 엔티티. – e36M3

+0

DAO가 POCO 엔티티에서 작동하는 경우 두 번째 예제에서 두 번째 트랜잭션 스크립트 예제 인 –

+0

을 제공하도록 업데이트되었습니다. 빈 도메인 개체가 포함 된 트랜잭션 스크립트라는 사실을 변경하지 않는다고 가정합니다.또는 existingUser가 User 유형이고 newEmail이 전자 메일 유형일 수있는 코드가 이미 암시하고 있습니다. 논리 그 자체가 엔티티에 없다는 사실은 그것을 빈혈로 만드는 것인데, POCO를 사용하면 그것을 변경하지 않습니다. – e36M3

1

언제나처럼 ... "의존합니다". : D 죄송합니다 ...

단 책임 원칙에 해당한다고 생각합니다. 모든 DAO가 엔터티를 검색하는 경우 (음, CRUD를 수행하는 대신 DbContext를 사용하는 경우), 그 밖의 것은 없습니다 ... 그렇다면 롤백하십시오. 여러 엔터티에 대한 사용자 지정 논리가 있다는 것을 알기 시작하면 저장소와 같은 것을 고려해야합니다.

+0

하지만 리포지토리는 정의에 따라 DDD 경로를 지정합니다. 필자는 엔티티와 1-1을 갖는 것보다 DAO를위한 논리적 그룹화를 만드는 것에 대해 이야기하고 있다고 생각합니다. 따라서 전화, 이메일 및 주소 엔티티는 모두 ContactsDAO를 통해 퍼널됩니다. – e36M3

+1

죄송합니다. 저는 속기 말하고있었습니다. "리포지토리 (repository)와 같은 것"이라고 말하면서, 리터럴 DDD 저장소로 받아들이려는 의도가 아니라 일반적인 DAO보다 더 비슷한 것으로 생각했습니다. 나는 또한 특정 코드 구조에 "고정"되어 있다고 생각하지 않는다. 내가 알고있는 DDD 경찰이 없습니다. 잘못된 패턴 신청으로 인해 벌금이 부과 될 것입니다. ;) – Paul

+0

네 말이 맞다! 나는 DDD를 시도 할 때마다 내가 너무 많은 수준에서 실패하고있는 것처럼 느껴지기 때문에 그렇게 느낀다. 따라서 실제로 프로젝트가 DDD에 머 무르지 않는다면 더 많은 엔티티 중심성이 아닌 반대로 기능별로 메소드를 그룹화하는 논리적 DAO를 갖는 것이 아무 것도 없습니다. 예를 들어 TradingDAO.SubmitTrade (주식, 가격, 계정); 또는 TradingDAO.GetPrices(); 또는 TradingDAO.GetSymbols(). PriceDAO.GetPrices() 및 PositionDAO.GetPositions()와 반대입니다. – e36M3

관련 문제