문제

처음에 S# 아키텍처 예제에 따라 시스템을 설계했습니다. 이 CodeProject 기사에 요약되어 있습니다 (불행히도, 나는 nhibernate를 사용하지 않습니다). 기본 아이디어는 지속성 계층과 통신 해야하는 각 도메인 객체에 대해 다른 라이브러리에 해당 데이터 액세스 오브젝트가 있다는 것입니다. 각 데이터 액세스 객체는 인터페이스를 구현하고 도메인 객체가 데이터 액세스 방법에 액세스 해야하는 경우 항상 인터페이스에 대해 코딩하고 DAOS 자체에 대해 결코 코딩하지 않습니다.

당시에는 여전히이 디자인이 매우 유연하다고 생각했습니다. 그러나 내 도메인 모델의 객체의 양이 커짐에 따라 조직 문제가 없는지 의문을 제기하고 있습니다. 예를 들어, 도메인의 거의 모든 객체는 해당 데이터 액세스 개체 및 데이터 액세스 개체 인터페이스로 끝납니다. 뿐만 아니라, 이들 각각은 다른 장소에 있으며 일부 네임 스페이스 주변에서 간단한 일을하고 싶다면 유지하기가 더 어렵습니다.

흥미롭게도, 이러한 DAO (및 해당 인터페이스) 중 다수는 매우 단순한 생물입니다. 가장 일반적인 것은 단일 getByid () 방법 만 있습니다. 나는 다음과 같은 많은 물체로 끝납니다.

public interface ICustomerDao {
  Customer GetById(int id);
}

public interface IProductDao {
  Product GetById(int id);
}
public interface IAutomaticWeaselDao {
  AutomaticWeasel GetById(int id);
}

그들의 구현자는 일반적으로 매우 사소한 곳입니다. 이것은 다른 방향으로 나아가는 것이 더 간단하지 않을지 궁금해하고, 간단한 데이터 액세스 작업을위한 단일 객체를 가지고 전략을 전환하고, 조금 더 필요한 사람들을위한 전용 데이터 액세스 개체의 생성을 예약 할 수 있습니다. 복잡한.

public interface SimpleObjectRepository {
      Customer GetCustomerById(int id);
      Product GetProductById(int id);
      AutomaticWeasel GetAutomaticWeaselById(int id);
      Transaction GetTransactioinById(int id);
}
public interface TransactionDao {
  Transaction[] GetAllCurrentlyOngoingTransactionsInitiatedByASweatyGuyNamedCarl();
}

누구든지 이와 같은 아키텍처에 대한 경험이 있습니까? 전반적으로 나는 설정에 매우 만족합니다. 이제는이 작은 파일의 관리가 유일한 관심사입니다. 그러나 데이터 액세스 계층을 구성하는 다른 접근 방식이 존재하는 것이 여전히 궁금합니다.

도움이 되었습니까?

해결책

간단한 시스템 이외의 간단한 접근 방식에 대해 권장합니다. 일반적으로 각 집계에 대한 사용자 정의 저장소를 작성하고 가능한 한 적절한 논리를 캡슐화하는 것이 좋습니다.

따라서 내 접근 방식은 고객 리포지토리와 같이 필요한 각 집계에 대한 저장소를 갖는 것입니다. 여기에는 추가 (저장) 메소드가 있으며 해당 집계에 적합한 경우 제거 (삭제) 방법이 있습니다. 또한 쿼리 (getActive)를 포함하여 적용되는 다른 사용자 정의 메소드가있을 수 있으며 일부 쿼리 중 일부는 사양을 허용 할 수 있습니다.

이것은 많은 노력처럼 들리지만 사용자 정의 쿼리 외에는 대부분의 코드는 최소한 최신 ORM을 사용하는 경우 구현하기가 매우 간단하므로 상속 (readWriteRepositorybase where t : iaggregateroot) 및/또는 구성 (전화 리포지토리 헬퍼 클래스로 나옵니다). 기본 클래스에는 GetByid와 같은 모든 경우에 적용되는 방법이있을 수 있습니다.

도움이 되었기를 바랍니다.

다른 팁

PHP에서 일하지만 데이터 액세스 계층에 대해 비슷한 설정이 있습니다. 다음과 같은 모습을 보이는 인터페이스를 구현했습니다.

interface DataAccessObject
{
public static function get(array $filters = array(), array $order = array(), array $limit = array());
public function insert();
public function update();   
public function delete();
}

그런 다음 각 데이터 액세스 객체는 다음과 같은 작업을 수행합니다.

class DataAccessObject implements DataAccessObject
{
    public function __construct($dao_id = null) // So you can construct an empty object
    {
        // Some Code that get the values from the database and assigns them as properties
    }
    public static function get(array $filters = array(), array $order = array(), array $limit = array()) {};  // Code to implement function
    public function insert() {};  // Code to implement function
    public function update() {};  // Code to implement function 
    public function delete() {};  // Code to implement function        
}

현재 각 데이터 액세스 객체 클래스를 수동으로 구축하고 있으므로 데이터베이스에 테이블을 추가하거나 기존 테이블을 수정할 때 새 코드를 직접 작성해야합니다. 제 경우에는 코드베이스가있는 곳에서 여전히 큰 단계입니다.

그러나 SQL 메타 데이터 (외국의 주요 제약 조건 등을 활용하는 상당히 사운드 데이터베이스 설계가 있다고 가정하여 이러한 데이터 액세스 개체를 생성 할 수도 있습니다. 그런 다음 이론적으로 단일 부모 DataAccessObject 클래스를 사용하여 클래스의 속성과 방법을 구성하고 데이터베이스의 다른 테이블과 자동으로 관계를 구축 할 수 있습니다. 이는 DataAccessObject 클래스를 확장하여 수동으로 구성된 코드의 양이 필요한 상황에 맞춤형 메소드와 속성을 제공 할 수 있기 때문에 설명하는 것과 동일한 것을 달성 할 수 있습니다.

.NET 개발을위한 사이드 노트로서, 당신은 subsonic과 같은 데이터 액세스 계층의 기본 구조를 처리하는 프레임 워크를 살펴 보셨습니까? 그렇지 않다면, 나는 그러한 프레임 워크를 조사하는 것이 좋습니다. http://subsonicproject.com/.

또는 PHP 개발의 경우 Zend 프레임 워크와 같은 프레임 워크가 유사한 기능을 제공합니다. http://framework.zend.com

조지 나는 당신의 느낌을 정확히 알고 있습니다. Billy의 아키텍처는 나에게 의미가 있지만 컨테이너, Imapper 및 Mapper 파일을 만들어야 할 필요성은 고통 스럽습니다. 그런 다음 Nhibernate를 사용하는 경우 .hbm 파일과 일반적으로 몇 가지 단위 테스트 스크립트를 사용하여 모든 작업을 확인합니다.

나는 당신이 nhibernate를 사용하지 않더라도 여전히 일반적인 기본 클래스 LO로드/컨테이너를 저장하는 것을 사용한다고 가정합니다.

public class BaseDAO<T> : IDAO<T> 
{
     public T Save(T entity)
     { 
       //etc......
     }
}
public class YourDAO : BaseDAO<YourEntity>
{
}

nhibernate가 없으면 반사 나 다른 마카 니즘을 사용하여 어떤 SQL/Sproc을 호출 할 것인지 결정할 것 같아요?

어느 쪽이든, 이것에 대한 나의 생각은 DAO가 기본 클래스에 정의 된 기본 CRUD 작업 만 수행 해야하는 곳이 될 것입니다. 그러면 사용자 정의 매퍼와 인터페이스를 작성할 필요가 없습니다. 이것을 달성 할 수있는 유일한 방법은 반사를 사용하여 DAO를 동적으로 만들기 위해 emit을 사용하는 것입니다.

나도 사용하고 있습니다 저장소 패턴 내 dao와 나는 그것에 매우 만족합니다. 그렇습니다. 당신은 꽤 작은 수업으로 끝나지만, 그것은 매우 유지 가능합니다. 사용하면 조금 더 강력합니다. IQueriable 인터페이스 (linq.) 또한 제네릭을 사용할 수도 있습니다 ( T GetById<T>(int id)) 꽤 일관된 데이터베이스 구조가있는 경우.

두 번째 접근 방식으로 거슬러 올라가는 주요 추첨은 단위 테스트입니다. 단순한 공장과 같은 큰 공장 방법을 조롱하려면 iCustomerdao를 조롱하는 것보다 더 많은 작업이 필요합니다. 그러나 내 프로젝트는 정신 부하가 밝아지고 유지 가능성이 높아지기 때문에 고도로 관련된 객체 (대부분의 단위 테스트에서 사용되는 곳)에 대한 두 번째 접근 방식과 함께 사용됩니다.

나는 당신의 시스템을 더 관리하기 쉽고 이해하기 쉽게 만드는 이유를 알아 냈습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top