반응형

VO, DTO, DAO 클래스 설명

[출처] http://choijaehyuk.com/128



VO

개념

Value Object DTO와 동일한 개념이나 차이 점은 read only 속성을 갖습니다.

Value Object는 관계데이터베이스의 레코드에 대응되는 자바클래스입니다형태는 db레코드를 구성하는 필드들을 Value Object Attribute로 하고 해당 변수에 접근 할 수 있는 Getter Setter 메소드의 조합으로 클래스를 형성되어진 클래스입니다특성은 대체로 불변성이고equals()로 비교할 때 객체의 모든 값을 비교해야 합니다.

필요성

Network traffic을 줄임으로 인해서 효과적입니다.

기대효과

Network traffic이 줄어듭니다.

 

장 단점

장점으로는 비 서버 측 클라이언트도 네트워크 오버헤드 없이 영속성 데이터에 액세스 할 수 있다는 점입니다데이터 전달을 위해 가장 효율적인 방법이지만클래스의 선언을 위해 많은 코드가 필요합니다즉 파일수가 많아지게 되고 관리도 힘들어지게 됩니다.

예제 소스코드

DTO

개념

데이터가 포함된 객체를 한 시스템에서 다른 시스템으로 전달하는 작업을 처리하는 객체입니다. Vo dto의 차이점은 vo는 특정한 비즈니스 값을 담는 객체를 vo라 하고 dto는 레이어간의 통신용도로 오가는 객체를 dto라고 합니다.

Vo DTO의 비교

DTO의 나머지 속성은 vo와 똑같다고 생각하여서 차라리 차이점을 비교하려고 합니다.

Core J2EE Patterns 라는 책에서는... Value Object Transfer Object를 동일한 뜻으로 사용합니다만 반대로 Martin Fowler는 저서 Patterns of Enterprise Application Architecture에서 약간 다른 의미로 이야기 합니다. DTO는 메소드 호출 횟수를 줄이기 위해 데이터를 담고 있는 녀석으로, VO는 값이 같으면 동일 오브젝트라고 볼 수 있는 녀석으로 표현을 하고 있습니다.

 

쉽게

DTO a = new DTO(1);

DTO b = new DTO(1);

이라고 했을 때 a != b 이지만,

 

VO a = VO(1);

VO b = VO(1); 이라고 했을때는 a == b라고 정의하는 형태입니다.

사실 이러한 내용도 헷갈리는 부분이 있는게 대부분의 검색에서 사람들은 vo dto를 같은 개념으로 이야기 하고 있어서 아직도 vo dto가 이런거다라기 보다 거의 똑 같은 개념으로 생각하고 있습니다.

 

DAO

개념

데이터 접근을 목적하는 객체입니다커넥션 같은 것을 하나만 두고 여러 사용자가 DAO의 인터페이스를 사용하여 필요한 자료에 접근 하도록 하는 것이 DAO의 개념입니다.

필요성

모든 데이터베이스에 공통적으로 접속 할 수 있는 ODBC가 나왔지만 완벽하진 못했습니다여전히 로우 레벨의 API를 포함하고 있었기 때문에 개발 장벽이 여전히 높았습니다이런 이유 때문에 개발자들은 정작 데이터베이스에 들어 있는 데이터를 어떻게 이용할지에 초점을 맞추기 보다어떻게 데이터베이스에 접속해서 데이터베이스와 교류하는지에 더 초점을 기울였습니다즉 데이터를 활용하는 논리적 고민보다 기술적 고민에 더 많은 신경을 썻었습니다이런 이유로 DAO란 대안이 나왔습니다.

기대효과

사용자는 자신이 필요한 Interface DAO에게 던지고 DAO는 이 인터페이스를 구현한 객체를 사용자에게 편리하게 사용 할수 있도록 반환해줍니다.

장 단점

DB에 대한 접근을 DAO가 담당하도록 하여 데이터베이스 엑세스를 DAO에서만 하게 되면 다수의 원격호출을 통한 오버헤드를 VO DTO를 통해 줄일수 있고 다수의 DB 호출문제를 해결할 수 있습니다또한 단순히 읽기만 하는 연산이므로 트랜잭션 간의 오버헤드를 감소할 수 있습니다.

 그러나 Persistent Storage를 너무 밀접하게 결합해서 작성을 하게 되면 Persistent Stroage를 다시 작성할 경우가 생기는데 이러한 경우 유지 보수의 문제가 생길수도 있습니다.

반응형

'Spring' 카테고리의 다른 글

Spring Transaction #2  (0) 2014.10.01
Spring Transaction #1  (0) 2014.10.01
domain object에 대한...  (0) 2013.07.08
Spring Java Mail  (0) 2013.07.05
Spring MultipartResolver  (0) 2013.07.02
반응형

먼저 도메인 객체에 대해 잘 모르는 사람들을 위해 이 오브젝트를 조금 자세히 설명할 필요가 있다.과거 자바가 웹의 영역에 드러서기 시작하면서 다른 플랫폼들과 소통하기 위한 장치가 필요했는데 그것이 바로 JSR-000220, 자바빈즈였다. 자바빈은 본래 다양한 목적으로 설계되었으나 지금은 대부분이 외부 리소스를 담는 그릇같은 용도로 사용되고 있으며, 빈 생성자를 가지며 내부에 private로 설정된 프로퍼티에 get…, set…과 같은 명명규칙을 갖고 있는 클래스를 일컫는다.


이렇듯 도메인 오브젝트의 첫 시작이었던 자바빈즈는 클래스 내부에 연산이나 다양한 기능을 넣기엔 기술적 한계가 많았으므로 대부분 해당 데이터를 처리하기 전에 임시로 담아두는 정도로 밖에 사용하지 않았다. 임시적으로 발생하는 데이터를 처리하기 전까지 담아두는 도메인 객체를 일컫어 빈약한 도메인 오브젝트 방식이라도 한다.

빈약한 도메인 오브젝트를 보다 잘 이해할 수 있도록 한가지 예를 들어보자. @Controller에서 파라미터로 넘어온 값을 DB에 넣기 위해 다음과 비슷한 도메인 오브젝트를 만들어 본 기억이 있을 것이다.

public class User {
private String id;
private String password;
private String name;

public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}

…중략…

}

이런 단순한 도메인 오브젝트는 테이블의 컬럼 또는 뷰에서 넘어오는 파라미터를 기본적으로 완벽하게 이해하게끔 설계하고 있으므로 해당 요청을 처리하는 계층에서 로직이 시작되기 전에 미리 User란 그릇에 테이블의 컬럼값과 파라미터 값을 저장시켜놓고 사용할 수 있었다.

근데 이런 도메인 오브젝트를 계속 사용하다보니 조금 헷갈리기 시작한다. 왜냐하면 따지고 보면 도메인 오브젝트가 가장 객체의 본질을 잘 표현해주는 주된 형태인데 이걸 User 오브젝트 자신보다 연관성이 떨어지는 UserService나 UserDao, UserController같은 곳에서 대신 컨트롤 하고 있으니 말이다.

혹시나 이해가 잘 안된 사람을 위해서 좀 더 자세히 설명하고자 한다. 객체지향적인 관점에서 말해보자면 도메인 오브젝트는 객체 자신에 그 무엇보다 가깝다. 현재의 자바기술로 도메인 오브젝트는 바로 객체 자신이라고까지 할 수 있으며 비록 잠시 태어나 소멸할지언정 가장 명확하게 객체 자신을 표현하고 있다는 오브젝트였다는 말이다.

너무 중요한 단락이기에 더욱 쉽게 설명해보겠다. 예를 들어 나는 초밥을 좋아하고 키가 178cm에 단정한 머리 스타일이고 …블라블라… 여하튼 나 자신을 너무 잘 알고 있다. 근데 나를 만든 개발자 때문에 나는 어디든 내 마음대로 움직일 수 없다. 이 개발자는 내가 스스로 못 움직이게끔 바닥에 나를 고정시켜놓고는 대신 나와 비슷한 녀석들을 대량으로 처리하는 이상한 기계에 맡겨 나를 조종하고 있다. 나는 저 기계보다 내 자신이 누군지 잘 이해하고 행동할 자신이 있는데 개발자 때문에 내가 누군지도 잘 모르는 기계가 나를 다스리도록 하고 있는 셈이다.

이제 이해가 조금 됬는지 모르겠다. 우리가 객체지향 프로그래밍이라 부르는 것은 바로 사물을 객체지향적인 관점으로 바라보고 그대로 해석할 수 있는 언어이기 때문에 객체지향적이라고 일컫는 것이다. 근데 빈약한 오브젝트 방식은 이런 객체지향적인 관점을 어느 정도 훼손하고 있다. 물론 보다 능률적인 대량처리를 위해 빈약한 오브젝트 방식이 결코 나쁘다고는 할 수는 없지만 한편으로는 결코 좋은 방식이라고도 할 수 없는 것이다.

그렇다면 이 빈약한 오브젝트를 조금 풍성하게 해보면 어떨까? 다음과 같은 소스처럼 말이다.

public class User {
private String id;
private String password;
private String name;

public int getToken() {
return getId() + getPassword();
}

… 중략…
}

다시 말하지만 도메인 오브젝트는 자신을 가장 잘 이해하고 있으므로 getToken() 메서드를 효율적으로 처리할 수 있는 로직을 가장 직관적으로 구현할 수 있다. 바로 아래와 같이 말이다.

public class User {
private String id;
private String password;
private String name;

private UserDao userDao;

@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public int getToken() {
return getId() + getPassword();
}
public String getId() {
Assert.hasText(id);
return id;
}
public String getPassword() {
if(password==null) return userDao.getPassword(id);
else return password;
}

… 중략 …
}

위의 코드는 여러모로 부족한 점이 많지만 중요한 것은 getToken()의 무결성을 보장해준다는 것이다. 만약 이 로직을 도메인 오브젝트 외의 Service 계층이나 Dao계층에서 처리 해야했다면 굉장히 이해가 불편함과 동시에 무결성을 보장하기가 까다로웠을 것이다. 하지만 우리는 위와 같이 도메인 오브젝트가 자기 자신과 관련한 비지니스 로직은 스스로 처리하게 하고 그 무결성을 스스로 보장하게끔 한 덕분에 매우 직관적이고 깔끔한 코드를 얻을 수 있게 되었다.

결론적으로 DDD는 도메인 자체에 더 많은 권한과 기능을 부여함으로써 도메인이 가질 수 있는 능력을 극대화 시키고 주도해 나가는 개발방식이며 더 나아가 도메인을 하나의 계층으로 인정하고 다른 영역과 분리해내는 4Tier 아키텍쳐인 것이다.

물론 위의 코드는 여러모로 문제점이 많다. 우선 도메인 객체에 적용될 수 없는 @Autowired와 같은 DI기술이 적용됬다는 점이며 지금은 보이지 않지만 해당 도메인이 DAO 계층을 흡수한 만큼 DB에 접근할 수 있게된 권한으로 자칫 엄청난 불상사를 초래할 수 있다는 점이다.

하지만 이런 문제점은 스프링의 @Configurable과 AOP 기술, 그리고 DTO 모델을 도입함으로써 해결할 수 있는 문제점들이기 때문에 DDD 주도의 개발을 막지는 못한다. 되려 DDD는 개발을 보다 쉽고 빠르게 도와주며 코드 자체를 직관적으로 바꿔주어 이용자의 부담과 불필요한 이해를 막아준다.


글을 마치며...

도메인 오브젝트는 이렇듯 단순한 자바빈에서 시작하여 조금씩 기능을 더해오더니 이제 개발의 주도적인 역할까지 수행하는 단계에 이르게 되었다. 이렇듯 도메인 오브젝트를 적극 활용하여 개발을 하게 되면 소스의 테스트가 더욱 쉬워지고 활용도 또한 극대화 된다. 그렇다고 무작정 도메인 오브젝트에 모든 기능을 씌우려고 해서는 절대로 안된다. 왜냐하면 DDD를 적용하는 것은 어디까지나 직관적이고 객체지향적인 설계를 위한 것이지 무분별한 남용을 위한 것은 아니기 때문이다.

만약 도메인 오브젝트에 존재하지 않는 외부값의 첨가가 필요하다면 이런 로직은 필히 해당 도메인의 Service 계층, 또는 Support 계층에서 전담하여 처리하고 도메인 오브젝트는 오로지 본인 내부의 리소스만을 조합하여 처리할 수 있는 로직만을 담당하여야 한다.

이렇게 도메인 오브젝트의 발전사를 마쳤다. 필자는 멋도 모르고 코딩을 해대던 과거 시절, 이미 자바빈 객체를 내멋대로 확장하여 사용한 적이 있었는데 그 당시 MVC를 알게 되고 부터는 자바빈에 기능을 부여하는 것이 잘못된 것으로만 알고 있었다. 헌데 이젠 DDD란 이름으로 예전의 나의 코딩방식이 또다시 새로운 패러다임이라고 조명받고 있으니 조금 우습기도 했다.

사람이란게 말을 함부로 바꿔서는 안되는 모양인가 보다.



반응형

'Spring' 카테고리의 다른 글

Spring Transaction #2  (0) 2014.10.01
Spring Transaction #1  (0) 2014.10.01
VO, DTO, DAO  (0) 2013.07.08
Spring Java Mail  (0) 2013.07.05
Spring MultipartResolver  (0) 2013.07.02
반응형

퍼사드 패턴을 설명하기 앞서 이전의 다른 패턴을 기억해 보자.

    패턴                                                 용도
----------------------------------------------------------------------
데코레이터        한 인터페이스를 다른 인터페이스로 변환

어댑터              인터페스는 바꾸지 않고 책임(기능)만 추가

퍼사드              인터페이스를 간단하게 바꿈

1. 컨텍스트

Facade 패턴은 복잡한 서브 시스템에 통일된 인터페이스를 제공함으로써 복잡한 API를 단순화 시켜준다. 시스템을 서브 시스템 단위로 나누어 구성하는 것은 시스템의 복잡도를 낮춰주지만, 동시에 서브 시스템 사이에서의 통신 부하와 결합도가 증가하게 된다. 이러한 서브 시스템 사이의 의존도를 낮추고, 서브 시스템의 사용자 입장에서 사용하기 편리한 인터페이스를 제공하고자 하는 것이 facade 객체이다.

 

 

 

 

 

 

Facade 객체는 실생활에서의 고객 서비스 센터와 유사하다. 가령, 어떤 상품을 구매하는 과정에서 문제가 생겼다고 가정할 때, 고객이 문제의 성격에 따라 해당 부서에 직접 연락하는 것이 아니라 고객 서비스 센터를 통하는 것은 Facade 패턴에 대한 좋은 유추 사례가 될 수 있다.

2. 적용 영역

■ 복잡한 서브 시스템에 대해 간단한 인터페이스를 제공하기를 원하는 경우
■ 클라이언트와 인터페이스의 구현 클래스 사이에 의존도가 높은 경우
■ 서브 시스템을 레이어(layer)로 구분하고자 하는 경우

3. 구조




 

 

 

 




4. 적용 결과

■ 서브 시스템의 컴포넌트로부터 클라이언트를 격리하여, 클라이언트가 쉽게 서브 시스템을 이용할 수 있다.
■ 서브 시스템과 클라이언트 사이의 의존성을 낮춘다.
■ Facade 패턴을 사용한다고 해도, 필요한 경우 서브 시스템의 클래스에 직접 접근할 수도 있다. 즉, 일반화 정도(generality)와 개발의 편의성 사이에서의 적당한 합의점을 찾아야 한다.

5. 관련 패턴

■ Abstract Factory는 Facade와 함께 사용되어 서브 시스템에 독립적으로 서브 시스템의 객체를 생성하는 인터페이스를 제공한다. 또한, 특정 플랫폼에 국한된 클래스를 숨기기 위해 Facade 대신 사용할 수도 있다.
■ Mediator는 기존의 클래스의 기능을 추상화한다는 의미에서 Facade와 유사하다. 그러나, Mediator의 목적은 서로 직접적인 연관을 갖는 객체(colleague object) 사이에서의 커뮤니케이션을 추상화하는 것인데 반해, Facade는 서브 시스템의 인터페이스를 추상화하는 것이다.
■ 하나의 Facade 객체만이 요구되는 경우에는 Facade 객체가 Singleton 형태를 취하기도 한다.

반응형

'Design Pattern' 카테고리의 다른 글

Strategy Pattern  (0) 2013.08.12
abstract factory pattern  (0) 2013.07.09

+ Recent posts