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

[DDD] Whiteship's DDD 아키텍처 수정

JEDI/DDD : 2009.06.16 18:17



Repository 역할이 DAO로 단순 위임 밖에 없어서, Repository를 없애고 그 자리에 DAO를 뒀습니다. Entity에서 이 객체를 사용하여 필요한 작업들을 할 겁니다. 이전의 Facade 역시 이름을 Service로 바꾸고, Transaction을 책임지게 했습니다. 이 서비스는 별다른 역할 없이 Domain 객체나 Dao로 역할을 위임하는 Thin Service입니다.

구조는 기존의 계층형 구조(Controller -> Service -> Dao)와 거의 비슷해 보이지만, 일단 Entity에서 Dao를 들고 예전에 서비스 계층에서 처리했던 비즈니스 로직을 담당하게 되었다는 것, 그 결과 Service의 일은 도메인 객체로의 단순 위임으로 바뀌었다는 점이 주요 특징으로 볼 수 있겠습니다. 또한, 모든 domain 클래스에 대한 C, S, D를 만들던 것과 달리 Entry Point에 해당하는 Entity에 대해 C, S, D를 제공하는 구조입니다. 즉 그림에서 Address라는 Value 타입과 OrderLine이라는 레퍼런스 타입에 대한 C, S, D는 볼 수 없죠.

'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


[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


[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

파트 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


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

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

Modules

JEDI/DDD : 2007.12.14 23:43


크고 복잡한 애플리케이션에서 모델은 갈수록 커지는 경향이 있다. 그러다가어느 시점에 도달하면 더이상 전체를 파악하기도 힘들고 그들의 관계를 이해할 수도 없을 만큼 복잡해진다.

모듈은 관련된 개념과 작업들을 묶어서 복잡도Complexity를 줄이기 위해 사용한다.

모듈을 사용하는 또 다른 이유는 코드의 품질과 관련이 있다. 높은 응집도Cohesion와 낮은 결합도Coupling을 유지하는 코드가 좋은 코드다.  모듈을 사용하면 응집도를 높이고 결함도를 떨어트린다. 왜냐면 모듈화 함으로써 기능적으로나 논리적으로 관련된 녀석들을 묶어주기 때문에 응집도는 높아지며, 모듈들은 모두 잘 정의된 인터페이스를 가지고 있기 떄문에 결함도를 낮춰준다.

사용자 삽입 이미지

모듈 이름은 유비쿼터스 언어의 일부에서 발췌해야 한다.

모듈을 한 번 만들고 그 역할을 정해두면, 그 내부에 많은 변화가 생기더라도 보통 모듈을 자주 변경하지 않는다. 하지만 프로젝트를 진행하면서 모듈을 얼려두지 말고 진화시키는 것을 권장한다. 모듈을 리팩토링하는 비용이 엄청나다는 것을 알지만 그래도 모듈을 유지하기 위해 돌아가는 방법을 선택하는 것 보다는 모듈을 변경하는게 좋다.

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

[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
Building Domain Knowledge  (0) 2007.01.03
top

TAG Modules

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


DAO vs Repository

JEDI/DDD : 2007.12.04 23:21


http://aeternum.egloos.com/1160846 이 글을 참조하세요. 아래 내용은 권해드리지 않는 내용입니다.

나도 DDD 하고싶어 모델링 적용기
Repository Pattern vs. Transparent Persistence

위 두 개의 글의 공통점은 DAO와 Repository의 차이에 대한 고민입니다. 저도 잘 모릅니다. 저는 사실 찬욱군이 쓴 글에 있는 링크를 따라가보지도 않았으며, 얇은 DDD책(DDD Quickly)도 다 읽지 못 했고, 그나마 읽었던 부분들도 잊혀져가고 있습니다.(다시 읽으려고 마음먹었습니다.)

그래도.. 나름대로 생각해 봤습니다. 어차피 작명의 문제이고 누군가 어떤 의도를 가지고 작명을 했을테니 그 뜻은 분명 단어 속에 숨어있겠죠.

DAO는 Data Access Object의 약자로 데이터(베이스)에 접근하는 객체를 나타냅니다. DB 접근하는 일을 분리해 냈습니다. SRP 객체지향 원칙의 사례로 등장했었던 적이 있었는데 어떤 글인지는 모르겠습니다.

Repository는 저장소입니다. 어떤 객체들을 저장하는 장소를 뜻할 것이며, 아마도 DB 자체를 또는 Table 자체 또는 '영속성이 보장되는 저장소'를 객체화한 표현이 아닐까 생각해봅니다. 이것이 필요한 객체는 바로 도메인 객체겠죠.

이정도 정보를 가지고 이 둘의 차이를 살펴보기엔 정말 막연합니다. 그래서 Finder라는 녀석까지 같이 보겠습니다. Finder는 findByXXX 류의 메소드들을 가진 클레스로 이 녀석 역시 DB나 영속성을 보장하는 어떠한 저장소에 접근을 합니다.

기존의 DAO에는 Finder가 하는 일까지 같이 포함하고 있었습니다. 그리고 DDD를 구현한(건지.. 구현 하도록 돕는 건지.. Anyway) ROO 라는 프레임워크에서는 Repository와 Finder로 분리해 두었습니다. 조금 더 세밀하게 SRP를 적용했다고 볼 수 있습니다.

따라서 저는 이렇게 결론을 냈습니다.

사용자 삽입 이미지

그럼 DAO와 Finder를 동시에 두면 어떻게 되는걸까? 라는 생각을 해볼 수 있는데요. DAO는 위에서도 언급했다시피, 데이터에 접근하는 객체입니다. Finder는 무언가를 찾아주는 녀석이죠. 그럼 무언가를 찾아주는 녀석이 매번 데이터에 접근해서 찾아야 하는데 결국 Finder도 DAO라고 볼 수 있지 않을까요? 그럴 때는 가능하다면, 기존의 DAO 이름을 Repository로 변경하는 것이... 좋을 것 같다는 생각을 해봅니다.

'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


DTO(Data Transfer Object)

JEDI/DDD : 2007.11.21 12:30


참조 :
http://martinfowler.com/eaaCatalog/dataTransferObject.html
http://en.wikipedia.org/wiki/Data_Transfer_Object
http://www.theserverside.com/discussions/thread.tss?thread_id=32389

찬욱군이 요즘 DTO Assembler를 만들고 있는 것 같습니다. 저는 DTO 개념이 없기 때문에, 오히려 더 복잡해 보이는데 왜 저렇게 해야 되는거지 궁금해 했습니다. 대체 DTO가 뭐길래...그래서 찾아봤습니다.

사용자 삽입 이미지
위 그림은 첫 번째 링크 마틴 파울러 eaa 카탈로그에서 가져왔습니다. 원격 호출을 할 때 호출의 수를 줄이려면, 한 번에 여러 객체를 가져와야 하는데, 메소드가 오직 하나의 객체만 반환할 수 있는 자바같은 언어들은 그런 것이 불가능하기 때문에 고안한 것이 DTO 입니다.

즉, 필요한 정보만 모아놓은 객체가 되겠죠. 따라서 서버 측에서는 이런 객체(DTO)를 지원하기 위해 여러 객체의 정보를 가지고 DTO를 만들어주는 Assembler라는 녀석을 제공해야 하고, 지금 찬욱군이 이 녀석을 만들고 있는 것 같습니다.

두 번째 링크인 위키피디아의 정의를 보면, DAO, 비즈니스 도메인 객체(DO), 그리고 DTO의 차이를 매우 간략하게 말해주고 있습니다.

The difference between Data Transfer Objects and Business Objects or Data Access Objects is that DTOs do not have any behaviour except for storage and retrieval of its own data (accessors and mutators).

무언가 혼란스러움이 생기기 시작합니다. 이제까지 도메인 객체(DO)라고 구현했던 녀석들과 DTO와의 차이가 없습니다. 그 녀석들(DO)도 단순하게 프로퍼티와 세터 게터만 가지고 있었으니까요. 그럼 DTO와 별단 차이가 없기 때문이죠. 이것참... 어쩐지 도메인 객체가 너무 횡하다 했습니다.

MemberDao.save(Member) 같은 메소드는 뭔가 어색하고 Member.join() 하면 그냥 DB 저장이 되야 어색하지 않은데 말이죠. MemberService.getMember(id)를 호출하면, Member 도메인 객체가 아니라, 사용자가 보기 원하는 정보만을 담은 Member DTO를 넘겨주는 것이였군요. 이런식으로 하면 도메인 객체 계층을 눞힐 수 있겠군요.(세워두는 것이 아니라..) 찬욱군이 그린 ROO 아키텍처가 이해가 가기 시작합니다.

저는 저 위의 그림의 Assembler보다 Facade가 더 궁금하네요. 역시 그림도 좋은데 코드가 있어야... 좀 더 명확할텐데 말이죠. DTO와 Assembler 그리고 Facade를 잘 활용한 애플리케이션 코드를 보고 싶네요.

'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 DTO

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

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

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