태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

'Persistence Ignorace'에 해당되는 글 1건

  1. 2010/01/20 Entity Framework 에 대한 변론 (4)

Entity Framework 에 대한 변론

.Net/.Net Framework Design Guide Line 2010/01/20 13:41
C-Thinker 님의 많은 포스트를 읽고 매우 상쾌해지는 느낌과 동시에 많은 도움이 되었습니다.

하지만  Entity Framework 4.0 - 아직도 헤메는 MS 라는 포스트는 많은 부분에 동의를 하지 못하였고, 이렇게 EF에 대한 변론(?) 을 하는 포스트를 작성하게 되었습니다.

일단, 포스트 내용을 반박하게 되는 글이 될 것과 C-Thinker님의 글에서 EF에 대한 문제의식을 제대로 집어 내지 못한 것이 포스트를 작성하는 것에 대해 조심 스럽게 만듭니다. 하지만 논쟁을 통해서 서로가 발전할 수 있다는 변증법 사고에 기반을 두고 EF에 대한 저의 의견을 적어 봅니다.


Table Module Pattern 의 개발 모델 문제에 대해 말 해 보도록 하죠.

이상한 모습도 그렇지만 아직도 테이블 기반 (Table Module Pattern) 의 애플리케이션 개발 모델을 버리지 못하고 있는 느낌이다.


우선 EF가 테이블 기반인가? 테이블로 부터 EDM을 생성하므로 테이블 기반이라고 말 할 수 있겠네요. 하지만 마틴 파울러가 말한 Table Module Pattern이냐? 라는 것에는 이견이 있군요. 파울러의 Table Module Pattern은 Data Access Layer를 작성할 때 1:1 테이블로 사상된 일명 DataSet을 통해 작업을 하느냐. 다시 말하면 직접적인 RecordSet을 통하여 작업 하느냐 라고 봅니다.  개발자가 이용하는 관점에서는 EF는 Domain Model 이며, Data Mapper를 구현 할때 Table의 메타 데이터를 이용한다. 라고 볼수  있네요.

매퍼 자체가 매핑을 하기 위해서 Gateway를 이용해야 하는데 Gateway는 Table Data Gateway, Row Data Gateway, Active Record를 사용할 수 있으나,  이것은 매퍼를 구현하는 방법에서의 적절한 것을 선택하는 것의 문제이지 Table을 기반으로 생성된 EDM이 문제일 수는 없다고 봅니다.





ORM과  Persistence Ignorance를 아래의 글로 언급하셨는데

ORM 의 근본 목적이라면 OO (Object Orientation) 프로그램 상에서 생성되고 관리되는 객체들과 관계형 (Relation) 으로 구성된 데이타베이스와의 구조적 차이 (Impedance Mismatch) 를 극복하기 위한 반복되는 코드를 줄이고 어떻게 저장되는 지에 대해서는 상관하지 않겠다 (Persistence Ignorance) 는 관점에 있다고 볼 수 있다.


저는 "ORM 이라는 것은 Object Oriented 객체와 RDBMS와의 임피던스 미스매치(Impedance Mismatch)를 조절하며 데이터 영속화(Data Persistence)를 자동화(Automate) 함으로써 비지니스 로직을 작성하는 개발자에게 Domain Model로 작업하도록 지원해 주는 것이 목표 라는 것"이라고 정리하고 있는데,  artofsoftwaredev님의 의견과 거의 같으면서도 다름이 느껴집니다.


Persistence Ignorance는 Jimmy Nilsson 의 책 Applying Domain-Driven
Design and Patterns: With Examples in C# and .NET (Addison-Wesley Professional, 2006)에서 제시한 용어로써 "keep your domain model decoupled from your persistence layer " 로써 정확한 정의가 모호합니다.

Eric Evans의 DDD 방법론과 마틴 파울러의 생각을 정의해 보자면  "도메인 모델이 저장 장소에 무지하도록 한다." 라고 할 수 있습니다. 저장장소가 인-메모리 가 되었건 , 파일 시스템이 되었건, SQL Server가 되었건 몰라도 영속화를 할 수 있어야 함을 의미 하는 것으로 , "어떻게" 보다는 "어디"에 또는 "무엇"에 영속화 되는가에 관심이 있겠다 말할 수 있습니다.

영속화 매체가 파일 시스템, 또는 오라클이냐, MySql이냐, MS SQL 이냐를 도메인 모델이 인지를 하지 않고 특정 영속화 인터페이스를 사용한다면 영속화 할 수 있다는 개념으로 Repository 패턴을 생각해 볼 수 있습니다.





객체와 테이블이 1:1의 관계이냐?
데이타베이스로 부터 모델을 생성하고 코드만 자동으로 생성을 하지 않은 후, 그 모델에 맞는 객체를 만들어야 한다. 예를 들어 주문 테이블이 있다고 하면 이 테이블로 부터 주문이라는 모델을 만들고 이 주문이라는 모델이 갖고 있는 필드들을 갖고 있는 객체를 만들어야 한다는 얘기다. 여기서 다시 객체와 테이블의 1 : 1 관계를 벗어나지 못한다. 그래도 여기까지는 큰 문제가 없다고 봐 줄 수도 있다. 정작 문제는 이 객체들을 데이타베이스에 넣고 빼는 과정을 자동화 해 주는 ObjectContext 이다.

우선 EF는 상속받아 구현되는 컴플렉스 타입을 지원하며 1:1 관계라는 것 자체가 사실과 다릅니다.
OO의 객체를 영속화 하기 위해서 테이블을 모델링 할 때 상속받아 구현된 모든 객체를 테이블과 1:1로 구현 할 수도 있고, 타입으로 구분하여 상속받아 구현된 모든 객체를 한개의 테이블에 저장할 수도 있습니다. 이 두가지 모두 전략에 따라 적절한 패턴의 선택 문제입니다.




그럼 문제가 된다고 말씀하시는 ObjectContext의 POCO 지원시에 의존성 문제를 볼까요
객체들을 자동으로 생성하지 않았으므로 POCO 를 사용할 경우 ObjectContext 는 어떤 객체들이 어떤 모델들과 어떤 관계를 갖고 있는지 알 수가 없게 된다. 따라서 ObjectContext 를 상속받는 객체를 만들어 사용을 해야 하는데 문제는 각 POCO 객체를 Entity Framework 에서 Entity 로 인식을 하고 처리를 하기 위해 이 POCO 객체타입으로 EntitySet 을 만들어야 한다는 것이다. 다시 말해서 도메인 객체를 데이타 엑세스 레이어에서 알고 있어야 한다는 얘기다. 어라... 이건 뭐가 거꾸로 되도 한참 거꾸로 됐다. 프로젝트를 UI, 도메인, 데이타 레이어로 나누었을 경우 UI -> 도메인 -> 데이타 순서가 아니라 UI -> 데이타 -> 도메인 순서의 의존성 (Dependency) 가 생긴다.


객체를 영속화 하기 위해서는 상태 관리, CRUD의 인터페이스를 제공하는 그 어떤것이 필요하게 되는데 ObjectContext가 그 역할을 하는 것입니다. POCO의 영속성을 지원하기 위해서는 지원하는 '그 무엇'이 있어야 합니다. 그것이 Transaction Script가 되었건, Table Module이 되었건 말이죠. EF 4에서는 POCO를 지원하기 위해 POCO를 EDM에 추가하는 것으로 해결하는 것이죠.

도메인에서 만들어진 객체를 데이터 레이어에서 알아야 하는 것이 문제라고 말씀하셨는데, 언어의 Primative 타입만을 데이타 레이어에 전송하지 않고 Object로 전달하기로 결정하는 순가. DTO라고 하는 객체가 필요하게 됩니다. DTO는 도메인 모델과 데이터 모델에서 알지 않고서는 작업이 되지 않기 때문에 EDM의 엔터티 자체가 DTO 역할을 하면서 엔터티의 상태 관리와 CRUD 및 데이터 매핑 작업을 ObjectContext가 해 주는 구조 입니다.

다시 말해서 DTO가 필요해 지는 순간 도메인 레이어와 데이터 레이어가 동시에 알아야 할 필요성이 생기고, 이것을 의존성이라고 말한다면 Primative Type 만으로 작업하는 것 이 외에는 방법이 없다고 생각합니다.

의존성의 순서는 둘째 치고, 의존성이 있다는 얘기는 변경발생시 두군데의 변경이 불가피 하나는 얘기이고 굳이 두개로 나눌 이유가 없다는 말일 수도 있다. 이는 다시말해 도메인 로직과 데이타 엑세스가 분리 될 수 없다는 것을 말하고 결국 데이타베이스에 대한 의존성은 줄지 않았다는 얘기가 된다.


의존성 문제는 개발자의 코드 자체가 레이어 간의 의존성을 가지냐의 관점으로 봐야 옳으며, 중간자 (Mediator)가 의존성을 알고 있느냐의 관점으로 보는 것이 아니라고 생각합니다. 데이터베이스의 변경 마다, 데이터 레이어와 도메인 레이어의 수직 변경을 메터데이터(EDM)에 위임하고 , EDM의 업데이트로 변경을 반영함으로써 , 수직 변경을 최소화하는 것은 옳은 관점이라고 생각합니다.


artofsoftwaredev 님의 말씀대로 모든 레이어가 Ignore 하고 서로의 변경에 전혀 관심 갖지 않아도 된다면 얼마나 좋겠습니까 만은 , 그 개념은 아직 이상적이며 완벽한 솔루션이 없습니다.


현재로써는 "관심의 분리 , Seperate of Concern"로 "한 곳에서만 관리하도록 하자 Single Point Management "의 관점으로 디자인 하는 것이 옳다고 볼수 있습니다.


EF가 완벽하냐? 라고 묻는다면 대답할 수 없습니다만, 디자인 관점이 옳으냐 라고 묻는다면 "예" 라고 하겠습니다.
저작자 표시
이올린에 북마크하기(0) 이올린에 추천하기(0)

현재글 : Entity Framework 에 대한 변론 posted By - 반더빌트 2010/01/20 13:41
Trackback 0 : Comments 4

Trackback Address :: http://smack.kr/trackback/357 관련글 쓰기

  1. C-Thinker 2010/01/20 16:58 Modify/Delete Reply

    안녕하세요. 변론을 하신다기에 들어와 봤습니다. ^^
    우선 지적하신 부분들에 대해서 변명을 하겠습니다.

    Table Module 에 대해서는 그 패턴을 사용했다기 보다는 개념적인 기반이 되어 있다고 표현을 한 것입니다.
    ORM 과 Persistence Ignorance 에서는 솔직히 무슨 말씀을 하려 하시는지 잘 이해가 가지 않는군요.
    객체와 테이블이 1:1 관계라고 표현한 부분에서는 테이블이라고 썼는데 사실 그 전에 언급한 모델을 그렇게 써 버렸군요. 도메인 모델을 지원을 하려면 기존의 도메인 모델과 EF가 만들어낸 모델과의 자유로운 매핑이 가능해야 한다고 생각합니다.
    POCO 와 ObjectContext 에 대해서 말씀드리자면, 개발자가 어떤 이유에서든 자유의지로써 의존성을 만들게 될 수는 있지만 프레임워크에서 강제해서 발생되는 의존성하고는 많은 차이가 있다는 생각입니다. 개발자가 만든 의존성도 나중에 문제가 되는데 프레임웍에서 의존성을 갖도록 강제를 당한다면 추후 확장성에 많은 문제가 발생할 소지가 많습니다.

    어쨋든 다른 관점에서 볼 수 있는 기회를 주신것에 감사드립니다.

    • 스맥 반더빌트 2010/01/20 18:04 Modify/Delete

      네 Thinker님 또 뵙게 되었습니다.

      Table Module Pattern에 대해서는 L2S이 가깝다고 할 수 있습니다. EF는 L2S에 논리 모델이 더해진 것으로 생각할 수 있네요, 또한 EF Table Module Pattern 을 기반으로 한다 해도 그것이 문제인가? 라는 의견입니다.

      "PI는 PI 의 정의 및 룰이 완벽하지 않은 데다가, 전적으로 ORM의 책임은 아니다 라는 의미이며, 도메인 모델은 Repository 패턴 등을 이용함으로써 PI를 일정부분 충족 시킬수 있다" 라는 의미입니다.


      POCO와 ObjectContext의 문제에 대해서는 Thinker님의 문제 의식에는 동의 하나, POCO를 영속화하기 위한 또다른 방법의 필요가 요구됩니다. 이것을 ObjectContext가 담당하도록 하는 일관적인 패턴에 대해서 동의 한다는 말입니다.

      DTO 예를 든 것은 불가피한 의존성의 발생 현실을 말하고자 함이며 , 의존성이 없이도 작동하는 해결책이 있다면 저도 매우 기뻐하고 싶습니다.

  2. 권효중 2010/01/21 16:41 Modify/Delete Reply

    EF 베타버전을 아직 저도 써보지는 않았지만 지난 PDC2009 의 EF 세션에서 보여준 데모에는 객체에서 데이타베이스를 생성하던데요..

    • 스맥 반더빌트 2010/01/21 21:01 Modify/Delete

      네 효종님

      EF는 .NET Framework 3.5 SP1에 정식 포함 되어 V1 이었으나, 다음 버전은 .NET Framework 4.0에 포함되어 EF4 로 불리웁니다.

      EF V1에서는 Entity를 DB에서 부터 생성 + 모델 디자이너에서 생성 할 수 있으나, Custom Entity에 대해서 DB에 반영 할 수는 없었습니다.

      EF 4.0(V2) 에서는 EDM 디자이너에서 생성한 Custom Entity를 DB에 테이블로 생성 할 수 있도록 기능이 업그레이드 되었답니다.

      EF 4.0의 새로운 기능은 EDM으로 부터 DB로의 테이블 생성, POCO 지원 등이 있습니다.


[생각을 적어 주세요~ 댓글은 작은 인연의 씨앗입니다.]