기술에 대해 다루는 빈혈 도메인 모델
-
03-07-2019 - |
문제
나의 질문에 대한 빈혈 도메인 모델과 분리의 문제입니다.무엇을위한 최고의 기술 공연/부착 도메인 논리에 빈혈 도메인을까?에서 나의 일을,우리는 꽤 빈혈이 모델,그리고 우리는 현재 사용 중인"helper"클래스를 수행하는 데이터베이스/비즈니스에 논리 도메인 개체입니다.예를 들어:
public class Customer
{
public string Name {get;set;}
public string Address {get;set;}
}
public class Product
{
public string Name {get;set;}
public decimal Price {get;set;}
}
public class StoreHelper
{
public void PurchaseProduct(Customer c, Product p)
{
// Lookup Customer and Product in db
// Create records for purchase
// etc.
}
}
할 때 필요한 구매를 만드는 것이 StoreHelper,그리고 메소드를 호출 도메인에 있는 개체입니다.나를 위해,그것의 의미는 고객 제품을 저장하는 방법을 알고 자신을 저장소,하지만 당신은 아마 없을 원하는 저장()메소드에서 도메인을 개체입니다.그것은 또한 의미한 방법은 다음과 같 고객입니다.구매(제품),하지만 두고 도메인 논리에 entity.
여기에 몇 가지 기술가 확실하지 않은 좋은/나쁜:
- 고객과 제품을 상속에서"법인"등을 제공하는 기본적인 CRUD 작업에서는 일반적으로(사용 ORM 어쩌면).
- 장점:각 데이터를 객체가 자동으로 얻을 CRUD 작업,그러나 그 다음에 묶여 데이터베이스/ORM
- 단점:이 문제가 해결되지 않는 비즈니스 운영의 개체에 대한 관계의 모든 도메인 개체를 기초 엔티티가 적절하지 않을 수 있습니다
- 사용 도우미 클래스를 처리하는 CRUD 작업 및 비즈니스 로직
- 그것은 상 DAOs 에 대한"순수한 데이터베이스로"작업,그리고 별도의 사업 도우미들에 대한 더 많은 비즈니스 운영?
- 그것은 더 나은 사용하는 정적이 아닌 또는 정적 도우미 클래스 이?
- 장점:도메인 물체에 연결되지 않은 모든 데이터베이스/비즈니스 논리(완전하게 빈혈)
- 단점:아 OO,아주 자연을 사용하여 도우미들에서는 응용 프로그램 코드(처럼 보이는 C 코드)
- 를 사용하여 더블 파견 세계에서 가장 인기있는 엔티티가 방법을 저장하는 임의의 저장소
- 장점:더 나은 분리의 문제
- 단점:단체가 몇 가지 여분의 논리를 연결(하지만 그것은 분리)
- C#3.0 사용할 수 있습니다 확장하는 방법에 첨부 CRUD/비즈니스 방법을 도메인 개체없이 그것을 건드
- 이것이 유효한 접근법?어떤 장점/단점?
- 다른 기술을?
무엇 최고의 기술에 대한 처리 이?나는 새로운 주차(내가 읽기 Evans 책-그래서 어쩌면 열리는 내 눈)
해결책
Martin Fowler 은 기록에 대해 많은 도메인 모델 등 빈혈 도메인 모델.그는 또한 간략한 설명(및 UML 클래스 다이어그램)의 많은 디자인 패턴을 도메인 모델과는 데이터베이스에 도움이 될 수 있다: 카탈로그는"패턴은 기업의 애플리케이션 아키텍처".
는 것이 좋 보고 Active 기록 고 데이터 Mapper 패턴입니다.의 설명에서 당신의 문제,그것은 소리처럼 당신의 도우미 클래스를 모두 포함 도메인/사업 규정 고 데이터베이스 구현을 상세정보.
의 활동 기록 이동 도우미의 도메인 논리와 데이터베이스 코드를 다른 도메인 물체(h Entity
기본 클래스).데이터 매퍼를 이동수의 도메인을 도메인 개체를 데이터베이스 코드로 별도의 지체입니다.다음 방법 중 하나 것보다는 객체지향적인 절차상의 스타일의 도우미 클래스입니다.
에릭 에반스'"도메인 중심의 디자인"책은 우수하다.가 건조하지만,확실히 가치가있다.측가 "도메인을 중심 디자인을 빠르게"mini-book 그것은 좋은 소개 Evans'책입니다.게"도메인을 중심 디자인을 빠르게"로 사용할 수 있는 무료니다.
다른 팁
를 방지하기 위해서 빈혈이 모델,리팩터링 귀하의 도우미 클래스:
로직용:
"고객입니다.PurchaseProduct(제품 제품을 지불)",
"고객입니다.KillCustomer(사람을 살인자,무기기)"
해 존재하는 오른쪽으로"고객"도메인을 개체입니다.
로직용:
"고객입니다.IsCustomerAlive()"
"고객입니다.IsCustomerHappy()"
이동해야하는 사양입니다.
로직용:
"고객입니다.Create()",
"고객입니다.Update()"
분명히 가야 저장소가 여기에 해당합니다.
로직용:
"고객입니다.SerializeInXml()"
"고객입니다.GetSerializedCustomerSizeInBytes()"
에 가야한 서비스입니다.
복잡한 생성자를 이동해야하는 공장이 있습니다.
그게 내가 그것을 참조하십시오.나는 기뻐할 수 있는 사람이 있는 의견 내의 이해 DDD 접근 방식이다.
편집:
때로는 빈혈 도메인 모델 할 수 없는 피.
편집 내 응답을 추가하는 DDD 에 대한되지 않을 따기와 떨어지는 패턴이 있습니다.
DDD 에 대해 우리가 생각하는 방식.
나는 항상 생각의 빈혈 도메인 모델로 방지 패턴이다.그것은 맑은 고객이 제품을 구매,는 능력이 될 수 있습 generised 에 의해 인터페이스 구현
Interface IPurchase
Purchase(Product);
, 그래서 모든 도메인의 개체할 수 있음을 구현하는 대로 필요합니다.그 방법으로 소개할 수 있습 기능이 귀하의 도메인 물체에게 어느 곳에 있어야한다.
방법 중 하나는 당신이 언급하지 않은 것을 사용하여 AOP 을 처리하는 데이터에 액세스 할 수 있습니다.예를 들어 내는 최근의 이용 방법(하지만 훨씬 단순화된 게시물에 대한 목적)이었다는 했 Account
도메인 엔티티는 debit
방법,캡슐화하는 비즈니스 논리를 만들기 위해 필요한 성공적인 직불카드 계정에서.
N.B.모든 코드를 자바 AspectJ AOP 표기...
public boolean debit(int amount) {
if (balance - amount >= 0) {
balance = balance - amount;
return true;
}
return false;
}
적절한 저장소에 주입으로 나의 측면,나는 그 사용행한 차단하는 전화를 이 방법은...
pointcut debit(Account account,int amount) :
execution(boolean Account.debit(int)) &&
args(amount) &&
target(account);
...그리고 적용되는 조언:
after(Account account, int amount) returning (boolean result) : debit(account,amount) {
if (result) getAccountRepository().debit(account, amount);
}
내 생각에 이것은 좋은 분리의 관심사,그리고할 수 있습 귀하의 도메인은 엔터티를 초점을 전적으로 비즈니스 논리에의 응용 프로그램입니다.