Whiteship's Note


[DDD] User-Familly 구현

JEDI/DDD : 2009.06.22 18:53


User-Familly 관계부터 생각해보면, User가 일방적으로 여러 Familly를 가지고 있다고 볼 수 있습니다. 다중성(?)은 User에서 Familly쪽으로 1:대 관계입니다. (형제 자매가 같이 입사한 경우 다:다가 될 수도 있지만, 드문 경우니깐 중복 데이터 상관하지 않고 일단은 1대다로 ㄱㄱ, ) 생명주기를 생각해보면, Familly가 User에 종속되어 있습니다. 타입을 생각해보면 User는 엔티티가 거의 확실하고, Familly는 Value 타입에 가까운 듯 합니다. 하지만 편의상 id를 주고 관리하렵니다.

자 그럼 이제 필요한 도메인 클래스를 추가하고 속성들을 만든 다음 관계를 명시합니다.

class User {
...
    @OneToMany(cascade = { CascadeType.ALL })
    Set<Familly> famillies;
...

}

여기서 준 @OneToMany로 다중성이 어떤지 나타나고, Familly의 생명주기가 User에 종속적이라는 것이 드러납니다.

다음은 UserController(UC)로 갑니다. FamillyController를 만들 필요 없이, Familly와 연관되는 부분과 관련하여 그 요청을 UC가 처리하게 합니다. 화면상으로는 User의 수정화면에서 Familly 그리드가 보이고, 거기에 추가하는 버튼과, 수정하는 버튼이 달려있습니다.


새로 개선한 OSAF를 사용하여 만든 컨트롤러에 Familly를 그리드, 추가, 수정을 다룰 핸들러 메서드를 추가했습니다.

@Controller
@RequestMapping("/base/user/*.do")
public class UserController extends GenericController<User, UserService, UserRef, UserValidator, UserParams>{

    public UserController() {
        super(User.class);
    }

    @Autowired FamillyValidator famillyValidator;

    @RequestMapping
    public void famillygrid(@RequestParam int userid, ModelMap model, OrderPage orderPage){
        if (orderPage.getOrder() == null) orderPage.setOrder("name asc");
        model.addAttribute("list", service.findFamilliesBy(userid));
        model.addAttribute("orderPage", orderPage);
    }

    @RequestMapping(value="/base/user/famillyadd.do", method=RequestMethod.GET)
    public void famillyadd(ModelMap model){
        model.addAttribute("model", new Familly());
    }

    @RequestMapping(method=RequestMethod.POST)
    public String famillyadd(int userid, @ModelAttribute("model") Familly familly, BindingResult result,
            SessionStatus status){
        famillyValidator.validate(familly, result);
        if (result.hasErrors())
            return "/base/user/famillyadd";
        else {
            service.addFamilly(userid, familly);
            status.setComplete();
            return CommonPages.CLOSE_GRID_REFRESH;
        }
    }

    @RequestMapping(value="/base/user/famillyupdate.do", method=RequestMethod.GET)
    public void famillyupdate(int famillyid, ModelMap model){
        model.addAttribute("model", service.findFamillyById(famillyid));
    }


}

thin facade 역할을 하고 있는 service를 이용하고 있습니다.

@Service
@Transactional
public interface UserService extends GenericService<User, UserParams>{

    Set<Familly> findFamilliesBy(int userid);

    void addFamilly(int userid, Familly familly);

    Familly findFamillyById(int famillyid);

}

인터페이스에 추가해주고,,, 실제로 하는 일은 대부분이 도메인 또는 dao로 위임하는 것입니다.

@Service
@Transactional
public class UserServiceImpl extends
        GenericServiceImpl<User, UserParams, UserDao> implements
        UserService {

    public Set<Familly> findFamilliesBy(int userid) {
        return get(userid).getFamillies();
    }

    public void addFamilly(int userid, Familly familly) {
        get(userid).addFamully(familly);
    }

    public Familly findFamillyById(int famillyid) {
        return dao.fingFamillyById(famillyid);
    }

}

그럼 도메인에서 할 일은 도메인에서 처리를 하고..

    public Set<Familly> getFamillies() {
        if (famillies == null)
            famillies = new HashSet<Familly>();
        return famillies;
    }

    public void addFamully(Familly familly) {
        getFamillies().add(familly);
    }

DAO에서 할일은 DAO에서 처리합니다,

    public Familly fingFamillyById(int famillyid) {
        return (Familly) getSession().createQuery(
                "from Familly where id = " + famillyid).uniqueResult();
    }

어디서 처리하든 tx facade 역할을 하고 있는 service를 거쳐왔기 때문에, 트랜잭션 처리가 됩니다.

ps: 스프링 @MVC 혹은 OSAF의 버그(?) 발견..

    @RequestMapping(value="/base/user/famillyadd.do", method=RequestMethod.GET)
    public void famillyadd(ModelMap model){
        model.addAttribute("model", new Familly());
    }

여기서 @RequestMapping의 value를 주지 않아도(CoC로 인해 같은 결과가 나와야 함) 똑같이 동작해야 하는데, 생략할 경우, seach.do를 실행할 때(위 메서드와는 전혀 관계 없는 OSAF GenericController의 update() 메서드 시그너쳐 int id를 Integer로 바꾸라는 에러가 발생함.. @_@)


'JEDI > DDD' 카테고리의 다른 글

[DDD] User-Familly 구현  (0) 2009.06.22
[DDD] Whiteship's DDD 아키텍처 수정  (6) 2009.06.16
[DDD] Whiteship's DDD 아키텍처  (10) 2009.06.12
[DDD] DDD 입문에 좋은 글  (4) 2009.06.11
파트 3: Refactoring Toward Deeper Insight  (0) 2008.10.24
Factories  (0) 2007.12.25
Aggregates  (0) 2007.12.18
Modules  (2) 2007.12.14
Services  (2) 2007.12.13
DAO vs Repository  (4) 2007.12.04
DTO(Data Transfer Object)  (2) 2007.11.21
top

TAG 1대다, DDD, OSAF

Write a comment.


[DDD] Whiteship's DDD 아키텍처

JEDI/DDD : 2009.06.12 11:23


기대는 하지 마시구요. @_@ 기존 틀(빈약한 도메인 객체 + 두꺼운 서비스 계층)에서 벗어난다는게 이렇게 머리 아픈 일인지 몰랐습니다. DDD 공부라도 제대로 했었어야 하는데.. 역시 개념없는 코드와 코드 없는 개념은 아무것도 아닌 것 같아요. 힘 없는 정의와 정의없는 힘처럼... 각설하고.. 오늘 구현해볼 아키텍처를 그려봤습니다.



일단 Web 계층에서는 Application 계층에 있는 Thin Facade 내지 서비스를 호출할 겁니다.

Thin Facade는 도메인 객체로 대부분의 역할을 위임할 겁니다.

도메인 계층에서는 Thin Facade로 부터 어떤 일을 위임 받은 도메인 객체는 비즈니스 로직을 담당할 것이고
- 컬렉션에 저장, 조회 등의 작업을 할 때는 계층에 위치한 Repository를 이용할 겁니다. 여기서 Repository는 DAO와는 개념이 다르다(참조: http://aeternum.egloos.com/1160846)는 것에 주의해 주세요.
- Repository는 모든 Entity가 아닌, Entry Point에 해당하는 Entity에 대한 것만 만들 겁니다.
- Email, JMS 등의 기능이 필요하다면 Infrastructure에서 제공하는 서비스를 이용할 겁니다.

시나리오 1: User


UserController가 요청을 받으면 UserFacade가 이 요청을 받아서 User의 특정 메서드를 호출하고, User는 UserRepository를 사용하여 원하는 작업을 한다.

시나리오 2: User->Address


위 상황에서 Value 타입인 Address가 추가 됐을 때 모습으로 별반 달라진 건 없음. Value 타입이 Entity 타입과 어떤 차이가 있는지 보여주는 시나리오.

시나리오 3: User->Address, Order


Order라는 새로운 Entity이자 Entry Type이 추가되자 Controller, Facde, Repository, Dao가 추가된다. User와 Order는 양방향 관계로 서로가 서로를 참조한다. 비즈니스 요구사항에 따라 방향성은 달라질 수 있다. 또한 현재는 각자가 자신의 Repository만 참조하고 있는데, 이 모습도 비즈니스 요구사항에 따라 달라질 수 있다. 중요한 건, 비즈니스 요구사항에 따라 도메인 객체만 변경하면 될 뿐, 나머진 그대로라는 것이다.

주의 할 것은 전체 아키텍처에서도 그렸듯이 도메인 계층에서 Application 계층을 참조하지 않는다는 것이다. Application 계층을 참조할 일이 있다는 것은 도메인 계층이 다시 Application 계층으로 일을 넘긴다는 것인데, 그렇게 되면 Thin Facade라는 가정이 어긋나게 되고 비즈니스 로직이 Application 계층쪽으로 새어나가게 될 것이다.

시나리오 4: User->Address, Order->OrderLine


이번에는 새로운 Entity OrderLine을 추가했다. 하지만 이 Entity는 Entry Point가 아니라 Order에 종속된 생명주기를 지나고 있다. 따라서 Order가 OrderLine까지 같이 관리하며 OrdeLineRepository는 만들지 않는다. 대신 Infrastructure에 OrderLineDao를 추가하여 OderRepository가 OrderLine을 DB에 넣을 때 이용할 수 있게 도와준다.

이제 구현해보는 일만 남았군요. 캬~~ 코딩하기 전에 그림 그려보는 것도 좀 도움이 되네요. 코딩하면서 계속 디자인을 바꾸니깐.. 테스트고 뭐고.. @_@ 일단 저렇게 큰그림 잡고 조금씩 테스트 해 가면서 기왕이면 TDD로 ㄱㄱ 해보렵니다! 파이팅!! 오늘은 이거 못 만들면 퇴근 못하니깐...ㄷㄷㄷㄷㄷ... 내일 스터디는 밤새고 가야할지도...??? 헤헷 후딱 하고 퇴근해버려야지~

'JEDI > DDD' 카테고리의 다른 글

[DDD] User-Familly 구현  (0) 2009.06.22
[DDD] Whiteship's DDD 아키텍처 수정  (6) 2009.06.16
[DDD] Whiteship's DDD 아키텍처  (10) 2009.06.12
[DDD] DDD 입문에 좋은 글  (4) 2009.06.11
파트 3: Refactoring Toward Deeper Insight  (0) 2008.10.24
Factories  (0) 2007.12.25
Aggregates  (0) 2007.12.18
Modules  (2) 2007.12.14
Services  (2) 2007.12.13
DAO vs Repository  (4) 2007.12.04
DTO(Data Transfer Object)  (2) 2007.11.21
top

  1. 2009.06.12 13:50 PERM. MOD/DEL REPLY

    비밀댓글입니다

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.06.12 15:08 신고 PERM MOD/DEL

    제 학습 로드맵을 요구하시는거군요?
    흠;; 하도 이것 저것 공부해서 로드맵이 어떻게 되는지 기억도 안나는데요.. 쉴 때 정리해 보겠습니다.

  2. Favicon of http://moova.tistory.com BlogIcon moova 2009.06.14 02:08 PERM. MOD/DEL REPLY

    기선군에게 로드맵을 달라고 하는 분이 있네요. 비밀댓글 상상하기~ㅋ
    그나저나 데이터베이스는 언제 공부할꺼임? 로드맵이 필요하면 단기 숙성 로드맵이 나한테 있긴 있는데....

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2009.06.14 09:34 PERM MOD/DEL

    그러게요. DB 공부도 해야되는데;; DB 만들고 지우는 일밖에 할 게 없으니.. @_@

  3. Favicon of http://blog.lckymn.com BlogIcon Kevin 2009.06.14 22:32 PERM. MOD/DEL REPLY

    공부하자 마자 또 뚝딱뚝딱 금새 만드셨네요. 역시 멋지십니다. ^O^_b
    한참 해오던거 탈피하는게 쉽지 않죠.
    전 2학년 1학기 마치고, 완전한 DDD는 아니지만
    자연스럽게 DDD 스타일의 디자인 습관이 생겼었는데...
    (DDD를 배운건 아닌데, 그 과목에서
    Domain Modeling의 중요성에 대해 강조를 하다보니 그렇게 되더군요.)
    근데, 마지막 학년 마지막 학기에
    Java web app. development쪽을 좀더 공부하려고
    J2EE 과목을 들었더니... 그 망할 EJB (그것도 2.0) 때문에
    혼란이 오더군요.

    가령 JavaBean 만드는데, Order 같은거 합계 계산하는 method를
    Order bean에 넣었는데, JavaBean은 자료 전달만 해야한다고... :O
    실제 돌아가는 EJB하나 만드는데, Home, Remote interface를 꼭 만들어야하고,
    암튼 그래도 믿었습니다. EJB가 표준인데다가, 여러 기업들이 참여해서 만든거라서...

    그러다보니 졸업후에 EJB의 문제점을 알게되서 이거 없이 개발을 해도,
    스타일이 비슷하게 가더라구요. 그러다가 로드 존슨이 강의한 영상을 보고,
    '아... EJB한테 당했다!' 라는 느낌이...ㅠ_ㅠ
    암튼 그 영상에서 DDD도 알게 되고, 바로 에릭 에반스가 강의한것도 찾아보고
    전에는 그냥 감으로 하던 도메인 모델링이
    체계가 잡혀 있다는것도 알게 되고, 참 좋더라구요. :)
    진작에 스프링에 손댈껄 그랬다는 후회도 되구요.
    암튼 늘 하던 방식 탈피하는데는 정말 노력이 필요하더군요.

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2009.06.15 14:16 PERM MOD/DEL

    ㅋㅋ금새는 아니에요. 저 그림도 몇 번이나 고치고 다듬은건지 모르겠네요. 아직 DDD도 잘 모르는 상태에서 그린거라 DDD랑 안 어울리는 부분도 있을 것 같습니다.

    저는 애초에 EJB는 보지도 않고 스프링으로 개발을 시작해서 이전에 얼마나 불편했었는지 어깨너머로 들은게 전부라.. 공감할 만한 경험이 없네요.ㅎㅎ;

    로드존슨 아저씨 덕분에 개발자로 일하고 있는 것 같아서 항상 맘속에 고마움을 느끼고 있답니다.

  4. Favicon of http://blog.lckymn.com BlogIcon Kevin 2009.06.14 22:39 PERM. MOD/DEL REPLY

    아... 근데 저기 Repository에 DAO가 또 필요한 건가요?
    제 생각엔 좀 중복 되는거 같은데요.
    Repository interface를 implement 하는 class가 DAO를 대신해야 하는거
    아닐까 하는 생각이 듭니다만...
    따로 DAO를 가지게 되면 Repository 이외에도 해당 Entity를 찾을수 있는 객체가
    존재한다는 얘기니 중복되는게 아닌가 하는 생각이 들어서 말이죠.
    Infrastructure는 Hibernate 같은 ORM이 되어야 하는게 아닐까 싶습니다만...
    제가 뭐 잘알고 하는 얘긴 아니고, 저는 DDD초급자라서 제의견과 함께
    가르침을 구하는 겁니다...^^;

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2009.06.15 14:22 PERM MOD/DEL

    네, 저 둘은 어찌보면 중복으로 보이죠.

    그런데 제가 만든 DAO가 너무 하이버네이트 기술에 의존해 있다보니, 객체 컬렉션으로 인식해야 할 Repository랑은 잘 안 어울리는 것 같기도 하고,

    DAO는 GenericDAO를 상속 받아서 기본적인 DAO 기능들 + 하이버네이트 기능(flush, clean 같은것)까지 포함한 것을 제공하는 반면 Repository는 왠만하면 도메인에서 실제로 사용하는 메서드들만 두기 위해서 구분지었습니다.

    어느 글인지는 모르겠는데, 여기 저기 DDD관련 코드를 뒤적거리다가 Repository가 DAO를 가지고 있는 코드를 봤었는데, 거기서 착안해서 저렇게 그렸고 구현했습니다.

    기능적으로 중복이기는 한데, Entity가 DAO를 직접 사용하지 않고, Repository를 거쳐서 사용하게끔 할 생각입니다.

  5. Favicon of http://blog.lckymn.com BlogIcon Kevin 2009.06.15 21:41 PERM. MOD/DEL REPLY

    아... 그렇군요.
    제 생각에는 사용 기술보다 Problem Domain에게 영향을 더 받는
    Repository와 사용기술에 종속적인 DAO를 같이 쓰면
    기술적 제약에 따라 디자인 자체가 변경되는 문제가 생길것 같아서 말이죠.

    가령 DAO는 자체 디자인이 변경될 가능성이 Domain modeling 을 통해 만들어진
    object 보다 높으니, 이게 변경되면 DAO만 변경되는게 아니라
    이걸 쓰는 Repository 내부도 변경을 해야하니 유지보수에 도움이 되지 않을것 같아서요.

    디자인 자체가 바뀌지 않으면 내부적으로는 아무리 바뀌어도
    해당 디자인을 사용하는 객체들에게 크게 영향을 미치지 않을텐데
    DAO를 쓰다보면 이녀석의 디자인자체가 바뀔 가능성이 있어서 말이죠.

    아무튼 이건 제 생각이구요.
    기선님 방법도 궁금하니, 해보시고 가능하면
    결과 공유 좀 해주시면 좋겠네요. :)
    저도 나름대로 이거저거 해보고 공유하겠습니다. ^^;

    그리고 기선님께서 소개하신 글 보고 방문한 이터너티님의 블로그에서
    좋은글을 하나 발견했습니다.
    http://aeternum.egloos.com/1160846

    아...
    참고로, 이미 보셨을지도 모르지만,
    Eric Evans의 저서 Domain-Driven Design 에서
    Repository 안에 SQL 쿼리와 일정부분의 DB access 를
    구현한 코드를 본적이 있습니다.
    물론 개념을 제공하기 위한 예제 코드라서 완벽한 해답이라고
    할수는 없겠지만요.

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2009.06.15 23:26 PERM MOD/DEL

    네 저도 저 글을 읽어봤습니다.

    Repository에 필요한 기능을 구현하려다 보니 DAO가 바뀔 수는 있을 지언정, DAO가 독립적으로 자주 바뀔 일이 있을지는 잘 모르겠습니다.

    아직 설계만 잡아두고 구현을 충분히 하지 못해서 실용적인 디자인이지는 잘 모르겠습니다. DDD 학습도 충분치 못해서 DDD 아키텍처라고 내세우기도 좀 그렇구요. 둘 모두 구현해 가면서 차차 다듬어 봐야겠습니다.

    물론, 모든 내용은 될 수 있는 한 공유할 생각입니다. 항상 좋은 의견 감사합니다.

Write a comment.


[DDD] DDD 입문에 좋은 글

JEDI/DDD : 2009.06.11 12:45


여기에 왕창있더군요. 사부님이 읽고 공부하라고 적극 추천해주는 바람에 출근해서 지금까지 모두 정독해버렸습니다. 개념 설명도 충분하고 중간 중간 코드도 같이 주셔서 이해하기가 더 좋았습니다. TDD까지 권하시는 센스.. 캬~~ 읽으면서 많이 감탄했네요.

이터니티님 감사합니다. 잘 읽었습니다~ 계속해서 연재해 주세요~

2009/03/25   Domain-Driven Design의 적용-4.ORM과 투명한 영속성 4부 [1]
2009/02/27   Domain-Driven Design의 적용-4.ORM과 투명한 영속성 3부
2009/02/23   Domain-Driven Design의 적용-4.ORM과 투명한 영속성 2부
2009/02/15   Domain-Driven Design의 적용-4.ORM과 투명한 영속성 1부
2009/01/18   Domain-Driven Design의 적용-3.Dependency Injection과 Aspect-Oriented Programming 7부 [2]
2009/01/02   Domain-Driven Design의 적용-3.Dependency Injection과 Aspect-Oriented Programming 6부
2008/12/24   Domain-Driven Design의 적용-3.Dependency Injection과 Aspect-Oriented Programming 5부 [2]
2008/12/17   Domain-Driven Design의 적용-3.Dependency Injection과 Aspect-Oriented Programming 4부
2008/12/13   Domain-Driven Design의 적용-3.Dependency Injection과 Aspect-Oriented Programming 3부
2008/12/09   Domain-Driven Design의 적용-3.Dependency Injection과 Aspect-Oriented Programming 2부
2008/12/05   Domain-Driven Design의 적용-3.Dependency Injection과 Aspect-Oriented Programming 1부
2008/11/30   Domain-Driven Design의 적용-2.AGGREGATE와 REPOSITORY 5부
2008/11/27   Domain-Driven Design의 적용-2.AGGREGATE와 REPOSITORY 4부
2008/11/25   Domain-Driven Design의 적용-2.AGGREGATE와 REPOSITORY 3부
2008/11/23   Domain-Driven Design의 적용-2.AGGREGATE와 REPOSITORY 2부
2008/11/20   Domain-Driven Design의 적용-2.AGGREGATE와 REPOSITORY 1부
2008/11/17   Domain-Driven Design의 적용-1.VALUE OBJECT와 REFERENCE OBJECT 4부
2008/11/17   Domain-Driven Design의 적용-1.VALUE OBJECT와 REFERENCE OBJECT 3부
2008/11/16   Domain-Driven Design의 적용-1.VALUE OBJECT와 REFERENCE OBJECT 2부
2008/11/15   Domain-Driven Design의 적용-1.VALUE OBJECT와 REFERENCE OBJECT 1부 [2]


'JEDI > DDD' 카테고리의 다른 글

[DDD] User-Familly 구현  (0) 2009.06.22
[DDD] Whiteship's DDD 아키텍처 수정  (6) 2009.06.16
[DDD] Whiteship's DDD 아키텍처  (10) 2009.06.12
[DDD] DDD 입문에 좋은 글  (4) 2009.06.11
파트 3: Refactoring Toward Deeper Insight  (0) 2008.10.24
Factories  (0) 2007.12.25
Aggregates  (0) 2007.12.18
Modules  (2) 2007.12.14
Services  (2) 2007.12.13
DAO vs Repository  (4) 2007.12.04
DTO(Data Transfer Object)  (2) 2007.11.21
top

TAG DDD
  1. Favicon of https://helols.tistory.com BlogIcon is윤군 2009.06.11 13:55 신고 PERM. MOD/DEL REPLY

    Thank U~~~~~~~~~~~~~ ㅋㅋ(영어 필터 대박..ㅋ)

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.06.11 13:58 신고 PERM MOD/DEL

    긁어오기 밖에 안했는데 고맙긴

  2. Favicon of http://flyburi.com BlogIcon 버리 2009.06.11 21:32 PERM. MOD/DEL REPLY

    와우 DDD가 이렇게 정리가 잘되어 있을줄이야.. 새로운 글의 발견 +_+ 감사~

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2009.06.11 22:44 PERM MOD/DEL

    넹~

Write a comment.


파트 3: Refactoring Toward Deeper Insight

JEDI/DDD : 2008.10.24 13:05


리팩터링 수준

다른 책들은 너무 로우 레벨로 얘기하는데 그 보다는 도메인에 대한 통찰을 통한 또는 모델이 말하고자 하는 바를 분명하게 하는 것이 시스템의 실용성에 더 지대한 영향을 주는 리팩터링 이라는 이야기..
The refactorings that have the greatest impact on the viability of the system are those motivated by new insights into the domain or those that clarify the model's expression through the code.
Deep Model

모델을 좀 더 심도있게 바라보도록.. 피상적인 모습으로만 축출한 모델이 다가 아니라는거...
A deep model provides a lucid expression of the primary concerns of the domain experts and their most relevant knowledge while it sloughs off the superficial aspects of the domain.
Supple Design

변경을 반영할 수 있는 설계가 되어야 한다.

In a process of constant refactoring, the design itself needs to support change.
Deep Model과 Supple Design은 Model-Driven Design을 뒷받침하는 두 개의 축이다.
A MODEL-DRIVEN DESIGN stands on two legs. A deep model makes possible an expressive design. At the same time, a design can actually feed insight into the model discovery process when it has the flexibility to let a developer experiment and the clarity to show a developer what is happening.
The Discovery Process

좋은 모델을 찾아가는 과정은 개인의 창의성에 달려있기도 하지만, 여러 패턴을 따를 수도 있겠다.
You will usually depend on creativity and trial and error to find good ways to model the concepts you discover, but sometimes someone has laid down a pattern you can follow.

가끔은 이론적인 얘기로 머리를 환기시키는 것도 좋네요.

'JEDI > DDD' 카테고리의 다른 글

[DDD] User-Familly 구현  (0) 2009.06.22
[DDD] Whiteship's DDD 아키텍처 수정  (6) 2009.06.16
[DDD] Whiteship's DDD 아키텍처  (10) 2009.06.12
[DDD] DDD 입문에 좋은 글  (4) 2009.06.11
파트 3: Refactoring Toward Deeper Insight  (0) 2008.10.24
Factories  (0) 2007.12.25
Aggregates  (0) 2007.12.18
Modules  (2) 2007.12.14
Services  (2) 2007.12.13
DAO vs Repository  (4) 2007.12.04
DTO(Data Transfer Object)  (2) 2007.11.21
top

Write a comment.


Factories

JEDI/DDD : 2007.12.25 00:12


Entity와 Aggregate는 보통 생성자에서 만들기는 너무 복잡해질 정도로 커지는 경향이 있다.

보통 객체를 요구하는 쪽에서 여러 인자들과 함께 생성자를 호출한다. 이러면 객체를 생성할 때 너무 많은 정보들을 알게 된다. 즉, 객체에 대한 클라이언트들이 객체 생성에 관한 정보를 알게 되는 것이고, 이 것은 도메인 객체와 Aggregate에 대한 Encapsulation을 깨트린다.

실제에서도 플라스틱, 고무, 철, 실리콘 등으로 프린터를 직접 만들진 않는다. 이런 복잡한 것들을 포함시키면 이해하기 어려운 설계가 된다. 따라서 복잡한 객체 생성 과정을 캡슐화하는 새로운 개념이 필요하다. 그게 바로 Factory다.

객체 생성 과정을 원자화Atomic하는 것은 중요하다. 그렇지 않으면, 만들다 만 객체를 생성할 수도 있다. 특히 Aggregate의 경우에 그렇다. 객체 생성이 실패하면, 예외를 발생시켜서 잘못된 값이 전달되지 않도록 해야한다.

따라서 복잡한 객체나 Aggregate 객체를 생성하는 책임을 별도의 객체로 위임하는 것이 좋다. 인터페이스를 제공하여 클라이언트가 구현 클래스에 직접 접근할 필요가 없도록 하라.

Factory와 관련된 GoF의 Design Pattern 중에 Factory Method 패턴과 Abstract Factory 패턴이 있다. 디자인 관점이 아니라 도메인 모델링 관점에서 살펴보겠다.

사용자 삽입 이미지
참조 : http://en.wikipedia.org/wiki/Factory_method_pattern

Factory Method는 다른 객체를 생성하는데 필요로 하는 정보를 가지고 숨겨둔 객체 메소드이다. 이것은 클라이언트가 Aggregate에 속한 객체를 얻고 싶을 때 유용하다. Aggregate 루트에 객체 생성을 책임지는 메소드를 추가하면 된다.

사용자 삽입 이미지
참조 : http://www.dofactory.com/Patterns/PatternAbstract.aspx

Abstract Factory는 객체 생성이 더 복잡하거나 객체 생성이 여러 개의 객체 생성을 포함하고 있는 경우에 사용한다. 예를 들어, Aggregate를 생성할 때, 그에 대한 책임을 별도의 Factory 객체에게 위임할 수 있다. Factory를 만드는 것은 객체 캡슐화를 위배하기 때문에 주의깊게 사용해야 한다.

Entity Factory와 Value Object Factory의 차이점. Value Object는 변하지 않는immutable 객체기 때문에, 한 번 만들어 지면 변하지 않아야 한다. Entity 는 immutable하지 않다. 매번 변하며, 식별성identity을 가지고 있다.

다음의 경우 Factory보다는 생성자를 사용하는게 좋다.
  • 객체 생성이 복잡하지 않을 때.
  • 객체 생성이 다른 객체 생성 과정을 포함하고 있지않으며, 오로지 인자로 넘어온 값들만 필요로 할 때.
  • 클라이언트가 구현 과정에 관심이 있을 때.
  • 계층구조가 없는 단순한 타입일 때. 어떤 구현체를 제공해야 할지 선택할 필요가 없기 때문에..
Entity 객체를 가져올 때 주의해야 할 것은 DB의 identity와 객체의 identity를 맞춰주어야 한다는 것이다.

'JEDI > DDD' 카테고리의 다른 글

[DDD] User-Familly 구현  (0) 2009.06.22
[DDD] Whiteship's DDD 아키텍처 수정  (6) 2009.06.16
[DDD] Whiteship's DDD 아키텍처  (10) 2009.06.12
[DDD] DDD 입문에 좋은 글  (4) 2009.06.11
파트 3: Refactoring Toward Deeper Insight  (0) 2008.10.24
Factories  (0) 2007.12.25
Aggregates  (0) 2007.12.18
Modules  (2) 2007.12.14
Services  (2) 2007.12.13
DAO vs Repository  (4) 2007.12.04
DTO(Data Transfer Object)  (2) 2007.11.21
top

TAG DDD, FACTORY

Write a comment.


Aggregates

JEDI/DDD : 2007.12.18 14:33


Aggregate는 객체의 소속Ownership과 경계Boundary를 정의하기 위해 사용하는 도메인 패턴이다.

모델은 많은 도메인 객체들을 포함하고 있을 것이며, 이 도메인 객체들은 서로 거미줄처럼 연결되어 있을 것이다. 실제 도메인에서의 연관 관계는 코드와 DB에도 그대로 반영되어야 한다. 마치 한 사람의 고객이 계좌 하나를 가지고 있을 때 Customer와 Account 테이블처럼 말이다.

모델이 복잡해지는 것을 막기 위해서 최대한 간단하고 이해 가능한 수준으로 작성하려 할 것이다. 그러기 위해서 많은 시간을 모델들 사이의 관계를 제거하거나 단순화 하는데 소비한다. 하지만 1:1, 1:다, 다:다 등의 관계를 단순화하는 작업이 그리 간단하지 않은 것 같다.

Invariant도 마찬가지로 신경써야한다. Invariant는 데이터가 변경되더라도 유지되어야 할 규칙을 이야기한다. 하지만 복잡한 관계에서 변경은 도메인 객체에 해를 끼칠 수도 있다. 그래서 신중한 롹킹으로 여러 사용자들이 데이터를 동시에 사용할 수 있도록 한다.

그래서 Aggregate가 필요하다.

사용자 삽입 이미지

Aggregate는 데이터 변경에 영향을 받는 객체들을 하나의 유닛으로 묶어놓은 그룹이다. Root에 해당하는 Entity 객체를 통해서 외부와 내부의 객체들 사이를 경계짓고 있다. 경계 내부에 또 다른 Entity가 있을 때 해당 Entity의 identity는 aggregate 내부에서만 통용되는 지역적인 identity이다.

이렇게 되어있을 때 무경성을 지키는것이 훨씬 편하다. 외부에서 내부에 있는 객체들에 바로 접근할 수 없으며, 최상위 Entity 객체를 통해서 조작되기 때문이다.

또한 내부의 객체에 대한 복사본을 외부로 전달하는 것이 가능하다. 이렇게 되면, 외부에서 해당 객체를 지지고 볶아서 구워 삶아 먹든 별 문제가 없을 것이다.

내부의 객체들은 외부에 있는 다른 Aggregate의 Entity를 참조할 수 있다.
최상위 Entity는 Gloval Identity를 가지고 있다.

'JEDI > DDD' 카테고리의 다른 글

[DDD] Whiteship's DDD 아키텍처 수정  (6) 2009.06.16
[DDD] Whiteship's DDD 아키텍처  (10) 2009.06.12
[DDD] DDD 입문에 좋은 글  (4) 2009.06.11
파트 3: Refactoring Toward Deeper Insight  (0) 2008.10.24
Factories  (0) 2007.12.25
Aggregates  (0) 2007.12.18
Modules  (2) 2007.12.14
Services  (2) 2007.12.13
DAO vs Repository  (4) 2007.12.04
DTO(Data Transfer Object)  (2) 2007.11.21
DDD: putting the model to work  (4) 2007.11.20
top

TAG Agrregate, DDD

Write a comment.


Services

JEDI/DDD : 2007.12.13 22:09


DDD Quickly 읽다가 정리합니다.

유비쿼터스 언어를 조사하다 보면 명사는 객체로 동사는 객체의 메소드로 연관시키는 경우가 많다. 그러나 그 중 몇몇은 특정 도메인 객체 어디에도 속하지 않는듯한 동사가 있다. 이러한 것들을 서비스로 등록하라.

예를들어, 예금이체 같은 동사는 Account 라는 두 개의 객체 중 보내는 객체 쪽에 둬야 할까 받는 쪽에 둬야 할까?

서비스는 절대로 도메인 객체에 지녀야 할 행위를 가지고 있어서는 안 된다.

1. 서비스에 의해 수행되는 작업은 Entity나 Value Object에 속하지 않는 도메인 컨셉이다.
2. 수행되는 작업은 도메인에 있는 다른 객체를 참조한다.
3. 작업은 상태 정보를 유지하지 않는다. Stateless

서비스를 사용하면서도 도메인 계층을 독립시키는 것이 중요하다.

사용자 삽입 이미지

서비스는 위 그림처럼 별도의 계층으로 존재하는 것이 아니라, 도메인 객체들과 연관된 서비스라면 도메인 계층에 두고, 애플리케이션 계층과 관련이 있다면 애플리케이션 계층에 둔다고 합니다. 그래서 서비스를 대체 어디에 두어야 할지 결정하는 일이 좀 어렵다고 나와있네요.

예금이체 같은 경우는 도메인 계층에 둘 것이고, 도메인과 관련되어 있진 않지만 애플리케이션에 꼭 필요한 역할...트랜잭션이나 로깅 같은 것들은 애플리케이션 계층에 두면 되겠군요. 이런 것들은 근데 Aspect로 처리하면 될 것 같고 흠.. 폼에 입력된 데이터를 검증할 Validator 같은 녀석들은 어떨까요. 이런것도 애플리케이션 계층에 속하겠죠?

내일은 Module...

'JEDI > DDD' 카테고리의 다른 글

[DDD] DDD 입문에 좋은 글  (4) 2009.06.11
파트 3: Refactoring Toward Deeper Insight  (0) 2008.10.24
Factories  (0) 2007.12.25
Aggregates  (0) 2007.12.18
Modules  (2) 2007.12.14
Services  (2) 2007.12.13
DAO vs Repository  (4) 2007.12.04
DTO(Data Transfer Object)  (2) 2007.11.21
DDD: putting the model to work  (4) 2007.11.20
Building Domain Knowledge  (0) 2007.01.03
What Is Domain-Driven Design  (2) 2007.01.02
top

  1. Favicon of http://truthiness.pe.kr BlogIcon ongs 2007.12.14 11:21 PERM. MOD/DEL REPLY

    홋 . 좋은 포스팅~! Module 을 기대합니다.~

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2007.12.14 22:38 PERM MOD/DEL

    ㅋㅋ오늘이 가기전에 정리해보겠습니다.

Write a comment.


TSE 2006(Applying Domain Design in the Enterprise with AspectJ)

Spring/TSE 2006 : 2007.12.06 09:27


AspectJ In Action의 저자답게 AspectJ로 DDD를 돕는 여러가지 방법을 설명해줬습니다.

• Overview of Domain-driven design
• Aspects for crosscutting infrastructure
• Aspects for fine-grained DI
• Aspects for domain logic
• Aspects for enforcing DDD best
practices
• Proceeding towards DDD

이런 순서대로 발표가 진행됐는데, 토비님께서 마소에 기고하셨던 내용과 비슷한 내용들이 초반에 언급되었고 그 뒤로는 AspectJ를 사용하여 DDD 구현에 도움이 되는 방법들을 소개해 줬습니다.
  1. Service Layer에서 Aspect성 기능들을 Aspect로 구현하기.
  2. Aspect 사용해서 Repository나 Facade나 Service 객체들을 도메인에 DI 하기.
  3. 도메인 로직 중에 Aspect성 기능들을 Aspect로 구현하기.
  4. 아키텍처 정책을 수행하도록 강제하는 기능들을 Aspect로 구현하기.(web에서 Repository 호출하면 Eclipse에서 error로 표시하도록, DI사용해서 주입해야 할 것들을 명시적으로 new 하지 못하도록, ...)
마지막으로 다음과 같은 '사고의 흐름'을 권장해줬습니다.

• 도메인 엔티티와 도메인 로직부터 시작하기
– Basic domain-driven and object-oriented principle
• 시작할 때 기본적으로 service 계층은 없다고 생각하기
– See how far you can get
– Add service level as required
• 구현과 관련된 규칙들을 강제하기
• DDD로 리팩터링하기.
top

  1. Favicon of http://truthiness.pe.kr BlogIcon ongs 2007.12.06 12:09 PERM. MOD/DEL REPLY

    '사고의 흐름' ..변화가 필요할것 같네요.TSE는 어떻게 볼 수 있죠?

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2007.12.06 13:29 PERM MOD/DEL

    TSE는 선택된 자만 볼 수 있습니다.ㅋㅋㅋ

  2. Favicon of http://truthiness.pe.kr BlogIcon ongs 2007.12.06 13:33 PERM. MOD/DEL REPLY

    히히^^

  3. Favicon of http://toby.epril.com BlogIcon 토비 2007.12.07 00:34 PERM. MOD/DEL REPLY

    기선이도 내년에는 TSE꼭 가야겠다

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2007.12.07 08:08 PERM MOD/DEL

    네. 꼭 갈꺼에요.

    그때 여행가이드좀 해주세요.
    첫 번째 해외여행이 될텐데..ㅋㅋ

Write a comment.


DDD: putting the model to work

JEDI/DDD : 2007.11.20 14:59


59분이라는 비교적 짧은 시간 동안 에릭 에반스가 발표한 자료가 올라왔었네요. Spring 2.5 관련 아티클 보러갔다가 DDD 발표 동영상 발견하고 이거 구경하고 있습니다.

발표자를 중심으로 찍은 화면이 재생되고, PPT는 플래시로 특정 시간마다 한 장씩 자동으로 보여줍니다. 오~ 발표자료 보여주는 데에도 상당히 신경을 쓴 InfoQ 멋집니다.

보러가기

이런.. 마지막에 조금 쉬었다가 2부에서 이어진다고 하는데, 아직 안 올라왔네요.

도메인, 모델, 유비쿼터스 언어, 모델 이름 선택에서 중요한 것, Context Map을 예제를 가지고 설명해줬습니다. 매우 차분하게 말씀하시네요. 목소리 톤이 약간 졸리기도 합니다.

'JEDI > DDD' 카테고리의 다른 글

[DDD] DDD 입문에 좋은 글  (4) 2009.06.11
파트 3: Refactoring Toward Deeper Insight  (0) 2008.10.24
Factories  (0) 2007.12.25
Aggregates  (0) 2007.12.18
Modules  (2) 2007.12.14
Services  (2) 2007.12.13
DAO vs Repository  (4) 2007.12.04
DTO(Data Transfer Object)  (2) 2007.11.21
DDD: putting the model to work  (4) 2007.11.20
Building Domain Knowledge  (0) 2007.01.03
What Is Domain-Driven Design  (2) 2007.01.02
top

TAG DDD
  1. Favicon of http://yunsunghan.tistory.com BlogIcon Max 2007.11.20 21:19 PERM. MOD/DEL REPLY

    좋은정보 찾아 주셔서 감사 합니다. ^^*

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2007.11.20 21:57 PERM MOD/DEL

    헤헷. 에릭에반스는 천천히 이야기하는 편이라 듣기도 좋았어요. 물론 그래도 대강만 알아들었지만요.ㅋㅋ

  2. Favicon of http://chanwook.tistory.com BlogIcon 찬욱 2007.11.20 22:18 PERM. MOD/DEL REPLY

    재밌죠~

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2007.11.20 23:49 PERM MOD/DEL

    ㅇㅇ귿!

Write a comment.


Building Domain Knowledge

JEDI/DDD : 2007.01.03 18:39


비행기 모니터링 시스템을 구축하려고 한다.
특정 지역에 떠있는 모든 비행기들의 루트를 파악하여 충돌할 가능성이 있는지 나타내는 모니터링 시스템을 구축하는 것이 프로젝트의 목표다.

앞에서 얘기 했듯이 도메인을 이해하는 것부터 시작해야 한다

이 분야 도메인 전문가는 비행기 통제사다. 통제사와 대화를 하는 도중 비행기 이륙과 착륙에 대한 이야기를 많이 듣게 되었다. 그리고 실제 충돌이 이착륙 대기 중일 때 발생할 위험이 있다고 한다.

통제사와 당신은 모든 비행기가 목적지와 출발지가 있다는데에 동의했다. 그래서 다음과 같이 그렸다.

사용자 삽입 이미지

실제 비행기가 공중에 있을 때는 어떤 일이 벌어질지 물어본다. 통제사는 각각의 비행기에는 정해진 비행로가 있다고 한다. 대화를 좀더 듣다보니 경로(Route)라는 흥미로운 단어를 들었다. 이 것이 실제 비행중에 가장 중요하다고 생각했고 비행기가 목적지와 출발지와 직접적으로 연관관계를 갖는 것이 아니라 경로(Route)와 연관을 맺고 이 경로가 목적지와 출발지와 연관을 맺도록 하는 좀 더 명확한 표현 같다.
사용자 삽입 이미지

좀 더 이야기를 해보니 이 경로는 여러 세부 경로로 나뉘어져 있다는 것을 듣게 된다. 즉 경로가 고정된 포인트로 이루어 진 것으로 파악이 되며 목적지와 출발지는 그 고정된 포인트 중 두 개로 파악할 수 있다.
사용자 삽입 이미지
고정된 위치는 3차원으로 표기 할 수 있다.(경도, 위도, 고도?) 하지만 통제사는 비행기를 지구 표면의 평면으로 투사한 곳에 점으로 인식하고 있다는 것을 알게 됐다. 따라서 2차원 점(경도 , 위도만?)으로 표현되도록 수정하였다.
사용자 삽입 이미지


여기까지 진행 한 것을 살펴보면 굉장히 많은 시간을 소비하는 것처럼 보이고 실제로도 그렇치만 당연히 이렇게 해야만 한다. 소프트웨어의 최종 목적은 현실의 도메인과 관련된 비즈니스 문제를 해결하는 것이기 때문에 도메인에 익숙해 져야한다.

'JEDI > DDD' 카테고리의 다른 글

[DDD] DDD 입문에 좋은 글  (4) 2009.06.11
파트 3: Refactoring Toward Deeper Insight  (0) 2008.10.24
Factories  (0) 2007.12.25
Aggregates  (0) 2007.12.18
Modules  (2) 2007.12.14
Services  (2) 2007.12.13
DAO vs Repository  (4) 2007.12.04
DTO(Data Transfer Object)  (2) 2007.11.21
DDD: putting the model to work  (4) 2007.11.20
Building Domain Knowledge  (0) 2007.01.03
What Is Domain-Driven Design  (2) 2007.01.02
top

TAG DDD

Write a comment.


What Is Domain-Driven Design

JEDI/DDD : 2007.01.02 15:35


소프트웨어 개발은 진짜 세상에 존재하는 프로세스를 자동화 시킨 것 또는 현실의 비즈니스 문제에 대한 솔루션을 제공한다.

좋은 소프트웨어를 개발하기 위해서는 그 소프트웨어가 무엇을 하는지 완벽히 알아야 한다.

소프트웨어 프로젝트를 시작할 때 도메인에 집중해야 한다. 도메인에 깊게 뿌리를 두지 않은 소프트웨어는 시간이 갈 수록 변화에 잘 적응할 수 없다.

추상화란? 도메인에 대한 모델이다. Eric Evans는 도메인 모델은 특정 다이어그램이 아니라고 한다. 영어 문장이나 잘 작성된 코드 처럼 도메인을 표현할 수 있고 의사소통이 가능한 다이어그램이다.

모델에 무엇을 표현하고 무엇을 표현하지 말지 정해야 한다.
다른 사람과 의사소통 할 수 있도록 표현이 가능해야 한다. 그래픽을 사용하는 방법과 글로 표현하는 방법이 있다.
=> We need to communicate the model

모델을 만든 뒤에는 코드 설계(code design)를 시작할 수 있다. 소프트웨어 설계는 큰 그림 부터 그리고 코드 설계는 세밀한 부분부터 그린다.
=> 좋은 코드 설계 없이 만들어낸 최종 산출물은 좋을 수 없다.

Waterfall 과 Agile 방법론의 단점들
Waterfall : feedback이 없다.
Agile : analysis paralysis(아무도 설계에 대한 결정을 하려 들지 않는다.), 초기에 전체 윤곽을 파악하기 힘들다.
=> DDD는 적용이 되면 어떤 개발 공정의 능력도 향상 시킬 수 있다.

DDD conbines design and development practice, and shows how design and development can work together to create a better solution.

'JEDI > DDD' 카테고리의 다른 글

[DDD] DDD 입문에 좋은 글  (4) 2009.06.11
파트 3: Refactoring Toward Deeper Insight  (0) 2008.10.24
Factories  (0) 2007.12.25
Aggregates  (0) 2007.12.18
Modules  (2) 2007.12.14
Services  (2) 2007.12.13
DAO vs Repository  (4) 2007.12.04
DTO(Data Transfer Object)  (2) 2007.11.21
DDD: putting the model to work  (4) 2007.11.20
Building Domain Knowledge  (0) 2007.01.03
What Is Domain-Driven Design  (2) 2007.01.02
top

TAG DDD
  1. Favicon of http://px.tistory.com BlogIcon 민재 2007.01.02 17:43 PERM. MOD/DEL REPLY

    음.. 굿잡..
    내가 조만간 첨언을 좀 하마.. 스터디 블로그에..

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2007.01.02 17:57 신고 PERM MOD/DEL

    네. 감사합니다. 그쪽으로 트랙백을 날리겠습니다.

    아니면 이번주 안에 테터 설치를 해야하는 임무를 완수하고 만들어지는 DDD jedi 블로그에서 정리를 해도 될 것 같습니다.

Write a comment.