2012.05.22 23:43

1. 어뎁터 패턴이란?!


어뎁터 패턴은 110v 의 콘센트를 220v 단자에 꼽기위한 노력에서 시작된다고 생각하면 된다. 

아래의 그림을 보자.

이렇게 우리는 110v 를 220v 로 꼽기 위해 돼지코라 불리우는 마법의 소켓을 끼우게 된다.

어댑터 패턴 역시 이러한 마법의 소켓 역할을 하게 도와준다.


간단하게 큰 틀만 보기 위해 아래 그림을 보자.


그림을 보기 힘들다.. 그래 나도 안다. 하지만 제발 한번만 어떤 부분이 무슨 역할을 하는지 보고 다음으로 넘어가자.


우선 110v 라디오와 220v 라디오를 만들자.


T220Radio 플레이어에 220v 라디오를 넣고 동작시키면 잘 돌아가지만, 110v 라디오를 꼽으면 에러가 뜨게 된다.

이러한 110볼트의 콘센트 문제 때문에 우리는 돼지코를 끼워 220v 콘센트로 바꿔야 한다.


다시 돌아가서 만들어진 라디오의 콘센트 모양을 보자 라디오는 11 자형 라디오와  00 모양의 라디오 두가지로 이루어져 있다.


그리고 이 220v (twotwo) 콘센트를 implement 하여 돼지코 어뎁터를 만들고, 그 돼지코 어댑터의 생성자에 110v 라디오 객체를 받아와 조작하여 출력시켜 준다. 

즉 슬롯은 220v인데 110v 단자로 받아 처리하는 것이다. 




느낀점.


어댑터 패턴은 안드로이드 개발을하면서 SQL-lite를 사용할 때 DB접근을 위하여 사용했던 부분이였었다. 처음엔 SQL 쿼리문의 결과값을 그냥 가져와서 쓰지 못할까? 배열로 저장시키면 되지 않을까? 했는데, 이러한 타입형 문제가 존재하기에 불가능 하다.


난 어댑터를 사용하면서 이게 패턴인줄도 모르고 사용하고 있었던 것이다. 


어댑터 패턴은 안드로이드에서는 정말 자주 쓰였던 패턴이므로  코드까지 직접 구현하여 설명을 하였다. 


지금 이 글을 읽는사람이 누구든간에 잘 숙지되었으면 좋겠다. 



hack the planet~! 



Posted by k1rha
2012.05.22 09:49

1.프로토타입 패턴이란?! 

프로그램을 오래 하지 않은 사람이라면 객체가 필요할때마다 New 를 생성해서 객체를 생성해 사용 하였을 것이다.

하지만 객체를 생성할때 드는 비용이 컴퓨터 상에서는 만만치 않을 뿐더러, 너무 많은 클래스를 관리하다보면 서브 클래스를 줄이거나, 객체의 형태나 표현방식과는 무관하게 생성 하고 싶을 때가 있다. 


이를 위해 나온 것이 바로 프로토 타입! 이다. 


글씨에 테두리 모양을 넣는 객체를 생성한다고 하자.

우리는 이 글씨에 테두리를 넣을때마다 테두리 객체를 생성하여 넣어줘야 할 것이다. 

하지만 프로토타입 패턴을 이용하면 하나의 객체만을 생성하고 그 객체를 복사하여 쓸수 있다. 




정확한 표현은 아니지만 요런 느낌 이랄까?  NEW 생성자를 호출할 경우 생성자 내의 코드를 전부 재 반복해야 하기 때문에 연산이 많아진다. 하지만 메모리를 복사하여 사용할 경우 그 과정을 줄일 수 있게 된다. 

개발자는 코드로 대화하는게 가장 빠르다고 했던가?! 


아래그림과 같은 프로그램을 짠다고 생각해보자. 단순히 글짜 텍스트에 테두리를 넣어주는 프로그램이다. 


일반적으로 글자 주변에 ~~ 를 만드는 클래스, ****를 만드는 클래스, ///를 만드는 클래스 를 생성해 생성해 주어 각 클래스에 넣거나 많은 메소드(usingStar, usingSlash, using물결 ) 를 사용해서 각각을 호출 할 수 있도록 해 줘야 할 것이다. 하지만 이렇게 만들 경우에는 using 부분에 변경사항이 생겼을 때,수많은 메소드를 전부다 변경 시켜 줘야 하는 유지보수면 문제점이 생긴다. 



이때 이 객체를 하나만 생성하고 쓸때마다 복사해서 쓴다면?

그리고 두개 이상의 다른 객체를 하나의 메소드로 통일하여 사용 할 수 있다면?

 

Cloneable이라는 복사해주는 기본 클래스를 상속받아서 자신을 복사해주는 Product를 짠다. 

그리고 그때 그때 복사하여 사용해 주면 된다.



아래와 같이 구현  할 것이다. 



MessageBox 에서 Product의 use 추상 메소드를 각각 재정의 해주고, Project 형의 createClone() 메소드를 정의해준다. product 클래스에는 cloneable 클래스가 상속되어 있기 때문에 clone()이라는 메소드를 통해 자신을 복사 할 수 있다. 








우와같이 UnderLinePen 객체와 messageBox의 객체가 다른데도 불과하고 manager.register 를 통하여 각각의 객체를 등록 시켜 준다. 그리고 manager.create 를 하면 각각에 대당하는 객체로 복사를 하는것이다.


즉 다른 두 종류의 객체가 manager 를 통하여 하나로 묶어서 관리하게 된 것이다. 




이러한 프로토 타입의 사용 여부는 다른 디자인 패턴과 연동되어 많이 사용된다.

그 만큼 부작용이 적고 장점으로 뭉쳐 있는 디자인 패턴이다. 


Posted by k1rha
2012.05.22 09:49

출처 : http://99yurina.blog.me/20156605313 


객체지향 원칙
바뀌는 부분은 캡슐화 한다.
상속보다는 구성을 활용한다.
구현이 아닌 인터페이스에 맞춰서 프로그래밍한다.
서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다.
클래스는 확장에 대해서는 열려 있지만 변경에 대해서는 닫혀 있어야 한다.(OCP)
추상화된 것에 의존하라. 구상 클래스에 의존하지 않도록 한다.
어떤 클래스가 바뀌게 되는 이유는 한가지 뿐이어야만 한다.

 

 

 

PatternDesc.
Strategy기본정의 : 
알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만든다. 알고리즘을 사용하는 클라이언트와 독립적으로 알고리즘을 변경할 수 있다.

- 알고리즘의 각 단계를 구현하는 방법을 서브클래스에서 구현합니다.
- 교환 가능한 행동을 캡슐화하고 위임을 통해서 어떻게 행동을 사용할지 결정
Observer기본정의 : 
한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱식되는 방식으로 일대다 의존성을 정의한다.

- 어떤 상태가 변경되었을 때 일련의 객체들한테 연락을 할 수 있습니다.
Decorator기본정의 : 
객체에 추가 요소를 동적으로 더할 수 있습니다. 
서브 클래스를 만드는 경우에 비해 훨씬 유연하게 기능을 활장할 수 있습니다.

- 객체를 감싸서 새로운 행동을 제공
- 컬렉션이 어떤 식으로 구현되었는지 드러내진 않으면서도
  컬렉션 내에 있는 모든 객체에 대해 반복 작업을 처리
Abstract Factory기본정의 : 
서로 연관된, 의존적인 객체들로 이루어진 제품군을 생성하기 위한 인터페이스를 제공합니다.
Factory Method기본정의 : 
객체를 생성하기 위한 인터페이스를 만듭니다. 
어떤 클래서의 인스턴스를 만들지는 서브클래스에서 결정하도록 합니다.
Singleton기본정의 : 
클래스 인스턴스가 하나만 만들어지도록 하고, 그 인스턴스에 대한 전역 접근을 제공
Command기본정의 : 
요청 내역을 객체로 캡슐화 하여 클라이언트를 서로 다른 요청 내역에 따라 처리.
Adaptor기본정의 : 
클래스의 인터페이스를 클라이언트에서 요구하는 다른 인터페이스로 변환
인터페이스가 호환되지 않아 쓸 수 없었던 클래스들을 같이 사용할 수 있게 해줌

- 하나 이상의 클래스의 인터페이스를 변환합니다
Façade기본정의 : 
서브시스템에 있는 일련의 인터페이스에 대한 통합 인터페이스를 제공.
서브시스템을 더 쉽게 사용할 수 있게 해주는 고수준 인터페이스

- 일련의 클래스들에 대한 인터페이스를 단순화 시킵니다.
Template기본정의 : 
작업 알고리즘의 골격을 정의

- 바꿔 쓸 수 있는 행동을 캡슐화한 다음, 실제 행동은 다른 객체에 위임합니다.
Iterator기본정의 : 
컬렉션을 표현하는 방법을 노출시키지 않으면서도 집합체 내에 있는 모든 객체들에 하나씩 접근

- 컬렉션의 구현을 드러내지 않으면서도 컬렉션에 있는 모든 객체들에 대해 반복작업을 할 수 있습니다.
Composite기본정의 : 
객체들을 트리구조로 구성하여 부분-전체 계층구조를 구현

- 클라이언트에서 객체 컬렉션과 개별 객체를 똑같은 식으로 처리할 수 있습니다.
State기본정의 : 
어떤 상태가 바뀜에 따라 객체의 행동을 바꿀 수 있습니다.
상태를 기반으로 하는 행동을 캡슐화 하고 행동을 현재 상태한테 위임.
Proxy기본정의 : 
다른 객체를 대변하는 객체를 만들어서 주 객체에 대한 접근을 제어 할수 있습니다.
Compound기본정의 : 
두 개 이상의 패턴을 결합하여 일반적으로 자주 등장하는 문제들에 대한 해법을 제공

[출처] Design Pattern|작성자 지우개


Posted by k1rha
2012.05.19 00:04

1. 빌더 패턴이란? 


복잡한 객체를 생성하는 방법과 표현하는 방법을 정의하는 클래스를 별도로 분리하여, 서로다른 표현이라도 이를 생성할 수 있는 동일한 절차를 제공 할 수 있도록 하는 패턴...


이라고~ 사전적 정의가 내려져 있다. 



하지만 나만의 방식대로 말하자면, 다양한 클래스로 생성 해야 할 것들을 하나의 클래스로 한방에 생성 하겠음!  이라고 정의하고 싶다. 물론 여기에는 묶을 수 있는 클래스와 묶을 수 없는 클래스를 구분하는 것은 개발자의 몫이다. 




2. 왜?! 빌더 패턴을 사용하는가? 


우선 피자종류에 대한 프로그램을 짠다고 해보자. 토핑과, 맛, 소스,피클양,페퍼로니,사이즈,치즈크러스터 등등 같은 것을 저장해 줘야 하는데, 이를 한클래스에서 다른이름으로 생성해 주면, 생설할때마다 속성값을 지정해 줘야 하는 불편 함이 있다. 그렇다고 다른 클래스로 생성하여 그것을 미리 설정 해 놓자니, 클래스를 재사용 하기에 불편함이 생긴다.


이 두가지 문제를 해결 하기 위한 것이 빌더 패턴이다.


즉!! 각각의 피자의 속성값을 생성 할때부터 미리 정해 놓을 수 있는데, 같은 객체타입으로 다룰수 있다는 것이다. 

이는 유지보수 면에서 엄청난 매리트다. 



3. 코드 예시 (출처 wikipedia_)



위 그림을 보면, PizzaBuilder 라는 객체를 hawaiian_pizza 와 spicy_pizza 로 각각 생성해 주는데, 이를 new PizzaBuilder 로 선언해 주는 것이 아니라, 그림의 2번 처럼 각각의 hawaiian_pizza 와 spicy_pizza 로 생성한 객체를  각각의 타입이 아닌 pizzaBuilder 타입으로 넣는다!. 


이해를 돕기 위해 PizzaBuilder 추상클래스를 보면, 그림의 1번에서 처럼 pizza 객체를 생성하고, 각각의 메소드를 구현해 놓았다. 그리고 각각의 추상클래스로 builderSource, BuildTopping 등의 추상메소드를 구현해 놓는다.


이제 이러한 PizzaBuilder 를 상속 받아 다양한 피자 객체들을 만들면 PizzaBuilder 에는 이미 피자 객체가 있기 때문에 각각의 속성 값들을 지정해 가지고 있을 수 있다.


이렇게 생성된 다른 객체는 같은 객체로 다뤄질 수 있게 되는 것이다. 



4.느낀점 


 프로그래밍을 오래 한 편이 아니기에 클래스를 선언하고 그 안에 들어가는 객체는 같은 이름의 객체로 생성하는 것만 보았었는데, 저런식으로 타입만 맞추어 다양한 클래스를 집어 넣는 경우를 빌더 패턴을 통해 배운 기분이다. 







Posted by k1rha
2012.05.03 00:29

우선 옵저버 패턴(Observer pattern)이란 무엇인가? 에 대해서 생각해보면, 흔히들 말하는 모니터링개념이라고 생각하면 좋다. 


스타크래프트에서도 옵저버는 감시하는 용으로 쓰이게 되는데, 이 패턴은 그러한 개념에서 이름이 붙여지지 않았을까 싶다. 


[그림출처]http://blog.naver.com/hoi5man?Redirect=Log&logNo=60147956284



예를들어 설명해보면 보안쪽 방화벽 장비가 시스템에 해킹시도가 있는지 없는지 감시하고 있다고 하자, 그리고 그 변화를 다른 객체에서 감지하고 싶다.  이럴경우 물론 Thread 나 Fork(유닉스환경)을 사용해서 그 데이터를 실시간으로 검사 주는 것도 방법일 것이다.


하지만 이 모니터링된 자료를 또다른 객체에서 쓰고싶다면? 그리고 또다른 객체에서 쓰고싶다면? 한 프로그램에서 관리받지 못하는 Thread 숫자는 각 프로그램마다 따로따로 돌아가고 이는 자원(resource)의 낭비가 될 수 있다. 


혹은 수많은 메소드들을 따로따로 호출해 줌으로써 코드가 번잡해지거나. 어떤 옵저버를 쉽게 추가하거나 삭제할 수 없을 것이다. 


옵저버 패턴을 이러한 문제를 해결하기 위하여 옵저버를 한데 모아 관리하고 그 옵저버들에게 변화가 일어남과 동시에 메시지를 전달하는 효과를 효율적으로 도와준다. 


옵저버 패턴을 구현하는 방법에는 여러가지가 있지만 대부분 주제(Subject) 인터페이스와 업저버(Observer)인터페이스가 들어있는 클래스 디자인을 바탕으로 한다.


흠... 위에 그림은 해드퍼스트 자료를 기반으로 좀더 보기 편하게 그려 본 것이다. 

(그리는데 고생했는데 너무 작지 않은가 걱정이다.ㅠㅠ..)


옵서버 패턴에 대해서 간단한 개요를 보면, 값이 자주 변화하는 클래스에서 변화가 이러날 때 변화를 출력하거나 그 변화를 이용해야 할 메소드를 호출 시키는 것이다. 


혹시 안드로이드 개발을 해보신 분이라면 안드로이드에 broadCast 의 특정 action 을 주어 특정 앱들만 받게 되는 형태와 매우 흡사하다. 


처음 옵저버들.(데이터변화를 감지해야할 대상)들은 registerObserver를 통하여 자신을 옵저버에 등록한다. 이때 자기 자신을 업데이트 시킬수 있는 Update() 메소드를 반드시 가지고 있어야 한다.


우선 MainClass 의 맨아래쪽에 있는 setMeasurrenments 클래스를 통해 데이터가 들어온다.

 (이 변화된 데이터는 특정 입력, 혹은 쓰레드를 통한 감시된 값들이 될 것이다.) 


그러면 자신의 변수들을 변형시키고 measurementsChanged() 함수를 실행시켜 NotifyObservers()를 호출하여 모든 옵저버들의 update 메소드를 실행시키는 간단한 구조이다. 





자바에는 이미 Observable 이라는 클래스가 존재하여 좀더 편하게 옵저버를 구성할 수 있도록 해놓았다. 

(Import java.util.Observable 과 import java.util.Observer 를 불러와주면된다 이후 이를 상속받아 사용한다. )

이 클래스를 상속받아 사용하면  옵저버들을 관리할 List 자료구조가 필요 없게 된다. (유용하다!) 

또한 for 문을  통하여 옵저버들에게 일일이 뿌려주는 구조를 취하지 않는다.



옵저버 입장에서는 Observer 인터페이스를 implement 시켜 Observable 이라는 클래스에 addObserver를 통해 넣어주면된다.


하지만 이렇게 자바를 기반으로 하는 Observable 패턴을 사용하면 안좋은점 2가지가 있다.

우선 인터페이스로 구성된것이 아니라 클래스로 구현된 것이기 때문에 자신의 프로그램에 맞게 재구성 할수 없다는 점이다. 

그리고 두번째는 클래스화이기 때문에 이미 다른것을 상속받은 상태에서는 또다시 상속받을수 없어 코드의 재사용성에 문제가 될 수 있다. 



==========================================================================================================

사실 필자는 처음 Observer Pattern 으로 인해서 Thread를 사용하지 않고 어떠한 패턴을 감시할 수 있을 줄 알았다. 

마치 WPF의 바인딩처럼 어떠한 변화가 update() 같은 메소드를 가지지 않고도 변화를 인식할 수 있는 패턴이라고 생각했다.  하지만 현실은 감시하는 부분은 어쩔 수 없는 부분인 것 같다. 


다만 변화를 감시하는 곳에서 MainClass 의 메소드중 하나를 실행시킬수 있다면, 그걸 필요로 하는 옵저버들에게 전파시켜주는 역할만을 담당 하는 것이다. 


옵저버 패턴이란 이런 것이다. 


=========================================================================================================



 




Posted by k1rha
2012.04.29 11:48

최근 OOP 를 공부함에 따라 UML 그리는 법부터 다시 공부를 하기 시작했다. 

필자가 개인적으로 OOP 코딩을 잘 못하는 관계로 이번 문서는 100% 신뢰를 보장하지 않는다 -_-.. 개인 공부 목적용일뿐..


아래 자료는 홍익대학교 컴퓨터 정보통신공학  OOP 수업자료 관련한 PDF 파일에서 발최한 그림이다. 




클래스 다이어그램을 그리기전 클래스를 규명해줘야 한다. 


맨위에는 클래스명이 들어가고, 그 아래 칸은 각각의 속성과 타입, 그아래는 연산자가 들어가게 된다. 


각각 메소드나 변수면 앞에붙는 문자의 의미는 다음과 같다.


+는 public 로써 모든 클래스에서 접근 가능하다.

-는 private 로써 상속받은 클래스간에만 접근이 가능하다.

#은 protected 로써 자기 자신에게밖에 접근 할 수 없다. 




다이어그램에서의 상속관계는 다음과 같이 표현한다. 


추상클래스같은 경우 MyDerivedClass 에서 상속받아 그 함수를 재정의해야 하므로 연관관계 세모 모양은 위로 향하게 된다.


  이 관계가 한국인들에게는 좀 헤깔릴 수 있는 관계이만 필자만의 노하우를 말하면 삼각형의 방향을 > < 의 부등식으로 보면 좀더 이해하기가 좋다.


예를들어


MyDerivedClass -> MyAbstractClass 라고 생각을 하면 myDerivedClass 는 MyAbstractclass 를 사용하기에 더 큰 개념이다. 이러한 경우 그대로  MyDerivedClass - ▷  MyAbstractClass 라고 표현해 주면 된다. 


부모자식 관계는 별개의 방식으로 생각하여 여러개의 클래스가 extends 로 상속 받을수 있으므로, 여러 자식은 한 부모를 가져야 한다. 라는 개념으로 보면 MyDerivedClass  가 자식이되고 MyAbstractClass 가 부모가 된다.





이번엔 구현(implement)부를 보면 interface는 객체를 상속받는 것이 아니지만 type과 이름만으로 선언된 것을 하위 클래스에게 전하여 규약을 만든다.

때문에 extends 보다 조금더 느슨한 느낌이라고 보면 되기에 점선으로 표시한다. 




다음은 aggregation(집합관계) 과 composition(구성관계) 이다. 


우선 위에 그림에도 나와 있지만 집합관계는 투명한 다이아몬드 모양으로 표시하고 구성관계는 검은색 다이아 몬드로 사용 된다. 

이 두가지 차이가 애매하다. 특히나 번역을 빌리면 더욱 난감해지는데 개발자들은 코드로 대화한다고 하지 않던가! 코드를 보면 보다 간결하다. 


우선 집합관계(aggregation)은 자식 클래스가 부모클래스와 독립적으로 작용한다.

구성관계(composition)은 자식클래스가 부모클래스에 종속된다. 



 main(){

    Greet g = new Greet(new ArrayList<String>());

    Greet gt = new Greet();

}


public Greet(List l){

    this.l = l;                     //집합 관계

}


public Greet(){

    this.l = new Greet();     //구성관계

}


따라서 부모 클래스가 제거되었을 때 aggregation의 자식 클래스는 살아남는다.  하지만, composition의 자식 클래스는 제거된다.


http://sonsooresoon.tistory.com/18 의 글을 빌어 한번 다시 설명하면 ,


역사수업 을 듣는 학생들이 있다고 가정하자. 그럼 역사 수업안에는 학생들이 있지만 학생들이 없다고 역사 수업이 없는 것은 아니다. 이러한 것을 집합 관계라고 한다. 


하지만 자동차를 속 엔진을 비교해 보면 자동차 엔진이 없으면 자동차는 굴러 가지를 않는다. 

이를 구성 관계라고 한다. 


외우기 쉬운 노하우로는 차를 구성하는 부품은 구성관계이고 그외의 추가적인 옵션들은 부속품이므로 집합 관계가 된다. 



그 다음 각 다이어그램간 연관 관계에 대해서 보겠다.



위 그림에서는 고용주와 피고용인을 대상으로 보았다.

분명 고용주는 소수이다. 그리고 피 고용인은 다수이다.  각 다이어그램간 숫자의 해석은 다음과 같다.


1 ..3   : 1명으로 시작해서...... 3명까지는 될껄? 

1 ..n , 1 ..*  : 한명으로 시작해서..... 많이 많이 될껄?

*      *   : 그냥 많이 많이 될껄?


이런 느낌이다. 


마지막으로 예시를 통하여 한번 복습해보자. 


고객 메일 어플리케이션을 보면 한명의 소비자는 메일 어플리케이션을 가져야 한다. 하지만 메일 계정이 반드시 고객이 구성성분은 아니므로 집합 관계이다. 고로 투명한 다이아 몬드로 표시해 준다. 


DelinquentCustomer 나 MoutaionCustomer 나 Regular Customer 세 부류의 고객들은 전부다. 각자 타입에 맞는 어플리 케이션을 사용 할수 있어야 한다.  하지만 이는 implement 로 interface만을 제공해 주겠다고 한다. 

각 고객들은 customer 를 상속받아 사용해야 하므로 화살표 방향은 customer 족으로 향하게 되는 것이다. 


이처럼 상속받는 것이 작은 개념, 상속 하는 것이 큰 개념으로 시작되면  UML 그리기는 이해하기가 편하다. 




Posted by k1rha