2011-01-24 2 views
1

..저장소 패턴 계속 - 클래스 메소드 또는 저장소 메소드? 은행 계좌, 말의 구조를 감안할 때

class Account 
{ 
virtual int Id { get; set; } 
virtual int Balance { get; set; } 
} 

그리고 간단한 클래스를 수행 트랜잭션을 추적, 그래서하고 싶은 말 ...

class Transaction 
{ 
virtual int Id { get; set; } 
virtual Account Account { get; set; } 
virtual DateTime Timestamp { get; set; } 
virtual int Amount { get; set; } 
} 

의 난을 추적 할 가정하자 완료된 거래가 여기에서 더 지능적인 접근 방식입니까?

interface IAccountRepository 
{ 
void Deposit(int account, int amount) 
} 

또는 ...

class Account 
{ 
void Deposit(int amount) 
{ 
    // this one is easier, but then I have to repeat 
    // myself because I need to store the Transaction 
    // in the database too. 
} 
} 

리포지토리 패턴은 일/ORM/세션 단위에 대한 핸들을해야하기 때문에, 가장 포괄적 인 것 같다 (nHibernate 수 사용) -하지만 사용 클래스 레벨 방법은 '이 객체에 이것을 수행하십시오'라는 표준 객체 지향 원칙에 더 가깝기 때문에보다 직관적 인 것처럼 보입니다.

제 질문은 트랜잭션을 기록하려면 데이터베이스 객체로도 저장해야한다는 것입니다. 클래스 레벨 메소드를 사용하여 두 번째 경로로 이동하면 Account 클래스 내부에서이를 수행 할 수 없으므로 결국 반복해야합니다.

내 다른 옵션은 내가 TransactionRepository에 계정을 찾은 다음 그 Deposit 방법을 수행하기 때문에

잘 작동
interface ITransactionRepository 
{ 
void CreateTransaction(int account, int amount); 
} 

, 그것은 종류의 함께 A와 B를 래핑 ... 또 다른 추상화이지만, 아무튼 이것이 현명한 접근 인 것처럼 정말로 느껴지지 않습니다. 왜 그런지 모르겠지만, 내 직감은 그게 최선의 방법이 아니라고 말합니다.

이것은 물론 하나 이상의 클래스 세트에 적용됩니다. 이는 디자인의 원칙입니다. 나는 당신이 어떤 생각을 가지고 있다면 더 많은 베테랑 프로그래머가이 상황에서 무엇을 할 것인지보고 싶었다.

답변

1

CRUD (생성, 읽기, 업데이트, 삭제) 계정의 저장소 패턴을 사용하여 sugguest 할 것입니다. 당신이

class Account 
{ 
    void Deposit(int amount) 
    { 
    } 
} 

는 그런 다음

// Get the account by id 
Account acc = rep.GetAccountById(23143); 
// Deposit the money 
acc.Deposit(21.23); 
// Update if needed 
rep.UpdateAccount(acc); 

거래 수는에서 할 수있는 계정을 업데이트 할 저장소를 통해 계정에 액세스 언급처럼

interface IAccountRepository 
{ 
    Add(Account acc); 
    Remove(Account acc); 
    Account GetAccountById(int account); 
    Update(Account acc); 
} 

그런 다음 계정 클래스의 예금 방법을 넣어 비슷한 방법이지만, 나는 Transcation의 Account 인스턴스보다는 Account Id를 저장하고있을 것이다.

class Transaction 
{ 
virtual int Id { get; set; } 
virtual int AccountId { get; set; } 
virtual DateTime Timestamp { get; set; } 
virtual int Amount { get; set; } 
} 
0

귀하의 질문은 구조적 DB/OO 불일치로 인해 발생하는 문제의 좋은 예입니다. 내 경험에 비추어 볼 때, 사람들은 설명하는 첫 번째 옵션을 선호하는 경향이 있습니다. 계정 비즈니스 개체를 무시하고 저장소를 사용하여 DB에 트랜잭션을 저장하십시오.

DB 구조가 비즈니스 계층 디자인에 영향을주지 않도록 강력히 권장합니다. 비즈니스 객체는 비즈니스 행위를 구현하기 위해 존재합니다.비즈니스 관점에서 Account 클래스에 속한 작업을 위해 저장소에 직접 액세스하면 비즈니스 규칙은 외부 Account 클래스 외부의 이상한 위치에서 종료됩니다.

  1. 준수하십시오 OO 원칙에 비즈니스 로직의 :

    는 다음과 같이 난 항상 이런 상황에 걸릴 접근 방식을 귀하의 질문에 대답합니다. 실제 프로세스에 따라 클래스와 상호 작용을 구조화하므로 비즈니스 규칙이 예상대로 끝납니다.

  2. DB에 스토리지 지향 뷰를 제공하십시오. 이것이 의미하는 바는 리포지토리가 비즈니스 개체의 구조를 모방하지 않아도된다는 것입니다. 예를 들어 계정과 트랜잭션에 대해 CRUD를 수행하는 저장소를 구현하십시오.