'DBC'에 해당되는 글 2건
- 2008/02/12 AOP와 직교성, 그들의 도구로 RAII와 Proxy의 활용
- 2008/01/04 Eiffel 과 DBC.(2)
AOP와 직교성, 그들의 도구로 RAII와 Proxy의 활용
작성자: yagur Rev : 2
AOP의 소개
프로그래밍 패러다임중 최근 성공적으로 보편화 된것은 객체지향프로그래밍이다. AOP(Aspect Oriented Programming)은 OOP를 대체할 패러다임이 아니라 OOP를 보완해줄수 있는 패러다임이다. 번역하자면 관점지향프로그래밍. 이를 비교적 간결한 문법으로 제공하는 편리한 비합성 프록시(non-composited proxy)라고 생각한다. 이것에 관한 생각은 이 글의 후반부에 위치한다.
아직 C++은 지원되지 않고 Java와 C#이 이를 지원하고 있다. 하지만 패러다임 자체는 C++ 구현에서도 어느정도 가능하다(문법적으로 이를 지원하는 컴파일러도 있다고 한다.)
AOP의 특징
AOP의 가장큰 장점중 하나는 재사용성의 증대와 관심사의 분리(Speration of Concerns)이다. 컴포넌트의 디자인 변경과 리팩토링은 수정이 가해진 객체들의 재 합성을 불가피하게 한다. 그렇다면 객체나 컴포넌트들간의 의존성, 연관성이 복잡한 상태에서 특정 모듈의 디자인이나 클래스의 프로시저를 재가공하는일은 과연 재사용성을 증대시키는 일인지 생각해볼필요가 있다.
횡단 관심사(Crosscut concern)
위의 특징에서 언급된 재가공은 알고리즘이나 구조변경이 아닌 여러 관점에서의 관심사의 추가 삭제를 말하고 있다. 이를 테면 트랜잭션, 로그, 프로파일러, 인증, 검증등이 있다. 이 관심사들은 주로 객체의 프로시저안에 들어 가있으며 횡단 관심사(crosscut concern)라 한다. 하지만 그 객체의 내용에 정말 들어가야 하는 코드들인지 생각해보면 해당 객체의 본질과 달리 부가적인 관심사라는 것을 알수있다. 또 이 관심사들의 종류와 갯수는 로직의 변경에 따라 바뀐다. 아래의 코드와 그림이 어느정도 이해에 도움이 될것이다.
bool PlayerAccount::InsertCash(...)
{
bool bResult;
Lock(); // 트랜잭션 시작
StartProfiling(); // 프로파일링 시작
ValidateAccount(); // 계좌 인증
WriteLog();
[DoSomeInsertion........................................]
VerifyAccount(); // 계좌 검증
EndProfiling(); // 프로파일링 종료
UnLock(); // 트랜잭션 종료
return bResult;
}
{
bool bResult;
Lock(); // 트랜잭션 시작
StartProfiling(); // 프로파일링 시작
ValidateAccount(); // 계좌 인증
WriteLog();
[DoSomeInsertion........................................]
VerifyAccount(); // 계좌 검증
EndProfiling(); // 프로파일링 종료
UnLock(); // 트랜잭션 종료
return bResult;
}
사실 InsertCash는 DoSomeInsertion.. 이 주 관심사이고 나머지 트랜잭션, 프로파일링, 검증, 인증 사항은 로직이나 상태, 전략에 의해 언제든지 추가 삭제, 이동, 시점변경이 가능한 부분이다. 이들은 좌측 그림과 같은 관심사 방향으로 끼어들어있다. 그리하여 이들을 횡단 관심사(crosscut concern)라 부르는것 같다.
재사용성 측면에서 보자면 횡단 관심사는 따로 분리되어 있어야 높게 평가될수 있다. 횡단 관심사를 포함하는 객체는 관심사의 변경이 있을때 마다 연관 혹은 합성이나 변경을 거쳐야 하기 때문이다.
객체의 직교성
느슨한 결합을 위해 의존성과 합성을 줄여 직교성을 살리는 것은 관심사의 분리(SoC)에서 시작될수 있다. 이것은 곧 객체지향으로 이어진다. 그것을 도와주는것이 AOP의 도입이다. 단 추상화 된 관심사들을 어떤것과 연관지을지 그 대상을 달리할수도 있다.("프록시의 활용"으로 넘어가 좀더 이야기하겠다.)
템플릿 메소드(GoF)를 활용할때 프로시져들의 트랜잭션이 개별이 아니라 템플릿 메소드의 시작과 끝에 들어가길 원할수도 있다. 인증 또한 유저가 로그인할때 한번만 하도록 방침을 세울 수도 있고, 유저의 잦은 로그인 아웃이 가능한 시스템에서 보안이 요구되는 경우 보안에 관심있는 개별 퍼블릭 메소드마다 사용자 인증을 하는 방침을 세울 수도 있다. 이때 인증은 공인인증서나 핸드폰 인증을 요구할수도 있는데, 인증 자체를 추상화 하여 느슨한 결합을 한다 해도 추상화된것에 의존성을 갖기 마련이다(나쁜 것은 아니다). 클래스의 기본 관심사는 직교성(orthogonality)을 띄고 다른 횡단 관심사에 영향을 받지 않으면서 재사용성을 높히는 방법에 대해 생각해볼수 있다.
C#과 Java의 AOP
자바에선 extension이나 프레임워크로 AspectJ나 SpringAOP같은것을 통하여 지원하며, C#에서는 문법적으로 AOP를 지원하고있다. 정해진 문법으로 관심사의 편리한 분리를 이루어내는 이것들의 예를 본다면 AOP가 OOP가 말하는 재사용성을 도와준다는것을 알수 있다. 아래의 것이 가능하다면 어떨까?
class SomeClass
{
[Log][Transaction]
bool DoSomething();
[Profile]
bool SomethingComplex();
}
C#이나 Java에서는 가능하다. 하지만 C++도 불가능한것은 아니다.{
[Log][Transaction]
bool DoSomething();
[Profile]
bool SomethingComplex();
}
프록시(Proxy)의 활용 그리고 RAII
다른 언어를 사용해보진 않았지만 AOP에 관련된 글들을 읽어 보면 일종으 프록시라고 이해된다. 프록시를 문법적으로 확장하는 조금 새로운 방법 정도로 볼수있다.
프록시는 GoF에 의해 우리에게 친숙한 패턴이다. 이쯤이면 이미 AOP의 활용방안중 하나가 Proxy Pattern이 될수 있다는것을 눈치신 분도 있을것이다. 프록시(proxy)와 다형성(polymorphism)은 c++에게 AOP의 일부를이미 지원하고 있었다.
단 여기서 사용할 프록시는 비합성 프록시(non-composited proxy)인데 GoF의 것과 아주 약간 다르나, 같은 인터페이스를 통해 실체를 접근한다는 근본은 같다. 그리고 이둘은 결합도의 차이로 나타난다. 합성은 상속보다 느슨한 결합이고 상속은 아주 단단한 결합인 셈이다. 그리고 좀더 접근가능한 멤버가 많아진다. 또 public 상속(is-a)보단 private 상속(is-implemented-in-terms-of)을 활용할수 있다. 이는 RealSubject의 횡단관심사를 확장이 아닌 정책으로 결합시키기 위함이다.
Non-Composited Proxy GoF's Proxy(Composited Proxy)
Non-Composited Proxy의 AOP
비합성 프록시는 이글에서 proxy를 AOP에 맞게 사용하기 위해 일부 변경한것을 지칭하기 위해 사용됬으므로 양해 부탁드립니다.
흥미로운 점은 프록시의 함수가 위빙(weaving)할때 조인 포인트(join-point)의 위치는 real subject의 함수의 전 후에 놓이며 같은 스코프(scope)에서 일어나는 것을 알수 있다. 이 경우엔 C++의 관용구인 RAII를 사용해 준다면 그 의미가 더 명확하고 안전해질수 있다.(RAII, ScopeGuard, ScopeLock)
이런 프록시를 두게 된다면 RealSubject는 횡단관심사로부터 직교성을 띌수 있으므로 OOP 완성도를 높힐수 있을것이다. AOP를 로우레벨에서 지원해야 하는 불편함은 단점이지만 확장이나 프레임워크에 얽메이지 않고 좀더 자유롭다는 장점이 있다.
DBC ASPECT
DBC(Design by Contract) 역시 하나의 횡단 관심사로 일반화 시켜볼수 있다. proxy의 real subject의 멤버 함수 방어적 프로그래밍을 하기위해 전후에 배치한 조건들을 횡단 관심사로 바꾸면 된다. 그렇다면 real subject는 좀더 직교적일수도 있다. 실제 사용자(개발자)가 Proxy에 의존 한다면 DBC를 횡단 관심사로 분리하고 Proxy 클래스 구현 속에 포함하게 된다면 realsubject는 좀더 간결하고 본래 구현 목적에 부합하는 것들로 구성될수 있다.
'개발 > 수필' 카테고리의 다른 글
| 테스트와 장인 - 2 (0) | 2008/02/15 |
|---|---|
| 테스트와 장인 - 1 (2) | 2008/02/14 |
| AOP와 직교성, 그들의 도구로 RAII와 Proxy의 활용 (0) | 2008/02/12 |
| 빌드 자동화와 배치 빌드 (0) | 2007/11/30 |
| 주석의 쓰임세 그리고 "중복의 해악" (0) | 2007/11/19 |
| " 품질을 요구사항으로 만들어라 "과 게임의 피드백 시스템 (0) | 2007/11/14 |
Eiffel 과 DBC.
작성자: yagur Rev : 1
Eiffel.
Eiffel은 Bertrand Meyer의 DBC(Design by Contract)를 구현하고 있는 객체 지향 언어입니다. 아래의 그림 같이 인텔리센스를 지닌 IDE도 제공하고 있습니다.(듀얼 라이센스를 지니고 있습니다. 상용은 유료입니다)
Contract(계약)
여기서 Contract(계약)란 사용자와 제공자사이의 합의점을 말합니다.
특징
Eiffel의 가장 큰 특징이라 한다면 단위 실행 혹은 프로시져의 책임을 문법적으로 지원한다는것에 있습니다.
Design by Contract
Precondition 과 Postcondition
Eiffel에서 require과 ensure를 통한 선,후행조건은 실행중 동적으로 확인될수 있습니다. 아래의 구조를 지니고 있습니다.
이 DBC의 선후행 조건은 그 책임을 아래와 같이 설명하고 있습니다.
방어적 프로그래밍과 DBC
방어적 프로그래밍은 모듈이나 함수가 예상하지 못한 상황에 대비하기 위해 확인 조건 코드들을 작성하여 대비합니다. 이것은 과도한 조건 확인을 초래하며, 복잡하고 유지하기 어려운 소프트웨어를 낳을수도 있습니다.
그에 비해 DBC는 책임 부여가 확실하고 그것이 문법적인 인터페이스로 이미 자리잡고 있습니다. Eiffel에선 이렇게 말하고 있지만 Code Complete 2nd의 ch8. 방어적 프로그래밍을 보면 단정문을 이용한 선후행 조건에 관하여 언급하고 있습니다. 방어적인 프로그래밍의 기법중 일부로 DBC를 채택하여 사용할수 있다는 것입니다.
DBC와 방어적 프로그래밍은 서로 다른것 같지만 다르지 않으며 방어적 프로그래밍의 한 방법으로 DBC를 활용할수 있습니다. DBC에 관한 더 자세한 내용은 Object-Oriented Software Construction(Meyer 1997)에서 찾아 볼수 있습니다.
Eiffel.
Eiffel은 Bertrand Meyer의 DBC(Design by Contract)를 구현하고 있는 객체 지향 언어입니다. 아래의 그림 같이 인텔리센스를 지닌 IDE도 제공하고 있습니다.(듀얼 라이센스를 지니고 있습니다. 상용은 유료입니다)
Contract(계약)
여기서 Contract(계약)란 사용자와 제공자사이의 합의점을 말합니다.
특징
Eiffel의 가장 큰 특징이라 한다면 단위 실행 혹은 프로시져의 책임을 문법적으로 지원한다는것에 있습니다.
Design by Contract
1. 호출자(Caller)와 제공자(Callee) 사이의 프로시져의 선행조건(Pre-condition)과 후행조건(Post-condition).
2. 사용자와 제공자 사이의 책임에 관한 계약과 그 장점
1번과 2번은 설계에서 당연한 관계를 가지고 있는 것들입니다. Eiffel이 아니라 C/C++만 하더라도, 방어적인 프로그래밍(Deffensive Programming)을 하시는 분들은 인자의 유효성이나 몇몇 선행조건을 대부분 작성하고 있습니다. 하지만 코드에서 이를 단번에 알기란 어렵습니다. 문법적 키워드가 있거나 분리되어 있지 않기때문입니다. Eiffel은 이것을 require과 ensure로 그 계약(조건들의 모음)들을 분리하는것을 문법적으로 지원 하고 있습니다. 이는 코드를 읽는 사람으로 하여금 직관적인 구분을 가능하게 하여 가독성을 높혀주는 효과도 지니고 있습니다.2. 사용자와 제공자 사이의 책임에 관한 계약과 그 장점
Precondition 과 Postcondition
Eiffel에서 require과 ensure를 통한 선,후행조건은 실행중 동적으로 확인될수 있습니다. 아래의 구조를 지니고 있습니다.
procedure_name(argument) -- comments...
require
Precondition
do
Procedure Body
ensure
Postcondition
End
Eiffel에서 두가지 조건(선행,후행)은 assertion(단정문)입니다. 단정문의 기능을 어찌보면 강요하게 됩니다. 특정 작업이 멈추는것이 좋을지 잘못된 상태정보를 리턴하는것이 좋을지에 선택이 가능했다면 어떨지 생각해보는것도 괜찮을것 같습니다.require
Precondition
do
Procedure Body
ensure
Postcondition
End
이 DBC의 선후행 조건은 그 책임을 아래와 같이 설명하고 있습니다.
방어적 프로그래밍과 DBC
방어적 프로그래밍은 모듈이나 함수가 예상하지 못한 상황에 대비하기 위해 확인 조건 코드들을 작성하여 대비합니다. 이것은 과도한 조건 확인을 초래하며, 복잡하고 유지하기 어려운 소프트웨어를 낳을수도 있습니다.
그에 비해 DBC는 책임 부여가 확실하고 그것이 문법적인 인터페이스로 이미 자리잡고 있습니다. Eiffel에선 이렇게 말하고 있지만 Code Complete 2nd의 ch8. 방어적 프로그래밍을 보면 단정문을 이용한 선후행 조건에 관하여 언급하고 있습니다. 방어적인 프로그래밍의 기법중 일부로 DBC를 채택하여 사용할수 있다는 것입니다.
DBC와 방어적 프로그래밍은 서로 다른것 같지만 다르지 않으며 방어적 프로그래밍의 한 방법으로 DBC를 활용할수 있습니다. DBC에 관한 더 자세한 내용은 Object-Oriented Software Construction(Meyer 1997)에서 찾아 볼수 있습니다.
'개발' 카테고리의 다른 글
| Jeff Bay의 객체 건강유지법. (0) | 2008/10/01 |
|---|---|
| 이럴때 테스트 셋을 만든 보람이 있습니다. (0) | 2008/04/12 |
| Eiffel 과 DBC. (2) | 2008/01/04 |
| Overloading과 Overriding [Part 2] (0) | 2007/05/26 |
| Overloading과 Overriding [Part 1] (0) | 2007/05/22 |
| Unicode 2 (1) | 2006/08/11 |










Recent Comment