Whiteship's Note


[OOAD] 객체지향 원칙 1. SRP

Design Pattern : 2010.05.07 00:35


참조: 
http://www.objectmentor.com/resources/articles/srp.pdf
헤드 퍼스트 OOAD (영문판) 390p
http://www.zdnet.co.kr/ArticleView.asp?artice_id=00000039135552
실용주의 디자인 패턴 (Holub on Patterns) 6p

Single Responsibility Principal, 보통 단일 책임 원칙이라고 하는데 여기서 "책임"이란 "변경 이유"에 해당한다. 따라서 이 원칙은 다음과 같이 재해석 할 수도 있다. 

어떤 클래스는 한 가지 이유로만 변경되어야 한다.

즉, 여러가지 이유로 해당 클래스가 변경된다면 그 클래스에 여러가지 책임 있다는 말이다. 또는 반대로 책임이 여러 크래스로 분산되어 있어도 문제다. 어떤 기능을 하나 손 보려면 여러 클래스를 두루 두루 손봐야 할지도 모르기 때문이다.

"한 가지 일"이라는게 클래스에게 지나친 제약이지는 않을까? 그렇치 않다. 스윙의 JTable은 백여개의 메서드를 가지고 있다. 하지만 그 모든게 테이블과 관련된 작업들이고 여러 리스너 인터페이스들을 구현하였기에 SRP를 잘 지키고 있는 예제로 볼 수 있다. 즉 지나치게 클래스를 제약하지 않는다.

응집도(cohesion)는 SRP의 또다른 이름이기도 하다. 높은 응집도를 가진 소프트웨어를 작성할수록 SRP를 잘 적용하고 있는 것이다.  
http://code.springsprout.org/browse/SpringSprout/src/springsprout/modules/member/MemberServiceImpl.java?r=HEAD

자 위에 있는 봄싹 코드에서 SRP를 위반한 코드를 찾아서 해당 코드를 작성한 사람에게 따지도록 하자. 

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

[OOAD] 객체지향 원칙 1. SRP  (2) 2010.05.07
[Tell, Don't Ask] 물어보지 말고 시켜라  (8) 2010.04.07
Visitor 패턴  (2) 2010.03.12
Holub on Pattern 좋은데요~  (4) 2008.12.07
프로토타입 패턴(Prototype Pattern)  (2) 2008.10.31
데코레이터(Decorator) 패턴  (0) 2008.10.01
프록시(Proxy) 패턴  (0) 2008.09.26
JUnit 공부하자.  (0) 2008.09.01
H.F.OOAD 5장 문제  (0) 2007.11.20
상위 클래스 보다는 인터페이스를...  (4) 2007.08.31
Singletons and lazy loading  (2) 2007.01.27
top

TAG OOAD, SRP

[Tell, Don't Ask] 물어보지 말고 시켜라

Design Pattern : 2010.04.07 15:51


http://c2.com/cgi/wiki?TellDontAsk
http://www.pragprog.com/articles/tell-dont-ask
http://www.ccs.neu.edu/research/demeter/related-work/pragmatic-programmer/jan_03_enbug.pdf

주요 내용
- Shy Code를 작성하라.
- 어떤 객체로부터 정보를 가져와서 판단하지 말고 그 객체가 판단하도록 시키자.
- Command와 Query를 구분하자.
- Law of Demeter를 지키자.

메서드가 어디에 어느 클래스에 위치 해야 하는지에 대한 이야기인데, 가끔 코딩하다보면 이 코드가 여기 있어야 되는건지..저기로 가야하는건지 판단의 기준이 잘 서지 않을 때가 있는데 그럴 때 이 말을 떠올리면 도움이 될 것 같습니다.

 public boolean confimMember(String email, String authCode) { Member storedMember = repository.findByEmail(email); if (storedMember == null) { throw new UsernameNotFoundException(email + " 에 해당하는 사용자가 없습니다."); } boolean result = storedMember.getAuthCode().equals(authCode); if (!result) { throw new InsufficientAuthenticationException(authCode + " 인증 코드가 올바르지 않습니다."); } else { storedMember.join(); storedMember.makeAvatar(); addMemberRole(storedMember); update(storedMember); } return result; }
이 코드는 봄싹의 MemberServiceImpl 코드중 일부입니다. 즉 위와 같은 코드는 저 원칙에 위배되는 코드로 객체 지향적이지 못한 코드입니다. 객체 지향적인 코드라면 함수 호출이 아니라 어떤 작업을(method) 지시해야 합니다. 그런데 지금은 authCode를 가져와서 매개변수의 authCode와 같은지 판다하고 있지요. 바로 이 예제가 Tell, Don't Ask에서 지적하고 있는 대표적인 사례입니다.

boolean result = storedMember.isConfirmed(authCode);

이렇게 매개변수로 필요한 정보를 전달하고 결과를 돌려받으면 됩니다. 즉 isConfirmed()라는 Query 메서드를 사용해서 정보를 조회하면 됩니다. Command 메서드가 아니라 Query 메서드기 때문에 당연히 객체 내부 정보를 변경하지 않도록 주의해야 합니다. Command 메서드와 Query 메서드를 잘 구분하는 것이 저 원칙을 지키는 지름길입니다. 또한, 이렇게 하는 것이 '데메테르 법칙'을 지키는 일이기도 합니다. 최측근에게만 일을 시키게 되니까 말이죠.

단, 단점이 있는데 그건 바로. 저 상태로 끝나면 모를까. 그게 아니라 Member 클래스에 isConfirm() 메서드를 만들어 줘야 한다는 거죠. 만약 3중, 4중으로 건너 건너 요청하던 코드를 저 원칙에 따라 고친다면 그만큼 자잘한 코드들이 생길 겁니다. 

그런 단점들 대신에 얻을 수 있는 장점으로 시스템 내부의 클래스간 의존도를 낮출 수 있다는 것입니다. 따라서 그 둘간의 저울질을 잘 하고 선택하시기를...

봄싹 코드는 이제 저 기준에 따라 모든 클래스의 코드를 리뷰하고 코드 뜯어고치기 작업을 진행합니다. 그게 끝나면 패키지 간의 의존성을 점검해봐야겠습니다.

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

[OOAD] 객체지향 원칙 1. SRP  (2) 2010.05.07
[Tell, Don't Ask] 물어보지 말고 시켜라  (8) 2010.04.07
Visitor 패턴  (2) 2010.03.12
Holub on Pattern 좋은데요~  (4) 2008.12.07
프로토타입 패턴(Prototype Pattern)  (2) 2008.10.31
데코레이터(Decorator) 패턴  (0) 2008.10.01
프록시(Proxy) 패턴  (0) 2008.09.26
JUnit 공부하자.  (0) 2008.09.01
H.F.OOAD 5장 문제  (0) 2007.11.20
상위 클래스 보다는 인터페이스를...  (4) 2007.08.31
Singletons and lazy loading  (2) 2007.01.27
top


Visitor 패턴

Design Pattern : 2010.03.12 21:26


http://c2.com/cgi/wiki?VisitorPattern
http://en.wikipedia.org/wiki/Visitor_pattern

Composition 패턴을 구현한 구조물에 어떤 기능을 수행하고 싶을 때 해당 기능을 별도의 인터페이스로 분리해낸것이 Visitor 패턴. 이렇게 하여 기존의 구조물에 해당하는 코드는 변경하지 않고 그것들을 사용하는 새로운 기능을 새로 추가할 수 있으니 Open-Closed 원칙을 달성했다고 볼 수 있다.


생각해보니 이런 패턴이 적용된 것들이 꽤 많으며, 적용할 수 있는 곳도 많은 것 같다. 윈도우에서 폴더나 파일을 우클릭한 다음에 저장, 복사, 이동 등을 하는 것들이 모두 이 패턴을 이용해서 구현하지 않았을까..

게다가 ASM은 이 패턴을 사용하여 BCEL이나 SERP 같은 코드 조작 툴보다 훨씬 뛰어난 성능의 라이브러리를 제공하고 있다.

그렇다 사실은 ASM 공부하다가 맨 첨에 등장하는게 이 패턴이라 잠깐 보고 넘어가기로 한 것이다. ㅋㅋ

흠... 하지만 ASM이 조작하는 클래스 처럼 클래스 아래 변수 쫙! 메서드 쫙! 변수와 메서드에는 어트리뷰터가 쫙! 있는 단순구조가 아니라, 파일이나 폴더 처럼 파일 안에 파일 쫙! 그 안에 또 파일 쫙! 이런 트리구조라면 Visitor 패턴을 개조한 Hierarchical Visitor 패턴이 더 효율적이고 유용하겠다.

http://c2.com/cgi/wiki?HierarchicalVisitorPattern

자 어서 ASM도 보도록 하자. ㄱㄱㄱㄱ

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

[OOAD] 객체지향 원칙 1. SRP  (2) 2010.05.07
[Tell, Don't Ask] 물어보지 말고 시켜라  (8) 2010.04.07
Visitor 패턴  (2) 2010.03.12
Holub on Pattern 좋은데요~  (4) 2008.12.07
프로토타입 패턴(Prototype Pattern)  (2) 2008.10.31
데코레이터(Decorator) 패턴  (0) 2008.10.01
프록시(Proxy) 패턴  (0) 2008.09.26
JUnit 공부하자.  (0) 2008.09.01
H.F.OOAD 5장 문제  (0) 2007.11.20
상위 클래스 보다는 인터페이스를...  (4) 2007.08.31
Singletons and lazy loading  (2) 2007.01.27
top


Holub on Pattern 좋은데요~

Design Pattern : 2008.12.07 03:27


사용자 삽입 이미지

수영장에서 놀다가 5대 원칙 부분만 읽어봤는데 아주 맘에 듭니다.

SRP: 단일 책임 원칙. 클래스 하나는 한 가지 책임만 지녀야 한다.

DIP: 의존성 관계 역전 원칙. 구체 클래스가 아닌 추상 클래스 또는 인터페이스에 의존할 것.

ISP: 인터페이스 분리 원칙. 세세한 인터페이스가 큰 한 덩어리 인터페이스보다 좋다.

LSP: 리스코프 대체 원칙. 상속 제대로 할 것.

OCP: Open-Closed 원칙.

무엇보다 번역이 정말 세심하게 되어 있는 것 같습니다. 간혹 독자가 긴 단락을 이해하지 못할까봐 역자 분의 요약도 볼 수 있는데 이 부분이 저한텐 많이 도움이 됩니다. 책 내용에 집중해서 좀 더 빠르게 읽게 도와준달까요.

책이 절판되서 없어지기 전에 장만 해 두시는 건 어떨까 싶습니다. :)

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

[OOAD] 객체지향 원칙 1. SRP  (2) 2010.05.07
[Tell, Don't Ask] 물어보지 말고 시켜라  (8) 2010.04.07
Visitor 패턴  (2) 2010.03.12
Holub on Pattern 좋은데요~  (4) 2008.12.07
프로토타입 패턴(Prototype Pattern)  (2) 2008.10.31
데코레이터(Decorator) 패턴  (0) 2008.10.01
프록시(Proxy) 패턴  (0) 2008.09.26
JUnit 공부하자.  (0) 2008.09.01
H.F.OOAD 5장 문제  (0) 2007.11.20
상위 클래스 보다는 인터페이스를...  (4) 2007.08.31
Singletons and lazy loading  (2) 2007.01.27
top


프로토타입 패턴(Prototype Pattern)

Design Pattern : 2008.10.31 16:57


참조: Java 언어로 배우는 디자인 패턴 입문

"복사해서 인스턴스 만들기"
"클래스에서 인스턴스를 만들지 않고 인스턴스에서 인스턴스 만들기"

객체를 클래스를 사용하여 new로 생성하지 않고 복사해서 만들고 싶은 경우
- 취급하는 객체가 다양해서 각각을 별도의 클래스로 두기엔 무리가 있을 때..
- 클래스에서 객체 생성이 어려운 경우(ex. 런타임에 마우스 조작으로 만들어 내는 객체)
- 프레임워크와 생성할 인스턴스를 분리하고 싶을 때. 모형이 되는 객체를 등록해 놓고 그 객체를 복사해서 인스턴스 생성.

예제 코드 from Wikipedia
/** Prototype Class **/
public class Cookie implements Cloneable {

public Object clone() {
try {
Cookie copy = (Cookie)super.clone();

//In an actual implementation of this pattern you might now change references to
//the expensive to produce parts from the copies that are held inside the prototype.

return copy;

}
catch(CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}

/** Concrete Prototypes to clone **/
public class CoconutCookie extends Cookie { }

/** Client Class**/
public class CookieMachine {

private Cookie cookie;//could have been a private Cloneable cookie;

public CookieMachine(Cookie cookie) {
this.cookie = cookie;
}
public Cookie makeCookie() {
return (Cookie)cookie.clone();
}
public static void main(String args[]) {
Cookie tempCookie = null;
Cookie prot = new CoconutCookie();
CookieMachine cm = new CookieMachine(prot);
for (int i=0; i<100; i++)
tempCookie = cm.makeCookie();
}
}

Prototype
- 원형 인터페이스로 객체 복사에 사용할 메소드를 정의한다.
- Cloneable 인터페이스 상속.

ConcretePrototype
- Prototype 인터페이스 구현하여 실제 복사 로직 구현.

Client
- Prototype 인터페이스를 사용하여 새로운 객체를 만든다.

주의할 것.
- Cloenable은 마커 인터페이스.
- 실제 clone 메소드는 Object 클래스에 들어있다.
- 필드 대 필드 복사라서 배열의 경우 레퍼런스를 복사해서 위험할 수 있다. 그럴 땐 직접 clone 메소드를 재정의 해야 한다.
- clone을 재정의 할 떄는 super.clone()을 호출해야 한다.
- clone은 복사만 하지 생성자를 호출하지 않는다. 그래서 생성시에 로직이 필요한 땐 그 로직도 clone에 같이 넣어 준다.
- 자세한건 API를 보시라...

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

[OOAD] 객체지향 원칙 1. SRP  (2) 2010.05.07
[Tell, Don't Ask] 물어보지 말고 시켜라  (8) 2010.04.07
Visitor 패턴  (2) 2010.03.12
Holub on Pattern 좋은데요~  (4) 2008.12.07
프로토타입 패턴(Prototype Pattern)  (2) 2008.10.31
데코레이터(Decorator) 패턴  (0) 2008.10.01
프록시(Proxy) 패턴  (0) 2008.09.26
JUnit 공부하자.  (0) 2008.09.01
H.F.OOAD 5장 문제  (0) 2007.11.20
상위 클래스 보다는 인터페이스를...  (4) 2007.08.31
Singletons and lazy loading  (2) 2007.01.27
top


데코레이터(Decorator) 패턴

Design Pattern : 2008.10.01 11:52


참조:
Java 언어로 배우는 디자인 패턴 입문

- 장식과 내용물을 동일시하기: 투과적인 인터페이스를 두고 객체에 기능들을 추가하여 목적으로 하는 객체를 만들어 나가는 방식.
- Component: 꾸밀 대상이 되는 요소, 인터페이스 or 추상 클래스
- Concrete Component: 컴포넌트 구현체
- Decorator: 장식물 인터페이스, 컴포넌트와 동일한 인터페이스를 가지며(extends), 자신의 멤버로도 가지고 있다.(delegation) 
- Concrete Decorator: 장식물 구현체.

사용자 삽입 이미지
출처: http://en.wikipedia.org/wiki/Decorator_pattern

- 내용을 바꾸지 않고 기능을 추가할 수 있다.
- 투과적인 인터페이스

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

[OOAD] 객체지향 원칙 1. SRP  (2) 2010.05.07
[Tell, Don't Ask] 물어보지 말고 시켜라  (8) 2010.04.07
Visitor 패턴  (2) 2010.03.12
Holub on Pattern 좋은데요~  (4) 2008.12.07
프로토타입 패턴(Prototype Pattern)  (2) 2008.10.31
데코레이터(Decorator) 패턴  (0) 2008.10.01
프록시(Proxy) 패턴  (0) 2008.09.26
JUnit 공부하자.  (0) 2008.09.01
H.F.OOAD 5장 문제  (0) 2007.11.20
상위 클래스 보다는 인터페이스를...  (4) 2007.08.31
Singletons and lazy loading  (2) 2007.01.27
top


프록시(Proxy) 패턴

Design Pattern : 2008.09.26 14:46


참조: Java 언어로 배우는 디자인 패턴 입문

- 필요해지면 만들기
- Proxy는 대리인
- 대리인이 처리할 수 있는 일은 대리인이 처리하고, 본인이 필요할 때에만 할 일을 본인에게 위임.

사용자 삽입 이미지
출처: http://en.wikipedia.org/wiki/Proxy_pattern

- 무거운 객체 생성이 필요할 때, 해당 객체가 정말로 필요한 시점에 생성하고, 그 전까지는 프록시가 해당 객체 역할을 대신하여 애플리케이션 성능을 높일 수 있다.

- 프록시 종류: Virtual Proxy, Remote Proxy, Access Proxy

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

[Tell, Don't Ask] 물어보지 말고 시켜라  (8) 2010.04.07
Visitor 패턴  (2) 2010.03.12
Holub on Pattern 좋은데요~  (4) 2008.12.07
프로토타입 패턴(Prototype Pattern)  (2) 2008.10.31
데코레이터(Decorator) 패턴  (0) 2008.10.01
프록시(Proxy) 패턴  (0) 2008.09.26
JUnit 공부하자.  (0) 2008.09.01
H.F.OOAD 5장 문제  (0) 2007.11.20
상위 클래스 보다는 인터페이스를...  (4) 2007.08.31
Singletons and lazy loading  (2) 2007.01.27
객체지향 디자인 원칙  (2) 2006.12.11
top


JUnit 공부하자.

Design Pattern : 2008.09.01 19:45


코딩하기
TDDBE에 있는 xUnit 예제 코드 자바로 코딩하기.
TDD - xUnit 18장.
TDD - xUnit 19장 (2)
TDD - xUnit 20장
TDD - xUnit 21장
TDD - xUnit 22장
TDD - xUnit 23장

코드보기


1.0 코드는 구하기 힘듬. 하지만 구했음 캬캬. 테스트 코드 분실.
2.0 코드의 가장 큰 변화는 "test"가 앞에 붙은 녀석들을 자동으로 등록/실행.
3.0 코드의 가장 큰 변화는 Assert가 상위 클래스가 됨.

개념파악
http://www.martinfowler.com/bliki/Xunit.html <- 기원
http://www.martinfowler.com/bliki/JunitNewInstance.html <- 왜 Isolate 시켰는가?
junit doc에 있는 cooktour 읽을 것.


Kent Beck 한테 배우는 거다. JUnit에 담겨 있는 패턴과 깔끔한 코드를...

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

Visitor 패턴  (2) 2010.03.12
Holub on Pattern 좋은데요~  (4) 2008.12.07
프로토타입 패턴(Prototype Pattern)  (2) 2008.10.31
데코레이터(Decorator) 패턴  (0) 2008.10.01
프록시(Proxy) 패턴  (0) 2008.09.26
JUnit 공부하자.  (0) 2008.09.01
H.F.OOAD 5장 문제  (0) 2007.11.20
상위 클래스 보다는 인터페이스를...  (4) 2007.08.31
Singletons and lazy loading  (2) 2007.01.27
객체지향 디자인 원칙  (2) 2006.12.11
Losely Coupled를 활용하라.  (0) 2006.12.11
top


H.F.OOAD 5장 문제

Design Pattern : 2007.11.20 17:48


사용자 삽입 이미지

위와 같은 클래스다이어그램을 주고 개선시키라고 합니다. ㄷㄷㄷ;

영문판으로는 230쪽인데 한글판은 몇 페이진지 모르겠네요. 재밌을 것 같아서 EA로 그려봤습니다. 가장 신경써야 할 세 가지 원칙을 알려주었습니다.
  1. Interface :: 인터페이스 기반으로 프로그래밍 할 것.
  2. Encapsulation :: 여러번 나타나는 것은 Encapsulation으로 숨길 것.
  3. Change :: 오직 하나의 변화에 클래스가 영향을 받도록 설계할 것.
1. 이래야 클래스가 Flexibility를 유지할 수 있기 때문입니다.
2. 단순하게 프로퍼티를 private로 설정하는 것 만이 Encapsulation이 아니라는 것을 이 책 어딘가에서 설명했었습니다.(1장인가..)
3. 단인책임원칙 SRP(Single Role of Responsibilty 맞나;;)와 관련있는 내용입니다. 여러가지 변경 사유로 인해 하나의 클래스가 계속 바껴야 한다면, 그 클래스가 책임지고 있는 일이 너무 많기 때문입니다. 나눠줘야 합니다.

어려워요...OTL
데이트하고와서 한번 해봐야겠네요.

혹시 해보고 싶으신 분이 있을지 몰라서 파일을 올려봅니다.



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

Holub on Pattern 좋은데요~  (4) 2008.12.07
프로토타입 패턴(Prototype Pattern)  (2) 2008.10.31
데코레이터(Decorator) 패턴  (0) 2008.10.01
프록시(Proxy) 패턴  (0) 2008.09.26
JUnit 공부하자.  (0) 2008.09.01
H.F.OOAD 5장 문제  (0) 2007.11.20
상위 클래스 보다는 인터페이스를...  (4) 2007.08.31
Singletons and lazy loading  (2) 2007.01.27
객체지향 디자인 원칙  (2) 2006.12.11
Losely Coupled를 활용하라.  (0) 2006.12.11
상속보다는 구성을 활용한다.  (0) 2006.12.11
top


상위 클래스 보다는 인터페이스를...

Design Pattern : 2007.08.31 23:56


AJN의 AgileJava 4th 스터디에서 Head First Java를 가지고 스터디하고 있습니다. 이번주는 7, 8, 9장을 다룰 것 같은데 7장을 열자마자 이상함을 느꼈습니다.

해당 챕터의 주제가 "상속과 다형성" 이다보니 상속을 이야기 하기 위해 여러 예제를 보여주며 설명하고 있는데 대부분의 예제의 상위 클래스가 제가 보기엔 클래스로 정의하기에는 상당히 추상적이라 인터페이스로 선언하는 것이 맞게 보입니다.

Shape 이라는 클래스에 rotate()와 playSound() 메소드가 정의되어 있고 이 클래스를 상속한 Square, Circle, Triangle, Amoeba 클래스가 있습니다.
사용자 삽입 이미지
도대체 Shape 클래스에 있는 메소드들은 어떻게 구현을 하는 걸까요? 흠;;

상위 클래스는 아래에서 위로 만들어져야 자연스러운 것 같습니다. 반대로 위에서 아래로 구조가 만들어 질 떄는 인터페이스가 어울립니다.

상속 구조는 하위 클래스들 간에(아직 자신이 하위 클래스인줄 모르는 상태에서) 공통되는 코드가 있을 때 그것을 제거하기 위해서 상위클래스가 만들어져야 합니다. 그래야 상위클래스가 쓸모가 있어집니다. 안그럼 위처럼 멍하니 하는일이 애매한 상위클래스가 만들어집니다.

반대로 인터페이스는 애초에 다른 컴포넌트와의 약속을 위해 미리 정해 놓을 수도 있고 이 인터페이스를 구현하는 클래스에 반드시 있어야할 메소드들을 강제 할 수 있기 때문에 미리 인터페이스를 설계 해두고 클래스들이 구현하도록 할 수 있습니다. 물론 매우 자연스러운 현상이며 나중에 필요로 인해 인터페이스와 클래스들 사이에 추상 클래스가 들어설 수도 있겠습니다. 그때가 되면 아래와 같이 바뀔 것입니다.

사용자 삽입 이미지
이러한 구조로 가더라도 결국 다형성은 사용할 수 있게 되며 필요에 따라 Shape 인터페이스를 구현하여 확장할 수도 있으며 AbsractShape을 상속 받아서 구현할 수도 있기 때문에 확장성은 더욱 좋아집니다.

새로운 기능의 추가을 추가 한다고 했을 때에도 새로운 메소드를 가진 인터페이스를 구현하도록 추가만 하면 되는 반면에 상속 구조에서는 상위 클래스를 수정해야 하고, 그렇게 되면 하위 클래스들 중에는 원치 않는데도 상위 클래스의 메소드를 가지게 되는 경우가 발생할 수 도 있습니다.

이래저래 애초부터 상위클래스를 계획하지 말고 처음에는 인터페이스 기반으로 설계를 하고 상위클래스는 필요에 따라 뽑아 내는 것이 그럴싸해 보입니다.
top


Singletons and lazy loading

Design Pattern : 2007.01.27 10:40


참조 : http://www.oreillynet.com/onjava/blog/2007/01/singletons_and_lazy_loading.html?CMP=OTC-FP2116136014&ATT=Singletons+and+lazy+loading

싱글톤 패턴이 클래스 달랑 하나여서 제일 간단해 보이는 디자인 패턴임에도 불구하고 Lazy Loading 또는 초기화 지연 기법을 사용하려고 하면 굉장히 복잡해 지네요. 그리고 동기화 문제도 생각하면 syncronized가 필수가 됩니다. 그래서 보통은 아래 처럼 구현을 하죠.

class Singleton {

    private static Singleton instance;

    private Singleton() {
    }

    public static synchronized Singleton getInstance() {
        return (instance != null) ? instance : (instance = new Singleton())
    }
}

하니면 초기화 지연 기법을 포기하고 아예 처음 변수를 선언할 때 객체도 만들어 버립니다.

class Singleton {

    private static Singleton instance = new Singleton();

    private Singleton() {
    }

    public static synchronized Singleton getInstance() {
        return instance;
    }
}

아니면 Head First Design Pattern에도 살짝 나왔던 것 같은데 2중 체크 라는 것을 합니다. 하지만 이것도 되는 것 처럼 보일 뿐 제대로 동작하지 않습니다.

// Correct Double-Checked Locking for 32-bit primitives
class Foo {
    private int cachedHashCode = 0;
    public int hashCode() {
        int h = cachedHashCode;
        if (h == 0)
        synchronized(this) {
            if (cachedHashCode != 0) return cachedHashCode;
            h = computeHashCode();
            cachedHashCode = h;
        }
        return h;
    }
    // other functions and members...
}

예제 코드가 좀 거시기 하지만 얼추 이와 비슷한 코드들이 동기화 관련된 부분에서 자주 보입니다. 이게 제대로 동작하지 않는 이유는 빨간 색 코드를 호출해서 h가 참조할 객체가 만들어 지는 도중에 녹색 조건 문에 다른 쓰레드가 걸려서 다 만들어 지지도 않은 객체의 레퍼런스를 가져갈 수 있기 때문인 것 같은데 이 것에 대한 자세한 내용은 여기를 참조하세요.

Anyway... 그럼 어떻게 하면 좀더 간단하고 빠르게(syncronized를 쓰지 않고) 싱글톤과 초기화 지연 기법을 사용할 수 있을까 하는게 참조한 글의 주제 였는데요.

public class Singleton {

    static class SingletonHolder {
        static Singleton instance = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }

}

이 코드는 위키피디아에 Initialization on Demand Holder를 참조 했다고 합니다. 위 코드를 보시면 먼저 Syncronized가 사라진걸 볼 수 있구요. 따라서 멀티 쓰레드 환경에서 매우 빠르게 동작할 것 같습니다. 그리고 초기화 지연은 어떻게 보장을 할까요. getInstance() 메소드가 호출되면 그 때 static inner 클래스인 SingletonHolder가 JVM에 로딩 되게 되고 그 때서야 객체는 만들어 지게 되는거죠. 그리고 그 이후에는 static이니까 싱글톤.. 단일 객체를 보장하게 되는 겁니다.

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

데코레이터(Decorator) 패턴  (0) 2008.10.01
프록시(Proxy) 패턴  (0) 2008.09.26
JUnit 공부하자.  (0) 2008.09.01
H.F.OOAD 5장 문제  (0) 2007.11.20
상위 클래스 보다는 인터페이스를...  (4) 2007.08.31
Singletons and lazy loading  (2) 2007.01.27
객체지향 디자인 원칙  (2) 2006.12.11
Losely Coupled를 활용하라.  (0) 2006.12.11
상속보다는 구성을 활용한다.  (0) 2006.12.11
바뀌는 부분을 캡슐화 한다.  (0) 2006.12.11
State Pattern 예제  (2) 2006.12.10
top


객체지향 디자인 원칙

Design Pattern : 2006.12.11 15:46


바뀌는 부분은 캡슐화한다.

상속보다는 구성을 활용한다.

구현이 아닌 인터페이스에 맞춰서 프로그래밍 한다.

서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다.


클래스는 확장에 대해서는 열려있지만 변경에 대해서는 닫혀 있어야 한다.

추상화된 것에 의존하라. 구상 클래스에 의존하지 않도록 한다.

친한 친구들하고만 이야기한다.

먼저 연락하지 마세요. 저희가 연락드리겠습니다.

어떤 클래스가 바뀌게 되는 이유는 한 가지 뿐이어야 한다.


원칙은 원칙일뿐 목적이나 법칙은 아닙니다.

참조 : Head First Design Patterns


ps : 시험 끝~~~~~~~

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

프록시(Proxy) 패턴  (0) 2008.09.26
JUnit 공부하자.  (0) 2008.09.01
H.F.OOAD 5장 문제  (0) 2007.11.20
상위 클래스 보다는 인터페이스를...  (4) 2007.08.31
Singletons and lazy loading  (2) 2007.01.27
객체지향 디자인 원칙  (2) 2006.12.11
Losely Coupled를 활용하라.  (0) 2006.12.11
상속보다는 구성을 활용한다.  (0) 2006.12.11
바뀌는 부분을 캡슐화 한다.  (0) 2006.12.11
State Pattern 예제  (2) 2006.12.10
캡슐화  (0) 2006.12.09
top


Losely Coupled를 활용하라.

Design Pattern : 2006.12.11 15:19


서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다. 라는 원칙인데 간단히 줄여봤습니다.

2장 Observer Pattern
=> WheatherData와 Display가 서로 인터페이스를 가지고 있슴으로 해서 둘의 종속성을 느슨하게 했습니다. p91

쌍방간에 인터페이스를 활용한 예제는 2장 Observer Pattern 밖에 없는 것 같습니다. 단방향으로 느슨한 결합은 거의 단원에서 보여지고 있기 때문에 생략합니다.

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

JUnit 공부하자.  (0) 2008.09.01
H.F.OOAD 5장 문제  (0) 2007.11.20
상위 클래스 보다는 인터페이스를...  (4) 2007.08.31
Singletons and lazy loading  (2) 2007.01.27
객체지향 디자인 원칙  (2) 2006.12.11
Losely Coupled를 활용하라.  (0) 2006.12.11
상속보다는 구성을 활용한다.  (0) 2006.12.11
바뀌는 부분을 캡슐화 한다.  (0) 2006.12.11
State Pattern 예제  (2) 2006.12.10
캡슐화  (0) 2006.12.09
H.F. Design Pattern 트집잡기  (4) 2006.12.09
top


상속보다는 구성을 활용한다.

Design Pattern : 2006.12.11 15:06


1장 Stratey Pattern
=> Duck 클래스에서 Flyable과 Quackable 인터페이스를 가지고 있습니다. p44

3장 Decorator Pattern
=> CondimentalDecorator는 상속과 Composition을 둘 다 활용하고 있습니다. p130

4장 Factory Pattern
=> 각각의 PizzaStore는 PizzaIngredientFacrory 인터페이스를 가지고 있습니다. p195

7장 Adapter Pattern
=> 객체 어댑터의 경우 Compositon을 활용하여 유연성을 높이고 있습니다. p283

9장 Composite Pattern
=> Decorator Pattern과 비슷한 모양으로 상속과 Composition 둘 다 활용하고 있습니다. p396

10장 State Pattern
=> GumballMachine이 모든 Sate들을 가지고 있습니다. p448


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

H.F.OOAD 5장 문제  (0) 2007.11.20
상위 클래스 보다는 인터페이스를...  (4) 2007.08.31
Singletons and lazy loading  (2) 2007.01.27
객체지향 디자인 원칙  (2) 2006.12.11
Losely Coupled를 활용하라.  (0) 2006.12.11
상속보다는 구성을 활용한다.  (0) 2006.12.11
바뀌는 부분을 캡슐화 한다.  (0) 2006.12.11
State Pattern 예제  (2) 2006.12.10
캡슐화  (0) 2006.12.09
H.F. Design Pattern 트집잡기  (4) 2006.12.09
Design Pattern 기말고사  (0) 2006.12.08
top


바뀌는 부분을 캡슐화 한다.

Design Pattern : 2006.12.11 14:30


1장 Stratey Pattern
=> fly()와 quack()이 여러 형태가 존재하기 때문에 interface로 따로 빼내었습니다. p44

2장 Observer Pattern
=> display()를 따로 빼내었습니다. p79

3장 Decorator Pattern
=> cost()를 따로 빼내었습니다. p120

4장 Factory Pattern
=> orderPizza()를 팩토리 메소드로 빼냈습니다. p150

5장 Command Pattern
=> 요구사항(action())을 커맨드 객체로 캡슐화 p244

8장 Template Pattern
=> 알고리즘 캡슐화
top


State Pattern 예제

Design Pattern : 2006.12.10 10:42


문제 : 2) [30점]  State pattern에서 공짜 알맹이 당첨 기능을 추가 하고 반응이 좋아 다른 한 가지 변경을 다하고자 한다. 현제의 기계에서는 한 번에 하나의 동전만 넣을 수 있다. 다른 뽑기 기계에서와 같이 한꺼번에 2개, 3개, 혹은 원하면 더 많은 동전을 넣을 수 있도록 하는 기능을 추가 해 달라는 요청이다.
   a. [10점] 확장된 state diagram을 그려라.
   b. [10점] State Pattern을 적용하지 않은 경우를 구현하라.
   c. [10점] State Pattern을 적용한 시스템을 구현하고, 패턴을 적용하지 않은경우와 비교해서 확장이 얼마나 쉬워 졌는지 설명하라.

A.
사용자 삽입 이미지

B. 각각의 상태를 flag로 두고 각 메소드 안에서 if-else문을 엄청나게 사용하여 구현을 해보라는 것인 것 같군요.

C. 새로운 상태(동전이 여러개인 상태)를 동전 있슴 State의 하위 클래스로 상속을 사용한 뒤 필요한 메소드를 오버라이딩 하면 될 것 같습니다.

자~ 이제 코딩하자 기선아.

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

Singletons and lazy loading  (2) 2007.01.27
객체지향 디자인 원칙  (2) 2006.12.11
Losely Coupled를 활용하라.  (0) 2006.12.11
상속보다는 구성을 활용한다.  (0) 2006.12.11
바뀌는 부분을 캡슐화 한다.  (0) 2006.12.11
State Pattern 예제  (2) 2006.12.10
캡슐화  (0) 2006.12.09
H.F. Design Pattern 트집잡기  (4) 2006.12.09
Design Pattern 기말고사  (0) 2006.12.08
Template Method Pattern을 사용하는 QuickSorting  (0) 2006.12.08
Simple Factory  (4) 2006.11.13
top


캡슐화

Design Pattern : 2006.12.09 23:39


캡슐화는 보통 Encapsulation이라는 단어를 한글로 대체 할 때 사용을 하고 있습니다. 객체의 데이터들을 숨긴다는 것을 뜻합니다. 하지만 좀더 추상적인 의미로 추상화라는 단어를 생각해 보면 다른 모습들을 생각해 볼 수 있습니다.

A circle with an inner circle filled with items, surrounded by gray wedges representing methods that allow access to the inner circle.

출처 : http://java.sun.com/docs/books/tutorial/java/concepts/object.html

위 그림은 데이터를 캡슐화 한 것이며 가장 일반적으로 생각하는 캡슐화의 모습입니다.

이렇게 데이터만 캡슐화 하는 것이 아니라 메소드의 일부분을 캡슐화 할 수도 있습니다. 자주 변화하는 부분만을 다른 클래스로 따로 빼내는 것이 바로 그런 캡슐화가 아닌가 생각해봅니다. 그리고 아마도 그림으로 표현하면 다음과 같을 것입니다.

사용자 삽입 이미지

자주 변하는 부분을 다른 클래스로 빼냄으로 해서 기존의 클래스는 변화에 닫힐 가능성이 높아지고 그럼으로 해서 OCP원칙에 한발작 다가서게 됩니다. 그리고 조금더 캡슐화를 추상화 시키면 Inner Class가 떠오릅니다. Class안에서 특정 Class를 캡슐화 하고 있는 모습이 바로 Inner Class와 잘 매칭 된다고 생각합니다.

관련 시험 문제 보기


ps : 그림이 너무 허접하네요.. ㅠ.ㅠ 방학때 포토샵도 살짝 공부할 예정이오니 아마 차후에는 그림 실력이 조금 나아질 것 같습니다. ㅎㅎ

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

객체지향 디자인 원칙  (2) 2006.12.11
Losely Coupled를 활용하라.  (0) 2006.12.11
상속보다는 구성을 활용한다.  (0) 2006.12.11
바뀌는 부분을 캡슐화 한다.  (0) 2006.12.11
State Pattern 예제  (2) 2006.12.10
캡슐화  (0) 2006.12.09
H.F. Design Pattern 트집잡기  (4) 2006.12.09
Design Pattern 기말고사  (0) 2006.12.08
Template Method Pattern을 사용하는 QuickSorting  (0) 2006.12.08
Simple Factory  (4) 2006.11.13
Principle of Least Knowledge  (4) 2006.11.11
top


H.F. Design Pattern 트집잡기

Design Pattern : 2006.12.09 00:33


2장 p80쪽에 나오는 getter들과 p105쪽에 구현되어 있는 getter들이 일치 하지 않음.

more..


3장 p129쪽에 나오는 다이어그램이 보여주고 있는 UML의 선이 나타내는 의미와 클래스안에 있는 표기된 멤버가 일치하지 않음.

more..


5장 Lazy instantiation을 '게으른 초기화'로 번역하고 있슴.

more..


7장 p286쪽 맨 아래에 보면 Enumerator 인터페이스를 사용하다가 전부 Iterator만 사용하도록 바꿀 것이라고 합니다. 그리고 다음 장 부터 Iterator 인터페이스를 어댑터 패턴을 이용해서 내부적으로는 Enumerator를 사용하도록 해주는 클래스를 만들기 시작합니다,.

more..


8장 p338쪽 하단에 mergeSort() 메소드가 있는데 안에 보면 전혀 머지 소트가 아닙니다.

more..


이 글을 참고 or 배낄지도 모를 저와 같은 학부 학생들에게...

more..

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

Losely Coupled를 활용하라.  (0) 2006.12.11
상속보다는 구성을 활용한다.  (0) 2006.12.11
바뀌는 부분을 캡슐화 한다.  (0) 2006.12.11
State Pattern 예제  (2) 2006.12.10
캡슐화  (0) 2006.12.09
H.F. Design Pattern 트집잡기  (4) 2006.12.09
Design Pattern 기말고사  (0) 2006.12.08
Template Method Pattern을 사용하는 QuickSorting  (0) 2006.12.08
Simple Factory  (4) 2006.11.13
Principle of Least Knowledge  (4) 2006.11.11
Adapter Pattern  (0) 2006.11.11
top


Design Pattern 기말고사

Design Pattern : 2006.12.08 20:36


이번 시험도 중간고사와 마찬가지로 Taking Home 방식입니다. 이런 시험을 한 학기에 두번이나 치르게 되다니.. 재미는 있지만 범위가 넓다보니 약~간 힘들어 지려고 하네요.

시험범위는 1장~11장(Strategy, Observer, Decorator, Factory, Singleton, Command, Adapter, Facade, Template, Iterator, Composit, State, Proxy)이고 현재까지 세 문제를 출제하셨습니다. 출제가 완료됐습니다.

1. 캡슐화에 대한 문제.
(완료)
2. State Pattern(10장)의 뽑기 기계 응용한 문제.(완료)
3. Quick Sorting에서 Pivot 구하는 부분을 탬플릿 메소드 패턴을 적용하여 구현하시오.(완료)
4. 디자인 원칙에 관한 문제.
5. 책에서 잘못 된 부분을 찾아 고치시오.(완료)

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

상속보다는 구성을 활용한다.  (0) 2006.12.11
바뀌는 부분을 캡슐화 한다.  (0) 2006.12.11
State Pattern 예제  (2) 2006.12.10
캡슐화  (0) 2006.12.09
H.F. Design Pattern 트집잡기  (4) 2006.12.09
Design Pattern 기말고사  (0) 2006.12.08
Template Method Pattern을 사용하는 QuickSorting  (0) 2006.12.08
Simple Factory  (4) 2006.11.13
Principle of Least Knowledge  (4) 2006.11.11
Adapter Pattern  (0) 2006.11.11
엔터프라이즈 컴퓨팅 중간고사 5)  (0) 2006.10.23
top


Template Method Pattern을 사용하는 QuickSorting

Design Pattern : 2006.12.08 20:33


문제는 다음과 같습니다.

more..


Test 클래스를 먼저 작성했습니다.

more..


그리고 탬플릿 역활을 하는 QuickSorting 메소드를 작성했습니다.

more..

여기서 getPivoit 메소드가 비어있는 탬플릿이 됩니다. 이 것을 구현하는 하위 클래스들은 pivot을 구하는 방법에 따라 getPivot 메소드를 다르게 구현할 것입니다.

Pivot은 다음과 같이 세가지 방법으로 구현하라고 하였습니다.
   a. 가장 오른쪽 인자를 Pivot으로 하는 경우.
   b. 가장 오른쪽 인자를 Pivot으로 하는 경우.
   c. Random하게 Pivot을 선택하는 경우.

간단하게 구현과 테스트가 가능합니다.


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

바뀌는 부분을 캡슐화 한다.  (0) 2006.12.11
State Pattern 예제  (2) 2006.12.10
캡슐화  (0) 2006.12.09
H.F. Design Pattern 트집잡기  (4) 2006.12.09
Design Pattern 기말고사  (0) 2006.12.08
Template Method Pattern을 사용하는 QuickSorting  (0) 2006.12.08
Simple Factory  (4) 2006.11.13
Principle of Least Knowledge  (4) 2006.11.11
Adapter Pattern  (0) 2006.11.11
엔터프라이즈 컴퓨팅 중간고사 5)  (0) 2006.10.23
엔터프라이즈 컴퓨팅 중간고사 2), 3), 4)  (0) 2006.10.23
top


Simple Factory

Design Pattern : 2006.11.13 11:27


"new"는 "구상 객체"를 뜻합니다. 즉 new를 사용하는 것은 구상 클래스의 인스턴스를 만드는 것이고 특정 구현에 종속된다는 뜻입니다.

Pizza pizza = new CheesePizza();


이 코드에서 new를 사용했다고해서 무슨 문제가 있는 것은 아닙니다. 문제는 "변화" 입니다. Cheese 피자 말고 Pepperoni 피자와 Greek 피자도 있다고 한다면 Pizza를 선택할 때 다음과 같이 코드가 바뀌게 됩니다.

if(type.equals("cheese")
   pizza = new CheesePizza();
if(type.equals("greek")
   prizza = new GreekPizza();
if(type.equals("pepperoni")
   pizza = new PepperoniPizza();


새로운 클래스가 추가 될 때마다 코드를 고쳐야 되기 때문에 문제가 생길 수 있습니다. 이런 경우 변화에 닫혀 있다고 합니다. OCP 원칙에 반대되는 형태로군요. 이럴 때 바뀌는 부분을 밖으로 빼내어 Factory 메소드로 만들면 훨씬 보기 좋고 사용하기도 편해집니다.

factory method를 사용하지 않는 경우의 Pizza 클래스입니다.

이 때 분홍색 부분의 코드 때문에 새로운 피자가 추가 될 때 마다 이 클래스는 계속 변경이 되어야 합니다.

이런 변경되는 부분은 따로 빼내는 것은 종종 유용한 경우가 있었습니다.(Strategy Pattern에서 Duck의 행동을 인터페이스로 빼내는 예가 있었습니다.)

이런 부분을 다른 클래스로 빼내고 그 클래스에 factory의 레퍼런스 변수로 팩토리 메소드를 호출하여 Pizza를 받아오는 형식으로 개선 할 수 있겠습니다.


현재의 모습을 클래스 다이어그램으로 보면 다음과 같습니다.


PizzaStore에서 Pizza 인터페이스를 구현한 특정 클래스 들에 종속되고 있습니다. 이것을 개선하기 위해서 이제 분홍색 부분을 SimplePizzaFactory 클래로 옮기고 orderPizza 메소드는 다음과 같이 수정합니다.

소스보기

more..


이렇게 하면 클래스 다이어그램은 다음과 같이 바뀌게 됩니다.


이렇게 PizzaStore에서 if-else if-else 와 같이 변하는 부분을 따로 클래스로 빼내게 되면 PizzaStore는 새로운 Pizza가 추가 되거나 메뉴에서 사라지더라도 소스코드가 변경될 일은 없습니다. 다만 SimplePizzaFactory의 코드는 계속 변경이 되겠지요.

지금까지 본 것을 하나의 패턴으로 정의 할 수는 없다고 합니다. 하지만 설계와 관련된 기술서를 읽다보면 팩토리 패턴, 팩토리 메소드라는 단어가 나올때 위의 그림을 떠올려 보면 대부분은 쉽게 이해가 될 것입니다.

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

State Pattern 예제  (2) 2006.12.10
캡슐화  (0) 2006.12.09
H.F. Design Pattern 트집잡기  (4) 2006.12.09
Design Pattern 기말고사  (0) 2006.12.08
Template Method Pattern을 사용하는 QuickSorting  (0) 2006.12.08
Simple Factory  (4) 2006.11.13
Principle of Least Knowledge  (4) 2006.11.11
Adapter Pattern  (0) 2006.11.11
엔터프라이즈 컴퓨팅 중간고사 5)  (0) 2006.10.23
엔터프라이즈 컴퓨팅 중간고사 2), 3), 4)  (0) 2006.10.23
엔터프라이즈 컴퓨팅 1)-2  (0) 2006.10.23
top


Principle of Least Knowledge

Design Pattern : 2006.11.11 14:30


최소 지식 원칙이라고도 하고 데메테르의 법칙 이라고도 합니다. 둘 다 같은 말이지만 책에서는 법칙이라고 하기보단 원칙이라는 말이 더 어울리고 최조 지식이라는 말이 원리를 더 잘 나타내고 있기 때문에 최소 지식 원칙이라는 말을 사용하기로 했답니다.
디자인 원칙
최소 지식 원칙 - 정말 친한 친구하고만 얘기하라.
인연을 많이 맺으면 맺을 수록 인생이 고달파 지기 때문에 되도록이면 인연을 맺지 않으면서 다른 객체들에게 영향력을 행사하는 방법으로 네가지가 있습니다.
  • 객체 자체의 매소드 호출
  • 메소드에 매개변수로 전달된 객체의 메소드 호출
  • 그 메소드에서 생성하거나 인스턴스를 만든 객체
  • 그 객체에 속하는 구성요소
이렇게 책에는 씌여있는데 영회 형의 옛날 블러그를 통해 찾은 c2.com에 있는 문서에 보면 다음과 같이 나와 있습니다.
  • You can play with yourself.
  • You can play with your own toys (but you can't take them apart),
  • You can play with toys that were given to you.
  • And you can play with toys you've made yourself.
순서가 조금 바꼈지만 무엇이 무엇을 번역한 것인지는 대충 짐작이 갈 것입니다. c2.com에 있는 문서에 보시면 약간 더 풀어서 설명한 글을 제공해 줍니다.

이 원칙을 위배하는 것 중에 가장 눈에 잘 띄는 모양은 줄줄이 비핸나 쏘세지 입니다. 그리고 객체 없이 그냥 호출하는 static 메소드들(facotory 패턴의 메소드나, singleton 패턴에 있는 메소드)입니다.

책에 나온 예제 소스코드 입니다.

more..


색칠 된 부분 모두 원칙에 위배되지 않습니다. 분홍색 부분은 두번째 줄에 해당하고 하늘색 부분은 세번째 줄에 해당하고 녹색은 네번째 줄에 해당하고 노란색은 첫번째 줄에 해당합니다.

위배되는 경우의 코드를 보겠습니다.

more..


분홍색 부분이 이 원칙을 배신하고 있습니다. 객체에 연쇄적으로 메소드를 호출하게 됐을 때.. 즉 위의 경우 getThermomoeter()를 호출 했을 때 받아오는 객체의 내용이 만약 바뀌게 된다면 잇따라 호출한 getTemperature() 메소드를 호출하지 못할 수도 있는 경우가 발생할 수도 있겠지요. 영회형 블러그에 있던 글을 인용하자면
그렇게 되면 설계 과정에서 관계가 강하지 않다고 떼어놓은 것에
다시 결합도(coupling)을 부여하는 결과가 되니까..
이런 모양을 원했는데...

요로케 된다는 뜻이 아닐까.. 생각해 봅니다.

위의 코드를 아래와 같이 수정하면 원칙을 따르게 됩니다.

more..



볼 거리 :
http://www.headfirstlabs.com/phpBB2/viewtopic.php?p=590&sid=70caa5b5a3b7d4ea2ed2d8e79a938635
-> 책의 이 부분에 대한 head first 포럼에 올라왔던 글입니다. 별로 재밌진 않네요. -_-;;
영회 형 예전 블러그의 글
-> 재밌지요. 다른 원칙들도 같이 정리되어 있습니다.
c2.com에 있는글
-> 이만한 자료를 찾을 수가 없었습니다. 더 좋은 자료 찾으시면 알려주세요.


top


Adapter Pattern

Design Pattern : 2006.11.11 12:29


흔히 사용하는 어댑터와 같은 역할을 하는 객체 입니다. 플랫폼에 독립적으로 클라이언트들이 사용하는 인터페이스에 맞춰 사용할 수 있도록 해줍니다.


기존 시스템에서 사용하던 소스코드는 그대로 두고 새로운 클래스의 메소드를 사용하고 싶다면 기존 시스템에서 사용하던 인터페이스를 구현하는 클래스를 만들면서 구현 할 때 사용하고 싶은 클래스의 인터페이스를 호출하면 됩니다. 그런 클래스를 어댑터라고 합니다.

이렇게하면 기존 시스템에서 사용하던 코드는 변경할 필요가 없이 기능이 확장될 수 있습니다. 이 그림은 Java를 처음 배울 때 자바의 특성중에 '플랫폼에 독립적이다.'라는 말이 나올때 마다 봤던 그림을 떠올리게 합니다. JVM자체는 플랫폼에 종속적이지만 JVM 위에서 실행되는 클래스들은 JVM 덕분에 리눅스든 윈도우든 맥이든 어디서든 돌아가게 되있다는 것이였죠.

책에서 예를 들고 있는 Duck interface를 보겠습니다.

기존 시스템에서 사용하던 인터페이스에 해당하는 Duck 인터페이스 소스보기

more..


사용하고 싶은 클래스에 해당하는 인터페이스인 Turkey 인터페이스 소스보기

more..


이 둘을 연결해주는 어댑터에 해당하는 TurkeyAdapter 클래입니다.

more..


어댑터 패턴의 정의
어댑터 패턴 - 한 클래스의 인터페이스를 클라이언트에서 사용하고자 하는 다른 인터페이스로 변환합니다. 어댑터를 이용하면 인터페이스 호환성 문제 때문에 같이 쓸 수 없는 클래스들을 연결해서 쓸 수 있습니다.

핵심이라고 생각하는 부분은 클래이언트는 바뀔 필요가 없는데 나중에 다른 구현을 추가할 수 있다는 것 같습니다. 즉 OCP가 적용되어 있는 패턴이라는 것이죠. 이런 어댑터 패턴은 크게 두 가지로 나뉘는데 하나는 객체 어댑터 패턴 다른 하나는 클래스 어댑터 패턴입니다.

먼저 객체 어댑터 패턴의 정의와 그 클래스 다이어그램 입니다.
The Object Adapter pattern- In this type of adapter pattern, the adapter contains an instance ofthe class it wraps. In this situation, the adapter makes calls to aphysical instance of the wrapped object.

감싸주는 클래스의 객체를 만들어서 호출하기 때문에 객체 어댑터 패턴이라고 합니다. Composition을 사용하여 확장이 편리하도록 했습니다.

다음은 클래스 어댑터 패턴의 정의와 클래스 다이어그램입니다.
The Class Adapter pattern - This type of adapter uses multiple inheritanceto achieve its goal. The adapter is created inheriting interfaces fromboth the interface that is expected and the interface that ispre-existing. The Object Adapter pattern is more often used as somepopular languages, such as Java, do not support true multiple inheritance as the designers of these languages consider it a dangerous practice.

top


엔터프라이즈 컴퓨팅 중간고사 5)

Design Pattern : 2006.10.23 21:22


 5) [10점] 가상대학에 올라와 있는 프로그램숙제의 예제들을 조사해서 잘못된 점들을 지적하고 수정하여라. 왜 잘못되었는지를 설명하고 수정 후에는 어떻게 좋아졌는지를 설명하라.


답 보기



코드보기


top


엔터프라이즈 컴퓨팅 중간고사 2), 3), 4)

Design Pattern : 2006.10.23 21:20


 

2) [20점] 시스템을 확장/변경 할 때 class의 수가 급격하게 늘어나는 경우가 생긴다. 이를 방치하면 관리가 어려워진다. 이 문제를 해결하기 위해 사용한 방법들을 보이고 어떻게 했는지를 설명하라. 우리가 지금까지 배운 것 중에서 예를 보여라.


답 보기




3) [30점] 우리가 원하는 것은 flexible 하고 extendable 해서, 장기적으로 적은 비용으로 효율적인 시스템을 만드는 일이다. 이것을 위해 몇 가지 원칙들을 사용해 왔다. 아래에 열거한 것들이 그 대표적인 것들이다. 이들이 지금까지 우리가 배운 디자인 패턴에서 어떻게 사용되고, 어떻게 우리가 원하는 것을 충족시켜왔는지를 설명하라.

       1.[10점] 바뀌는 부분을 캡슐화 한다.


답 보기



       2.[10점] 서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는

          디자인을 사용해야 한다.


답 보기



       3.[10점] 클래스는 확장에 대해서는 열려있고 변경에 대해서는 닫혀있어야 한다.


답 보기



4) [10점] 옵져버 패턴에서는 푸시방식과 풀 방식이 있다고 했다. 2장에서는 푸시 방식만 보였다. 이번에는 풀 방식을 보여라.


more..


top


엔터프라이즈 컴퓨팅 1)-2

Design Pattern : 2006.10.23 21:18


 2. 2차 확장/변경(1년이 지난 후)

       다.[10점] 김치피자가 인기가 좋아서 뉴욕과 시카고에서도 치피자를 메뉴에 추가 하고자 한다. Dough는 밥 대신 시카고에서 사용하는 ThickCrustDough를 사용한다. 뉴욕에서는 된장이 쉽게 구할 수 있지만 시카고에서는 한국된장이 쉽게 구할 수 있는 재료가 아니라서 일본된장을 사용하기로했다.


답 보기



more..



top


엔터프라이즈 컴퓨팅 중간고사 1)-1-나

Design Pattern : 2006.10.23 21:16


나.[10점] 서울분점에서는 메뉴에 김치피자를 추가 하고자 한다. 김치피자에서는 Dough를 밥으로 만들어야 하고, 치즈대신 된장을 사용한다.


more..


top


엔터프라이즈 컴퓨팅 중간고사 1)-1-가

Design Pattern : 2006.10.23 21:14


 1) [30점] 교과서 4장의 문제를 확장/변경 하고자 한다. 여러 가지 확장/변경의 가능성이 있다. 이번 문제에서는 2차에 걸쳐서 확장/변경 하고자 한다. 프로그램에서 고친 부분을 보여라. 디자인 패턴을 사용해서 어떤 부분이 확장/변경이 용이하도록 해 주었는지 설명하라.

 

1. 1차 확장/변경

     

  가.[10점] 서울에 분점을 내고자 한다. 일반적으로 뉴욕의 피자와 같지만 서울

          사람들은 치즈를 좋아하지 않아서 일반적인 경우의 1/2만 사용한다. 그리고

          페퍼로니 피자의 경우 짜지 않은 “야채페퍼로니”를 사용한다.



more..


top


Decorator Pattern 예제(끝)

Design Pattern : 2006.10.22 21:04



무기쪽을 decorator pattern을 사용하여 다이어그램을 그려보았습니다.
저 주황색 부분 때문에 저 화면에 있는 모든 클래스들은 Human이 되며.. 그 중에서도 특히 WeaponDecorator 클래스들은 Human type의 모든 클래스들을 감쌀 수 있습니다.(멤버 변수로 Human 타입의 변수를 가지고 있기 때문이지요.) 용법은


String name = "백기선";
Integer hp = 100;
Integer mp = 50;
Human worrior = new Worrior(name, hp, mp);
worrior = new LongSword(worrior);

녹색 부분 처럼 감쌀 수가 있게 되는 것입니다.

구현은 먼저 Human쪽 부터 구현을 하고 그다음 WeaponDecorator..그다음은 뭐. 방어구도 Decorator로 하고 질병이며.. 나머지도 그런식으로 하면 될 듯합니다.

먼저 HumanTest class부터 작성합니다.

HumanTest code 보기


이정도 하면..Human쪽은 끝난 듯 하군요.

WeaponTest 클래스를 먼저 작성하고.. 위의 다이그램에 맞춰가며 클래스들을 구현해 갑니다.

WeaponTest class 보기


헉... 에러 발생..


어라... getter들이 값을 안가져왔군요... 흠...

에러는 어떻게든 잡았고... 나머지.. 방어구 라든가.. 질병.. 뭐 그런것도 무기쪽 구현한 거랑 똑같기 때문에 DRY(Don't Repeat Yourself)법칙에 따라 생략하겠습니다.


top


Decorator Pattern 예제

Design Pattern : 2006.10.20 16:35


데코레이터 패턴 레포트 상세 내용

게임게발을하고 있습니다. 각 케릭터는 인간이라는 한 종족으로시작을 하게 되며

한 종족은 전사, 마법사, 도둑세 가지의 직업을 가지게 됩니다. 각 케릭터가 착용하게 되는 아이템은 무기, 방어구를 착용하게 됩니다. 그리고 모든 직업은 공통적으로 HP, MP라는 속성값을 가지게 됩니다.

케릭터를생성하여 전사, 마법사, 도둑 세가지의 직업으로 나누어서각 케릭이 어떠한 직업을 가지고 어떠한 이름을 가지고 있는지 보여줍니다. 그 후 아이템을 습득하여 무기및 방어구를 습득하여서 어떠한 아이템을 착용했는지 그리고 그 아이템은 어떠한 상세 내용을 가지고 있는지에 대한 메시지를 창에 보여주게 됩니다.

또한케릭터가 독에 걸리거나 상처를 입는 등 상태이상에 걸리게 되면 케릭터가 상태이상에 걸렸다는 메시지를 창에 보여주면 됩니다.

각 아이템은 다음 예제와 같은 상세한 세부내용이 있습니다.

무기 예제

단검                               데미지 1~10

롱소드                             데미지 10~20

바스타드 소드                      데미지 10~20

방어구 예제

가죽 갑옷                          방어 확률 10%

플레이트 아머                      방어 확률 20%

풀플레이트 아머                    방어 확률 30%

상태이상은 다음 예제와 같은 상세한 세부내용이 존재합니다.

가시독

이동속도가 느려집니다.

맹독

케릭터의 HP가 감소됩니다.

마나독

케릭터의 MP가 감소됩니다.

질병

질병

케릭터의 HP, MP가 감소됩니다.

상처

케릭터가 부상을 입어 활동을 할 수 없습니다.

오.. 지쟈스.. 클래스가 몇개인고.. 이것도 월요일까지 제출해야 한다는거~

오늘 일단 이것부터 해결해야겠군요..

top