이전 포스트 Dependency Inversion Principle 에서 의존하는 모듈, 레이어 사이에 추상 (interface 또는 abstract class)을 의존함으로써 구현의 상세(detail)를 의존할 때보다 느슨한 커플링을 만들 수 있고,  구조적 설계와 비교할 때 의존의 방향이 역전 되었다라고 하며, 의존의 전이를 끊었다라고 말했습니다.

Inversion of Control 은 프레임워크가 정의한 추상(interface 또는 abstract class)을 클라이언트 코드가 구현을 하고, 구현된 객체를 프레임워크에 전달(또는 주입) , 프레임워크가 제어를 가지게 함으로써 클라이언트 코드로 부터 제어의 수를 줄이게 하는 것이라고 말할 수 있습니다. 모든 제어를 클라이언트 코드가 가지고 있는 구조적 설계와 비교해 프레임워크가 제어를 가지는 것을 제어가 역전 되었다 라고 말합니다.

Invsersion of Control Container 란 무엇일까요? Invsersion of Control 을 담고 있는 상자 일까요?



용어의 개념을 왜곡하지 않고 가능한 원래의 의미를 알기 위해 마틴 파울러의 [ Inversion of Control Containers and the Dependency Injection pattern] 의 글을 번역 인용하여 IoC Container를 설명하고자 합니다.

콜론(:) 구분자로 저장된 영화의 목록에서 특정 감독의 영화를 조회하는 예제는 아래와 같습니다.

 public class MovieLister
 {
        private MovieFinder finder;
        public MovieLister()
        {
            finder = new ColonDelimitedMovieFinder("Movies1.txt");
        }
 
        public List MoviesDirectedBy(String arg)
        {
            List items = new List();
            List allMovies = finder.FindAll();
             
            foreach (Movie item in allMovies)
            {
                if(string.Equals(item.DirectorName, arg)){
                    items.Add(item);
                }
            }
 
            return items;
        }
    }
 
    public interface MovieFinder
    {
        List FindAll();
    }
 
    public class ColonDelimitedMovieFinder:MovieFinder
    {
        string sourceFilename = string.Empty;
 
        public ColonDelimitedMovieFinder(string arg)
        {
            this.sourceFilename = arg;
        }
 
        #region MovieFinder 멤버
 
        public List FindAll()
        {
            List items = new List();
 
            //Read From file : sourceFilename;
            //Split with Colon Delemiter
            //Add to items List
            string rawText = File.ReadAllText(sourceFilename);
            foreach (string row in rawText.Split(new char[]{':'}))
            {
                items.Add(new Movie(row.Split(new char[] { '|' })[0],

 row.Split(new char[] { '|' })[1])); 
            }
            return items;
        }
 
        #endregion
    }
 
    public class Movie
    {
        public string Name;
        public string DirectorName;
        public Movie(string name, string directorName)
        {
            this.Name = name;
            this.DirectorName = directorName;
        }
    }
}
 


이 클래스를 나만 사용한다면 깔금하고 멋져보입니다. 하지만, 나의 친구가 이 멋진 기능을 자신의 프로그램에 복사해서 넣고 싶다면 어떤 일이 벌어질까요? 그들이 영화 목록을 콜론으로 구분된 "movie1.txt"라는 이름의 텍스트파일로 정한다면 환상적일  것입니다. 다른 파일이름을 사용하고 싶다해도 속성값 만 변경하면 되니 괜찮습니다. 하지만 영화목록을 위한 완전히 다른 폼을 사용하길 원한다면 : SQL 데이터베이스, XML 파일, 다른 텍스트파일 포멧 , 이 경우에 데이터를 가져오는 다른 클래스가 필요 합니다. 나는 MovieFinder interface를 사용했기 때문에 MoviesDirectedBy 메소드는 변경하지 않아도 됩니다. 하지만 알맞는 finder 인터페이스 구현 인스턴스를 얻을 방법이 필요합니다.


이 상황을 P of EAA 에서는 Plugin 이라고 기술합니다. finder를 위한 구현 클래스는 컴파일타임에 링크되지 않습니다. 내 친구가 어떤 구현을 원할지 모르니 Lister 가 특정 구현과 일하는 대신, 내 손을 떠나 나중에 플러그 될 수 있도록 합니다. 문제는 어떻게 해야 Lister가 구현 클래스를 무시하면서도 여전히 인스턴스와 일할 수 있게 하느냐 입니다.

이것을 실제 시스템으로 확장하자면, 우리는 수십개의 이런 서비스와 컴포넌트를 가지고 있을 것입니다. 이런 경우에 interface 를 통해 이야기하는 방법으로 컴포넌트 사용 방법을 추상화 할 수 있습니다. ( 컴포넌트가 interface를 가지도록 설계되지 않았다면 Adapter를 사용할 수 있습니다.) 


중요한 문제는 이 플러그인들을 어떻게 어플리케이션에 조립하느냐 입니다. 이것이 경량 컨테이너 lightweight Container 가 부상하게 이유입니다. 일반적으로 Inversion of Control을 이용해 해결할 수 있습니다.
 


주: 여기서 경량 컨테이너란 Service Locator, PicoContainer, Spring, Avalon, Guice 등을 말합니다.

주: 여기서 Inversion of Control을 이용해 해결한다는 말은 구현을 선택하는 전략을 가진 객체에게 제어를 넘김으로써 구현을 찾도록 한다는 것을 의미합니다.

주 : 추상을 사용함으로써 커플링을 느슨하게 하는 아이디어는 로버트 C. 마틴의 Dependency Inversion Principle 이 도입된 것입니다.



Inversion of Control 

이 컨테이너들이 "Inversion of Control"을 구현하고 있기 때문에 유용하다고 말할 때 완전히 혼란 스러워졌습니다. Inversion of Control 은 프레임워크의 일반적인 특성입니다. 따라서 경량 컨테이너들이 특별하다라고 말하는 것은, 내 차는 바퀴를 가지고 있기 때문에 특별하다라고 말하는 것입니다.

그렇다면 과연 컨트롤의 어떤 관점이 역전 되었다는 것일까? 내가 처음 제어의 역전을 말했을 때는 사용자 인터페이스의 제어를 의미하는 것이었습니다. 초기의 사용자 인터페이스는 어플리케이션에 의해 제어 되었습니다. 여러분은 "Enter Name" , "Enter Address" 와 같은 순차적인 명령을 가지고 있고, 여러분의 프로그램은 프롬프트를 나타낸 후 각각에 대해 응답을 선택할 것입니다. main loop를 담고 있는 그래피컬 UI 프레임워크를 가지고 작업한다면, 스크린의 다양한 필드를 위한 이벤트 핸들러가 제공되고, 프로그램의 중앙 제어는 UI 프레임워크에게 역전됩니다. 제어는 여러분에게서 프레임워크로 이동한 것이죠.


컨테이너에게 있어서 역전 이라고 하는 것은 컨테이너가 플러그인 구현을 스스로 찾는 것을 의미 합니다. 나의 순진한 Lister는직접 인스턴스화된 finder 구현을 찾습니다. 이렇게 하면 플러그인으로 사용할 수 없게 됩니다. 컨테이너를 사용하면 Lister에 구현을 주입할 수 있습니다. 


심사숙고한 후 우리는 이 패턴을 위한 좀더 구체적인 이름이 필요하다는 결론에 도달했습니다.  제어의 역전 Inversion of Control은 너무 일반적인 용어여서 사람들이 매우 혼란스러어 했습니다. IoC 에 대한 다양한 토론을 거친 결과 우리는 IoC를 Dependency Injection 이라고 이름 붙이기로 했습니다.


마틴 파울러의 [ Inversion of Control Containers and the Dependency Injection pattern] 중 일부 


no more IoC , it`s Dependency Injection!



위의 내용을 요약하자면 :
 

이미 작성된 코드를 다른 어플리케이션에 재사용하거나, 의존하고 있는 객체의 행위를 컴파일타임 이후에 다른 행위로 플러그 하고자 한다면, 클라이언트 객체는 추상을 가지고 작업을 해야 합니다. 이 추상에 구현을 교체할 수 있는 패턴을 마틴파울러는 Plugin 패턴이라고 이름 붙였습니다. 그럼 추상을 구현한 다양한 플러그인 중에 알맞는 플러그인을 선택해야하는 문제가 남게 됩니다.

의존 그래프의 생성과 생성된 의존을 주입 하는 일이 코드의 여러곳에 반복적으로 난립하게 되는 문제이지요, 의존 그래프의 생성과 주입 전략을 가진 객체가 등장 했으니 이것을 경량 컨테이너 라고 하는 놈 입니다. 제어를 넘겨 받은 컨테이너 이므로 Inversion of Control Container 라는 이름을 얻게 되었습니다. 그런데, IoC Container 라는 이름이 너무 일반적인 용어라서 사람들이 너무 혼란스러워 하게 되었고, IoC Container 가 하는 일이 결국에는 의존을 주입하는 일이기 때문에 Dependency Injection 이라 부르기로 결정했습니다.




그럼 의존을 주입하는 방법이 궁금해 질 것입니다. 의존을 주입하는 방법으로는 
1. Constructor Injection
2. Setter Injection
3. Interface Injection 
의 크게 세가지가 있으며, 주입할 객체를 생성하는 설정을 코드에 내재하거나 설정파일(주로 XML 파일) 을 이용하기도 합니다.


이 포스트는 IoC Container 의 개념을 설명하는 목적으로 여기에서 줄이며, 주입하는 방법까지 설명은 마틴 파울러의 
Inversion of Control Containers and Dependency Injection pattern 글과 이 글을 번역 설명한 행복한 아빠 님의  IoC 와 DI 에 대한 블로그 포스트 시리즈 1, 2, 3 포스트를 읽어보시기 바랍니다.

토비님의 블로그와 저서 스프링 프레임워크 3.0 은 IoC  컨테이너의 자세한 내용을 담고 있습니다. 

마틴 파울러의 [Inversion of Control Containers and the Dependency Injection pattern] 글에 대한 여러 개발자님들의 번역이 있군요. 그 중 SKY-TIGER 님의 번역 글을 링크 합니다. 





참고 :
Inversion of Control Containers and Dependency Injection pattern by 마틴 파울

저작자 표시
신고

이 글을 Twitter / Facebook 에 공유하기
이 글이 유익하다면 아래의 트위터 버튼을 눌러 공유해 주시거나, 페이스북 "좋아요" 버튼을 눌러 주세요.

   


Posted by 반더빌트
리파지터리 패턴은 그 복합성 때문에 완벽히 이해하고 적용할 수 있기까지 매우 어려운 패턴이라 생각됩니다. 여러번에 걸쳐 이 주제를 포스팅 하는 이유가 바로 그 때문입니다. 여러 문서를 학습하거나 구현에 적용할 때에는 관련된 해결해야 하는 문제들이 등장하게 되죠. 패턴이 잘못 사용되지 않도록 하기위해서는 그 패턴이 가지는 정확한 목적을 이해하는 것이 가장 우선시 되는 것이죠.

리파지터리 패턴은 그 역할과 구현이 명확한 개발언어로 스펙으로 정의 된것이 아닌, 일반언어(plain text)로 정의 되어 있음은 많은 개발자들이 정확한 의미를 파악하기 어려울 수 있습니다. MSDN 에 리파지터리 패턴에 잘 정의된 문서가 있어 [문맥] 과 [목표] 문단을 중심으로 번역 포스트 합니다.

이 문서는 리파지터리 구현시에 발생하는 [데이터 조회 로직]가 리파지터리에 들어가려는 현상이 있는데 이렇게 하는 것이 맞느냐 틀리느냐에 대한 근거 수집 차원에서 접근 했으며, 리파지터리의 세부 성격으로 보았을때 조회 로직 자체도 리파지터리로 부터 분리하는 것이 옳다라는 결론을 얻게 되었습니다.  이 결론이 틀리다 생각되시면 의견을 주시어 생각을 바로 잡을 수 있도록 도와 주시기 바랍니다.

Repository는 저장소 라는 용어로 데이터소스에 대한 관리(CRUD)를 어떻게 추상화 하느냐에 대한 패턴입니다.





문맥:

많은 어플리케이션에서 비즈니스 로직은 데이터베이스, 쉐어포인트, 웹서비스와 같은 데이터저장소의 데이터에 접근합니다. 직접접근은 다음과 같은 부작용을 초래할 수 있습니다.

중복된 코드
프로그래밍 에러가 발생할 높은 잠재성
비즈니스 데이터에 대한 오타
캐싱과 같은 데이터-관계 정책 중심화하기 어려움
외부 의존으로 부터 비즈니스 로직을 분리하기 어려움에 따른 테스트 불가능성


목표:

리파지터리 패턴을 사용하는 것은 다음의 목표를 하나 이상 달성합니다.

당신의 수 많은 코드를 테스트 자동화를 극대화하고, 유닛 테스트를 지원하기 위해 데이터 레이어로 부터 분리 시키기를 원한다.
당신은 여러 곳에서 데이터소스에 접근 하고 있으며, 중앙에서 관리되는 일관성 있는 접근 룰과 로직을 적용기를 원한다.
데이터 소스를 위한  캐싱 caching 전략을 중앙화 centralize 하기를 원한다.
데이터 또는 서비스 엑세스 로직으로 부터 비즈니스 로직을 분리함으로써 코드의 유지관리성 maintainability과 가독성 readability  을 향상 시키기를 원한다.
문제를 런타임이 아닌 컴파일 타임에 구분해 낼 수 있도록 비즈니스 엔터티를 강-타입 strongly typed 으로 사용하기를 원한다.
연결된 데이터와 작업하기를 원한다. 예를들어 필드를 계산하기를 원하거나 복합관계를 강제하거나 엔터티의 데이터 엘리먼트 사이의 비즈니스 룰과 작업하기를 원한다.
복잡한 비즈니스 로직을 단순화 시키기 위해 도메인 모델을 적용하기를 원한다.


솔루션:

비즈니스 로직이 모델에 대해서 동작하도록 함으로써 데이터를 조회하는 로직을 분리하기 위해 리파지터리를 사용한다. 비즈니스 로직은 데이터소스 레이어의 데이터 타입에 대해서 자연스러워야 하며, 데이터소스는 데이터베이스, 쉐어포인트 또는 웹서비스가 될 수 있습니다.

리파지터리는 어플리케이션에서 데이터 소스 레이어와 비즈니스 로직 레이어 사이를 중재 mediates 한다. 리파지터리는 데이터소스에 대해 데이터를 질의하고 데이터 소스와 비즈니스 엔터티 사이의 데이터를 매핑한다. 비즈니스 엔터티의 변경을 데이터 소스에 저장한다. 리파지터리는 데이터소스, 웹서비스에 의존적인 상호작용을 비즈니스 로직으로 부터 분리 시킨다. 데이터와 비즈니스 티어의 분리는 다음의 3가지 잇점을 얻게합니다.

1. 데이터로직 또는 웹서비스 접근 로직을 중앙화 한다.
2. 유닛 테스트를 위한 대안을 제공한다.
3. 어플리케이션 진화 될 수 있는 디자인을 채택할 수 있도록 유연한 아키텍처를 제공한다.

리파지터가 비즈니스 엔터티를 질의하는 두가지 방법이 있습니다. 클라이언트 비즈니스 로직에 대한 질의 오브젝트를 제출 하는 방법, 비즈니스 조건을 정의하는 메소드를 사용하는 방법.  후자의 경우 리파지터리는 클라이언트 행동에 대한 질의를 만듭니다. 리파지터리는 질의를 만족하는 엔터티 집합을 반환합니다. 다음의 다이어 그램은  클라이언트,데이터소스 사이에서 리파지터리의 상호작용을 보여줍니다.


리파지터리의 상호작용 다이어그램.




클라이언트는 지속화를 위해 변경되었거나 새로 생성된 엔터티를 리파지터리에 제출합니다. 더 복잡한 상황에서는 Unit of Work 패턴을 사용할 수도 있습니다. 이 패턴은 연관된 의존을 영속화하기 위해서 수행되어야 하는 여러개의 작업을 어떻게 캡슐화 할 수 있는지를 보여 줍니다. 캡슐화된 아이템은 변경/삭제 행위를 위해 리파지터리에 보내 집니다. 이 가이드는 Unit of Work 패턴의 예제를 포함하지 않습니다. 더 많은 정보를 얻길 원하시면 마틴 파울러의 웹사이트의 Unit of Work 페이지를 방문하세요. 

리파지터리는 서로 다른 도메인에서 데이터와 작업 사이의 다리 bridge 입니다. 일반적인 경우는 데이터베이스 또는 쉐어포인트의 약-타입 의 데이터와 도메인의 강-타입 오브젝트에 매핑하는 것입니다.  한가지 예로 데이터베이스는 질의를 실행하기 위해 IDBCommand 오브젝트를 사용하고 IDataReader 오브젝트를 반환합니다. 리파지터리는 데이터소스에 대한 적절한 질의를 발행합니다. 그 결과를 외부로 노출된 비즈니스 엔터티에 매핑합니다. 리파지터리는 그 표현을 번역하기 위해 Data Mapper 패턴을 사용합니다. 리파지터리는 특정 기술에 대한 의존을 클라이언트로 부터 제거합니다. 예를 들어 클라이언트가 프로덕트 데이터를 조회하기 위해 리파지터리를 호출 한다면, 오로지 카탈로그 리파지터리의 인터페이스만을 사용하면 됩니다. 클라이언트는 프로덕트의 정보를 조회하기 위해 데이터베이스의 SQL로 질의 되는지 쉐어포인트의 CAMIL 이 사용되는지 알 필요가 없습니다. 이런 종류의 의존을 분리 시키는 것은 구현에 있어 유연함을 제공합니다.


구현상세:

쉐어포인트 를 예로 든 설명인데 번역 생략합니다. 코드를 이용한 구현 설명은 아니고 개념 설명입니다.

쉐어포인트 리파지터리의 상호작용 다이어 그램.
 




고려사항:


리파지터리 패턴은 코드의 추상화 정도를 증가시킵니다. 이는 이 패턴에 익숙하지 않은 개발자가 코드를 이해하는데 있어 더욱 어렵게 만들 수 있습니다. 이 패턴을 구현하는 것이 수많은 양의 코드 중복을 감소시키지만  관리해야 하는 클래스 수를 증가 시킵니다. 

리파지터리는 서비스와 리스트에 접근하는 코드를 분리하는데 도움을 줍니다. 고립은 독립적인 서비스처럼 다루기 쉽게 만들어 줍니다. 하지만 전형적으로 리파지터리 그 자체를 테스트하는 것은 매우 어렵습니다. 

멀티 스레드 환경에서 캐싱 데이터를 사용할 때 캐쉬 오브젝트에 대한 동기화도 고려해야 합니다. 종종 ASP.NET 캐쉬와 같은 일반적인 캐쉬는 스레드로 부터 안전하지만, 멀티 스레드 환경에서 작동 되는 오브젝트 그 차제에 대해 스레드로 부터 안전하도록 확인해야 합니다.

여러분이 고부하 시스템에서 데이터를 캐싱 한다면 성능 문제가 부가될 수 있습니다. 데이터소스에 대한 동기화 접근을 고려해 보세요. 이는 데이터에 대한 단일 요청만이 수행되도록 보장합니다. 

### 끝.


참고

리파지터리 패턴 구현에는 마틴파울러의 데이터 매퍼 패턴 (Data Mapper pattern)이 함께 사용됩니다.
리파이터리 패턴 구현에는 마틴파울러의 질의객체 (Query Object) 라는 개념이 사용됩니다.
동적, 재사용가능, Single point decision 을 위해서는 명세서 패턴 (Specification pattern) 이 함께 사용됩니다.
질의의 개별 조건에는 Criteria 라는 개념이 사용됩니다.
저작자 표시
신고

이 글을 Twitter / Facebook 에 공유하기
이 글이 유익하다면 아래의 트위터 버튼을 눌러 공유해 주시거나, 페이스북 "좋아요" 버튼을 눌러 주세요.

   


Posted by 반더빌트
존 아킹, 스콧 밀렛의 Professional Enterprise.NET 이  웹지니 장현희님의 번역으로 제이펍에서 출간되었습니다.  엔터프라이즈에 대한 개념이 척박한 닷넷 커뮤니티와 국내 환경에 또하나의 귀중한 책이 번역되 더욱 편하게 공부할 수 있게 되서 매우 반가운 소식입니다. 엔터프라이즈 시스템이 익숙한 분들도 있고, 아닌 분들도 계실 겁니다. 아마도 낮선 분들이 더 많을 것으로 생각됩니다. 이 책은 책의 목차만으로도 내용을 추측 할 수 있을 정도로 매우 직관적으로 저술 되었으며, 엔터프라이즈에 대한 기반 지식을 조금 알고 있다면 술술 읽혀질 정도록 매끄럽게 번역 되었습니다.


엔터프라이즈 닷넷 표지, 출처 웹지니님 블로그 http://www.mvpmagazine.net/40




원서를 펼쳤을 때 공 저자인 아킹이 엔터프라이즈를 알았을 때 느꼈다는 감정에 너무 동감 했기 때문에 읽지 않을 수 없었던 책이며, 번역서를 발견 했을 때 매우 기쁜 책입니다. 엔터프라이즈의 개념을 접하는 분들은 아마 공통적으로 느낄 감정이라고 생각됩니다.

"아킹 씨, 귀하의 경험과 능력은 출중하지만 이력서로 미루어 볼 때 귀하는 엔터프라이즈 분야의 경험이 전무하군요, 아쉽지만 다음에는 함께 일할 수 있는 인연이 있기를 바랍니다"

...

감독관이 말했던 '엔터프라이즈 패턴'에 대해 알아보기 시작했다. 그러나 인터넷에서 엔터프라이즈 아키텍처에 대해 검색했을때, 지난 8년간 내가 해왔던 컴퓨터 프로그래밍을 무용지물로 만드는 완전히 새로운 수준의 소프트웨어 디자인을 발견하고는 머리가 멍해지는 느낌이었다. - 프로페셔널 엔터프라이즈닷넷 - Professional Enterprise.NET, p.3

업계에서 '엔터프라이즈' 라는 용어는 '기업용' 이라는 한정적인 의미로 받아들이는 경향이 있습니다. 이런 생각은 자신의 영역이 기업용의 복잡한 비즈니스를 처리하는 서비스가 아니니 엔터프라이즈 아키텍처는 나와는 관계가 없어 라고 무시 또는 회피하는 경우가 발생합니다. 저는 엔터프라이즈에 대한 저자의 아래의 정의에 동의 합니다.

엔터프라이즈 아키텍처란 무엇인가?

엔터프라이즈 아키텍처 Enterprise architecture 란 주로 조직의 요구를 효과적이고 효율적으로 지원하기 위한 비즈니스 프로세스, 정보의 흐름, 시스템, 애플리케이션, 데이터 그리고 인프라스트럭처 등을 묘사하는 광범위한 프레임워크를 설명하기 위해 사용된다. 

....

개발자의 관점에서 엔터프라이즈 아키텍처란 어떤 의미를 가질까? 엔터프라이즈 아키텍처를 정의한다는 것은 프로세스, 프레임워크, 디자인, 개발 및 배포를 위한 일련의 패턴을 정의하고, 회사나 부서에서 필요로 하는 소프트웨어의 모든 것을 관리한다는 것을 말한다. 이 문장에서 가장 중요한 구문은 소프트웨어의 모든 것 all of software이다. 즉, 엔터프라이즈 아키텍처란 모든 단계의 디자인에서 소프트웨어가 필요로 하는 모든 요소들을 생성하기 위한 통합된 개발 플랫폼이다. -  p.5, p.6


이 책은 에릭 에반스의 도메인-드리븐 디자인 DDD 와 마틴 파울러의 패턴 오브 엔터프라이즈 어플리케이션 아키텍처 PoEAA 에서 제안된 개념들을 닷넷에서 어떻게 적용될 수 있는지, Structuremap, NHibernate 등의 프레임워크가 구현한 개념이 무엇이며 그 적용되는 방법은 무엇인지에 대해 다루고 있습니다. 실제 자신의 프로젝트에 이런 프레임워크를 적용해 보지 않더라도 작동방법을 알 수 있고, 엔터프라이즈의 다양한 주제에 대한 인덱스를 한권의 책을 통하여 제공받을 수 있다는 것은 개발자들에게 매우 행운이 아닐 수 없습니다.

이 책의 좋은 점중 하나는 개념의 도입부에 그 개념이 도출된 히스토리를 담고 있는 것입니다. 이런 내용은 오랜 경험과 같은 것인데 책보다는 사수로 부터 일대일로 전해지는 내용이어서 도자기를 만드는 기술이 그러하듯이 단절되기 쉬운 것이죠.

책 한권을 읽는다고 해서 엔터프라이즈 아키텍처의 모든 것을 알 수 있다고 기대하는 건 아니겠죠? 저자는 서문에서 아래와 같이 밝히고 있습니다.

만일 여러분이 개발에 매우 능하며 블로그와 포럼에 많은 시간을 할애하는 오픈 소스 전문가라면 지금 당장 이 책을 내려놓기 바란다. 이 책은 엔터프라이즈의 모든 것을 다루는 완벽한 참고서가 아니다. 이 책은 테스트 우선 방법론을 강요하지 않는다. 또한 애자일 선언문을 내세우지도 않으며 엔터프라이즈 전문가에게 어필하는 책도 아니다. - 저자 서문 중에서


이 책은 엔터프라이즈 아키텍처의 많은 필수 개념과 최신의 프레임워크들을 소개한다 라는 관점에서 매우 가치있는 책이라 생각됩니다. 포스트의 제목이 적용하기 안내서 인 것은 바로 이 때문입니다.


관련링크
알라딘 책 사러가기 - 가격비교에서 강컴이 2~3천원 더 싸다. 책은 예스24에서 샀다.  <-- 이런 난 뭐니~~~


### 끝.



저작자 표시
신고

이 글을 Twitter / Facebook 에 공유하기
이 글이 유익하다면 아래의 트위터 버튼을 눌러 공유해 주시거나, 페이스북 "좋아요" 버튼을 눌러 주세요.

   


Posted by 반더빌트

도메인-드리븐 디자인 요약의 또하나의 포스트 입니다. DDD를 설명하는 포스트의 번역인데요, 원문에서도 언급하듯이 DDD를 확실히 이해하려면 전반적인 모든 것을 알고 있어야

하고, 알고 있더라도 개인적인 경험에 의존하기 때문에 매우 어렵습니다. 다행이도 전체를 조망하는 통찰력을 가진 글을 읽음으로써 우리는 좀더 쉽게 DDD를 이해할 수 있습니다.

아래에 번역한 포스트가 바로 그런 글입니다.

번역 :

Domain-driven Design
http://powerdream5.wordpress.com/2007/10/15/domain-driven-design/

Domain-Driven Design(DDD)은 제가 존경하는 전문가중의 한명인 Eric Evans(http://domainlanguage.com/)가 변론한 소프트웨어 개발 접근법입니다.  DDD의 주요 목적은 도메인과 도메인 로직에 집중하여 요구사항에서 빗나가지 않게 하는 것입니다.
 
DDD는 유용하다는 것과 전통적인 소프트웨어 개발 방법론의 문제점을 극복할 수 있음을 보여 줍니다. 불행한 점은 DDD를 완전히 이해하는 것은 매우 어렵우며, 여러분의 경험에 매우 의존적이라는 것입니다. 여러분은 또한 실제 프로젝트에 적용하고, 여러분의 경험을 반복해서 집약해야 합니다. 솔직히 말해서 저도 DDD를 조금만 알 뿐입니다. 하지만, DDD에 대한 저의 생각을 나눌것이며 여러분의  댓글을 환영합니다.

Domain-driven design Building Blocks



우리는 도메인 모델에서 그들의 책임을 기준으로 나눌수 있는 5개의 역할을 가지고 있습니다. 5개의 역할은 Enity, Value Object, Factory, Repository 그리고 Services  입니다. 이것들을 저의 지식에 근거하여 설명해 보려 합니다.

       Entity: 엔터티는 사용자와 소프트웨어 개발자 모두에게 관련이 되어 있기 때문에 도메인 모델에서 가장 중요한 부분입니다. 엔터티는 소트프웨어의 상태 변화와 관계없는 아이텐티티를 가지고 있습니다. 다른 말로 하면, 우리는 엔터티를 데이터베이스와 같은 그 어딘가에 저장해야 합니다.

       Value Object: 엔터티는 아이텐티티를 가지고 있고 아이덴티티는 변경될 수 없기 때문에 어플리케이션이 엔터티를 생성하고 추적하는 데에는 비용이 많이 듭니다. 성능을 고려해 보면 도메인 모델의 모든 명사(noun)들을 엔터티로 매핑하는 것은 비합리적 입니다.  Value object 는 아이텐터티가 없으며, 여러분의 도메인 모델의 다른 오브젝트 들이 공유할 수 있는 오브젝트 입니다.

 Domain-Driven Design의 장점을 취하려 할때  엔터티와 value object를 구별하는 것이 우리가 만나는 첫번째 장애물입니다 . 어떤 오브젝트가 아이덴터티를 가져야 할지 말아야 할

지는 전적으로 소프트웨어 개발자가 결정하며, 거기에는 어떤 직접적인 규칙이 없습니다. 저의 의견은 엔터티를 인식하는 일은 오브젝트를 테이블에 매핑하는 것과 유사합니다.

Embedded value 패턴을 기억합니까? 어떤 종류의 오브젝트가 자신의 테이블을 가지고 매핑되어야 하고, 어떤 종류의 오브젝트가 부모 테이블에 매핑되어야 할지? 이 질문에 대한

답은 여러분의 판단 능력과 경험에 달려 있습니다.

         Factory: Factory는 엔터티를 생성할 책임이 있습니다. 일반적으로, 여러분의 도메인 모델에서 엔터티는 항상 다른 오브젝트들과 관계를 가지고 있기 때문에 엔터티를 생성하

는 과정은 복잡합니다. 엔터티를 생성할 때 우리는 관계망을 초기화 해야 합니다. 그래서 엔터티를 생성하는 프로시저를 캡슐화 하는 오브젝트를 정의하는 것은 매우 훌륭합니다.

         Repository:리파지터리는 엔터티를 관리할 책임을 가집니다. 관리란 데이터베이스로 부터 엔터티를 업데이트, 저장, 로딩하는 것을 의미합니다. 리파지터리는 특정 인터페이

스와 인터페이스를 구현하는 구상클래스 집합을 가집니다. 구상 클래스들은 어플리케이션의 영속화 레이어(persistent layer)를 캡슐화 합니다.

              Service: 도메인을 기술한 후에, 명사는 엔터티/value object 로, 동사는 메소드로 매핑할 수 있습니다. 때때로 어떤 동사들은 엔터티/value object 의 메소드로 매핑하는

것은 불합리합니다. 이런 경우에  이런 메소드들을 담는 service라는 이름의 새로운 역할을 만들 수 있습니다. 서비스는 어플리케이션의 과잉을 정의 할 것입니다. 서비스는 클라이언트에 의해 접근 될 것입니다.

이 글을 읽어 주셔서 감사합니다. DDD에 대해 잘못된 이해가 있다면, 어떤 의견도 좋으니 남겨주세요, DDD에 대한 더 많은 정보를 원한다면 이 링크(http://www.infoq.com/minibooks/domain-driven-design-quickly)를 열어 보세요.

신고

이 글을 Twitter / Facebook 에 공유하기
이 글이 유익하다면 아래의 트위터 버튼을 눌러 공유해 주시거나, 페이스북 "좋아요" 버튼을 눌러 주세요.

   


Posted by 반더빌트
TAG ddd


티스토리 툴바