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.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

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


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


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