2016년 12월 5일 월요일

멀티 스레딩 첫번째

멀티 스레딩?
  • 한 프로세스를 여러 수행단위(스레드)로 나눠 처리하는 것을 말함
장점
  • 사용자에 대한 응답성이 향상됨
  • 자원을 공유하고 코드 공유의 이점이 있음
  • 자신이 속한 프로세스의 자원들을 공유하기 때문에 경제적임
  • 멀티 프로세서인 경우에 각 스레드가 병렬로 수행할 수 있음
단점
  • 멀티 스레드는 캐시나 TLB(변환 색인 버터)와 같은 하드웨어 리소스를 공유할 때 서로 간섭할 수 있음
  • 하나의 스레드만 실행 중인 경우 실행 시간이 개선되지 보단 오히려 지연될 수 있음
  • 멀티 스레드의 수행이 예측 불가함
  • 실행 순서가 보장되지 않음
  • 테스트 및 디버깅이 어려움
프로그래밍시 주의할 점
  • 컨텍스트 스위칭에 상당한 비용이 소모되기 때문에 너무 많은 스레드는 성능이 더 떨어짐
참고
  • https://ko.wikipedia.org/wiki/%EB%A9%80%ED%8B%B0%EC%8A%A4%EB%A0%88%EB%94%A9
  • http://codedragon.tistory.com/3525

2016년 11월 25일 금요일

Load Balancing 설명

Load Balancing : 웹 어플리케이션의 부하를 분산하는 방식임
  • Server Side Load Balancing
    • Switch(L4, L7)를 사용함
    • HA proxy - Open Source Software Loadbalancer임
    • 문제점
      • Switch가 처리할 수 있는 요청수에 한계가 있음
      • Switch장비를 설치하거나 설정이 어렵고 비싼 장비임 (HA proxy 역시 서버가 필요함)
      • Switch에 장애가 생기면, 접속 문제가 발생함 (이중화하여 Active – Standby로 동작하도록 세팅함)
그림1) Server Side Load Balancing
  • Client Side Load Balancing
    • Server Side Load Balancing의 문제점을 해결하고자 나옴 개념임
    • Switch를 거치지 않고 바로 서버로 요청하는 방식임
    • 즉, Switch에서 하는 분산 역할을 클라이언트 소프트웨어에서 처리하자는 것임
    • 자바에선 Ribbon을 이용함
      • 각 서버의 host정보를 일일이 설정이 필요함
      • Eureka를 함께 사용하면 따로 설정을 하지 않아도 됨
그림2) Client Side Load Balancing
참고
  • http://blog.leekyoungil.com/?p=259

2016년 11월 12일 토요일

Docker 명령어 모음

Stop all containers
 $ docker kill $(docker ps -q)

Remove all containers
 $ docker rm $(docker ps -a -q)

Delete all 'untagged/dangling' (<none>) images
 $ docker rmi $(docker images -q -f dangling=true)

Remove all docker images
 $ docker rmi $(docker images -q)

Remove all docker volumes
 $ docker volume ls -qf dangling=true | xargs -r docker volume rm

Docker 소개

도커?
Docker는 컨테이너 플랫폼이다.

컨테이너?
컨테이너는 서버 동작하기 위해 필요한 코드, 런타임, 시스템 툴, 시스템 라이브러리들을 포함하는 소프트웨어의 부분이다.

가상머신과 도커 비교
가상머신는 어플리케이션, 바이너리, 라이브러리, 게스트 OS를 포함하고 있다.
도커는 어플리케이션, 바이너리,라이브러리는 포함하고 커널을 서로 공유한다. 
즉, 도커를 사용함으로써 게스트OS 동작하는데 필요한 자원을 절감할 수 있따.

참고
https://www.docker.com/what-docker

2016년 10월 23일 일요일

Interpreter Pattern (해석자 패턴)

의도
  • 사용자가 표현하기 쉬운 표현을 사용하게 하고 이를 해석하는 개체를 통해 약속된 알고리즘을 수행하는 패턴
이럴 때 사용하자.
  • 해석이 필요한 언어가 존재하거나 추상 구문 트리로서 그 언어의 문장을 표현하고자 할 때
장점은?
  • 문법의 변경과 확장이 쉬움
  • 문법의 구현이 용이
  • 표현식을 해석하는 새로운 방법을 추가 할 수 있음
단점은?
  • 복잡한 문법은 관리하기 어려움
코드
Context 클래스
class Context
{
public:
   Context(string str) : m_str(str) {};
   const char* GetStr()  { return m_str.c_str(); };
private:
   string m_str;
};

AbstractExpression 클래스
class AbstractExpression
{
public:
   virtual void Interpret(Context* pContext) = 0;
};

TerminalExpression, NonterminalExpression 클래스
class TerminalExpression : public AbstractExpression
{
public:
   void Interpret(Context* pContext) {
      cout << "TerminalExpression: " << pContext->GetStr() << endl;
   };
};

class NonterminalExpression : public AbstractExpression
{
public:
   void Interpret(Context* pContext) {
      cout << "NonterminalExpression: " << pContext->GetStr() << endl;
   };
};

실행부분
void main()
{
   auto_ptr<Context> pContext(new Context("Context"));

   auto_ptr<AbstractExpression> pTerminal(new TerminalExpression());
   pTerminal->Interpret(pContext.get());

   auto_ptr<AbstractExpression> pNonterminal(new NonterminalExpression());
   pNonterminal->Interpret(pContext.get());
}

UML - class 다이어그램

참고
  • GoF의 디자인 패턴(개정판) 재사용성을 지닌 객체지향 소프트웨어의 핵심요소
  • http://horajjan.blog.me/220330464407
  • http://seungdols.tistory.com/entry/GoF%EC%9D%98-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-%ED%96%89%EB%8F%99-%ED%8C%A8%ED%84%B4
  • http://copynull.tistory.com/147

Facade Pattern (퍼사드 패턴)

의도
  • 인터페이스 집합에 대해 하나의 인터페이스를 제공하는 패턴
이럴 때 사용하자.
  • 복잡한 서브시스템에 대한 단순한 인터페이스 제공이 필요할 때
  • 추상 개념에 대한 구현 클래스와 사용자 사이에 너무 많은 종속성이 존재할 때
  • 서브시스템을 계층화시킬 때
장점은?
  • 클라이언트와 서브 시스템의 연결을 느슨하게 만듦
  • 서브시스템에 접근하는 인터페이스를 제공
  • 단순한 인터페이스로 복잡한 서브시스템을 감쌈
단점은?
  • 다른 구성요소에 대한 메소드 호출을 처리하기 위해 "래퍼"클래스를 많이 만들어야 할 수 있음
  • 시스템이 더 복잡해지고, 개발시간도 늘어나면서 성능의 저하도 있을 수 있음
코드
CExec 클래스
class CExec
{
public:
   CExec(string str) { m_str = str; };
   void Print() { cout << m_str.c_str() << endl; }
private:
   string m_str;
};

CSubClassOne, CSubClassTwoCSubClassThree 클래스
class CSubClassOne
{
public:
   void Exec() {
      auto_ptr<CExec> pExec(new CExec("Sub Class One"));
      pExec->Print();
   };
};

class CSubClassTwo
{
public:
   void Exec() {
      auto_ptr<CExec> pExec(new CExec("Sub Class Two"));
      pExec->Print();
   };
};

class CSubClassThree
{
public:
   void Exec() {
      auto_ptr<CExec> pExec(new CExec("Sub Class Three"));
      pExec->Print();
   };
};

CFacade 클래스
class CFacade
{
public:
   CFacade() {
      m_pSubClassOne = new CSubClassOne();
      m_pSubClassTwo = new CSubClassTwo();
      m_pSubClassThree = new CSubClassThree();
   };

   ~CFacade() {
      delete m_pSubClassOne;
      delete m_pSubClassTwo;
      delete m_pSubClassThree;
   };

   
   void ExecOne() {
      m_pSubClassOne->Exec();
      m_pSubClassTwo->Exec();
   };

   void ExecTwo() {
      m_pSubClassThree->Exec();
   }

private:
   CSubClassOne* m_pSubClassOne;
   CSubClassTwo* m_pSubClassTwo;
   CSubClassThree* m_pSubClassThree;
};

실행부분
void main()
{
   auto_ptr<CFacade> pFacade(new CFacade());
   pFacade->ExecOne();
   pFacade->ExecTwo();
}

UML - class 다이어그램

참고
  • GoF의 디자인 패턴(개정판) 재사용성을 지닌 객체지향 소프트웨어의 핵심요소
  • http://wooriworld2006.tistory.com/336
  • http://blog.naver.com/ruly2001/70072957308

2016년 10월 21일 금요일

Public, Protected, Private 차이 설명

  • 접근 제어자
구분제어자설명
접근권한public모든 클래스에서 접근이 가능함
protected동일 패키지에 속하는 클래스와 하위 클래스 관계의 클래스에 의해 접근이 가능함
private클래스 내에서만 접근이 가능함

  • 접근 권한
종류클래스하위 클래스동일 클래스모든 클래스
(default)OXOX
publicOOOO
protectedOOOX
privateOXXX
  • 출처
    • http://hyeonstorage.tistory.com/176

2016년 9월 12일 월요일

Spring Security ( PasswordEncoder )

PasswordEncoder 인터페이스 설명
  • org.springframework.security.authentication.encoding.PasswordEncoder
    •  메소드
      • String encodePassword(String rawPass, Object salt)
      • boolean isPasswordValid(String encPass, String rawPass, Object salt)
    • Spring Security 3.1 이후 넘어가면서 deprecated 됨
  • org.springframework.security.crypto.password.PasswordEncoder
    • 메소드
      • String encode(CharSequence rawPass)
      • boolean matches(CharSequence rawPassword, String encodedPassword)
    • 해킹소지가 있는 salt 노출을 방지하기 위해 제거된 듯 보임
    • 기존 인터페이스와 혼동하지 않기 위해 메소드명도 바뀐 듯보임

org.springframework.security.crypto.password.PasswordEncoder 설명
  • org.springframework.security.crypto.bcrypt.BCrytPasswordEncoder
    • bcryto 해시 알고르즘을 이용한 암호화
    • 신규 시스템이면 권장
  • org.springframework.security.crypto.password.NoOpPasswordEncoder
    • 암호화하지 않는 클래스
    • 테스트 용도로만 사용하길 바람
  • org.springframework.security.crypto.password.StandardPasswordEncoder 
    • sha해시 알고르즘을 이용한 암호화 
    • 기존 sha를 사용하고 있었다면 이것을 사용하길 바람
참고
  • http://zgundam.tistory.com/54

2016년 9월 7일 수요일

Spring Security OAuth2 ( TokenStore 설명 )

  • InMemoryTokenStore : 메모리에 저장하는 방식
    • 단일 서버에 사용하기 좋음
    • Low traffic
    • 실패시 hot swap되지 않음
    • 개발시 사용하시 좋음
  • JdbcTokenStore : DB에 저장하는 방식
    • 관계형 DB에 토큰 을 저장
    • 서버확장시 InMemoryTokenStore보다 좋음
  • JwtTokenStore : 토큰에 JSON정보를 인코딩해서 이용하는 방식
    • 토큰을 back end에 저장하지 않음
    • 단점은 access_token 파기가 어려움, 정보가 많으면 토큰길이가 길어짐

2016년 9월 2일 금요일

홍콩&마카오 여행 (2016년8월25일-2016년8월29일)


여행기간(2016.08.25 ~ 2016.08.29) 여행비용(총 비용: 1,000,140원)
  • 해외여행보험자: 14,890원
  • 항공비 (인천~홍콩, 홍콩~인천): 270,000원
  • 환전: 453,370원 (HK$ 3100)
  • 숙박비: 51,523원(Rainbow Lodge 도미토리  - 1박), 84,528원(IBIS Hotel - 1박), 101,142원(에어비엔비 개인실 - 1박), 286,554원(Venetian Hotel - 1박) ==>> 261,880원 / 1명
1일차
  • 공항
  • 유심 80
  • 옥스퍼드 150
  • 버스이동 A35 (15)
  • 시티게이트 아침 24.5
  • 통총 케이블240
  • 불상 입장료 38
  • 버스이동 DB01R (10)
  • 디스커버리배이페리 (40)
  • 옥스퍼드 100 충전
  • 지하철 (9.7)
2일차
  • 아침 58
  • 스타벅스 44
  • 맥주 24
  • 물 9
  • 빅토리아파크 83
  • 엽서 30
  • 맥주 152
  • 물 7.5

3일차
  • 마카오 페리 177
  • 버스 8.5
  • 에그타르트 18
  • 저녁 108
4일차
  • 마카오타워
  • 저녁
5일차 
  • 마카오 페리 153
  • 선물 
  • 점심
  • 간식

2016년 4월 5일 화요일

Thead Safe란?

Thead Safe

  • 멀티 스레드 프로그래밍에서 일반적으로 어떤 함수나 변수, 혹은 객체가 여러 스레드로부터 동시에 접근이 이루어져도 프로그램의 실행에 문제가 없음을 뜻함.
  • 즉, 하나의 함수가 한 스레드로부터 호출되어 실행 중일 때, 다른 스레드가 그 함수를 호출하여 동시에 함께 실행되더라도 각 스레드에서의 함수의 수행 결과가 올바로 나오는 것으로 정의함
참고
  • https://ko.wikipedia.org/wiki/%EC%8A%A4%EB%A0%88%EB%93%9C_%EC%95%88%EC%A0%84

2016년 4월 4일 월요일

Spring Data JPA Appendix1 (CrudRepository, PagingAndSortingRepository, JpaRepository)

각 클래스의 기능
  • CrudRepository : CRUD functions를 지원
  • PagingAndSortingRepository : pagination and sorting records를 지원
  • JpaRepository : JPA related method를 지원 (CrudRepository와 PagingAndSortingRepository의 모든 함수를 갖음)
** CRUD functions만을 지원하고 싶다면, CrudRepository클래스를 사용하면 됨.

참고
  • http://stackoverflow.com/questions/14014086/what-is-difference-between-crudrepository-and-jparepository-interfaces-in-spring

2016년 3월 29일 화요일

Grunt - The JavaScript Task Runner

Grunt는 무엇?
  • Javascript를 사용한 Task Runner
  • 반복적인 작업을 스크립트를 통해서 수행하는 자동화 도구
  • 여러 가지 JS 및 CSS 파일을 합치고 최소화, 배포 폴더로 복사하는 과정들을 스크립트를 작성하여 자동화 시킴
  • Grunt와 Grunt 플러그인들은 npm(Node.js Package Manager)을 통해 설치되고 관리
Grunt의 장점
  • Javascript/Node.js 기반의 빌드 툴. Javascript 및 Node.js는 활발하게 유지 보수되며 성장하고 있서 안정성 및 전망에서 많은 기대를 할 수 있음.
  • Javascript 어플리케이션에서 사용되는 다양한 기능들(jshint, minify, uglify, less)을 안정적인 플러그인으로 제공
  • 작성 및 유지보수가 쉬운 빌드 스크립트를 제공
  • 커뮤니티가 크고 활발
설치
  1. nodejs 설치 ( https://nodejs.org/ )
  2. nodejs관련 환경변수 추가
    • PATH -> "nodejs설치 경로"추가 ( C:\Program Files\nodejs\ )
    • NODE_PATH -> "prefix 값 + \node_modules" 추가 ( C:\Users\...\AppData\Roaming\npm\node_modules )
  3. Grunt설치 ( > npm install -g grunt-cli 실행 )

패키징 전 준비해야 할 파일
  • Gruntfile.js : 설정을 위해 사용되거나 Task들을 정의하고 Grunt플러그인들을 읽어들임
  • package.json : 필요한 Grunt플러그인들을 정의하여 "npm install"시 읽어들여 설치함
참고
  • http://xinics.tistory.com/99

2016년 3월 11일 금요일

메모리 캐시 ( Memcached, Redis )

1. Memcached


분산 메모리 캐싱 시스템.
DB에 저장된 데이터를 메모리에 적재하여 응답속도를 높여 동적 웹 어플리케이션의 성능을 높이기 위한 용도로 사용하기도 함.
데이터를 작은 단위의 key-value형태로 저장.

맴캐시드를 사용하지 않았을 때는 분리되어 있는 메모리에 대해 각 서버에 할당된 캐시 크기만큼만 사용하기에 효율적이지 않음.
맴캐시드를 사용하면, 결합되어 각 서버는 전체 캐시 크기만큼 사용할 수 있음. 즉, 메모리 운용이 효율적이라는 것임.






2. Redis

in-memory data structure store.
데이터베이스, 캐시, 메시지 브로커로 사용할 수 있음.
key-value형태로 저장.
string, hasheds, lists, sets, sorted sets과 같은 데이터 구조를 지원.
Global Cache 방식


* Global Cache방식은 네트워크 트래픽이 발생하기 때문에 Java Heap 영역에서 조회되는 Local Cache가 성능이 낫지만 WAS 인스턴스가 증가하게 되는 경우, Cache에 저장되는 테이터 크기가 커지기 때문에 Redis방식 유리


3. 참고
http://blog.naver.com/windfalcon1/220400294140
http://ojava.tistory.com/70

2016년 1월 24일 일요일

State Pattern (상태 패턴)

의도
  • 객체의 상태에 따라 스스로 행동을 변경할 수 있게 하는 패턴
이럴 때 사용하자.
  • 객체의 행동이 상태에 따라 달라지며, 런타임 시에 행동이 바뀌어야 할 때
  • 다중 분기 조건 처리가 너무 많을 때
장점은?
  • 상태에 따른 행동을 국소화하며, 서로 다른 상태에 대한 행동을 별도의 객체로 관리
  • 상태 전이를 명확하게 만듦
  • 상태 객체는 공유될 수 있음
코드
State 클래스
class State
{
public:
   virtual void Handle() = 0;
};

ConcreteStateA, ConcreteStateB 클래스
class ConcreteStateA : public State
{
public:
   void Handle() {
      cout << "ConcreteStateA" << endl;
   };
};

class ConcreteStateB : public State
{
public:
   void Handle() {
      cout << "ConcreteStateB" << endl;
   };
};

Context 클래스
class Context
{
public:
   Context(State* pState)
      : m_pState(pState) {};
   ~Context() {
      m_pState = NULL;
   };

   void SetState(State* pState) {
      m_pState = pState;
   };
   void Request() {
      m_pState->Handle();
   };
private:
   State* m_pState;
};

실행부분
void main()
{
   State* pConcreteStateA = new ConcreteStateA();
   State* pConcreteStateB = new ConcreteStateB();

   Context* pContext = new Context(pConcreteStateA);
   pContext->Request();

   pContext->SetState(pConcreteStateB);
   pContext->Request();

   delete pConcreteStateA;
   delete pConcreteStateB;
   delete pContext;
}
UML - class 다이어그램
참고
  • GoF의 디자인 패턴(개정판) 재사용성을 지닌 객체지향 소프트웨어의 핵심요소
  • http://joochang.tistory.com/64
  • http://blog.naver.com/gp_jhkim/220519499252
  • http://hunnywind.tistory.com/105

2016년 1월 18일 월요일

겨울 하늘 아래 구름

Strategy Pattern (전략 패턴)

의도
  • 동일 계열의 알고리즘군을 정의하고, 각각의 알고리즘을 캡슐화하며, 이들을 상호 교환이 가능하도록 만드는 패턴
이럴 때 사용하자.
  • 행동이 조금씩 다를 뿐 관련된 많은 클래스들일 존재할 때
  • 알고리즘의 변형이 필요할 때
  • 사용자가 몰라야 하는 데이터를 사용하는 알고리즘이 있을 때
  • 하나의 클래스가 많은 행동을 정의하고, 이런 행동들이 그 클래스의 연산 안에서 복잡한 다중 조건문의 모습을 취할 때
장점은?
  • 동일 계열의 관련 알고리즘군이 생김
  • 서브클래싱을 사용하지 않는 대안임
  • 조건문을 없앨 수 있음
  • 구현의 선택이 가능함
단점은?
  • 서로 다른 전략을 알아야 함
  • Strategy 객체와 Context 객체 사이에 의사소통 오버헤드가 있음
  • 객체 수가 증가함
코드
Strategy 클래스
class Strategy
{
public:
   virtual void Algorithm() = 0;
};

ConcreteStrategyA, ConcreteStrategyB 클래스
class ConcreteStrategyA : public Strategy
{
public:
   void Algorithm() {
      cout << "ConcreteStrategyA" << endl;
   };
};
class ConcreteStrategyB : public Strategy
{
public:
   void Algorithm() {
      cout << "ConcreteStrategyB" << endl;
   };
};

Context 클래스
class Context
{
public:
   Context() {};
   void SetStrategy(Strategy* pStrategy) {
      m_pStrategy = pStrategy;
   };
   void Do() {
      m_pStrategy->Algorithm();
   };
private:
   Strategy* m_pStrategy;
};

실행 부분
void main()
{
   Context* pContext = new Context();

   Strategy* pStrategyA = new ConcreteStrategyA();
   pContext->SetStrategy(pStrategyA);
   pContext->Do();

   Strategy* pStrategyB = new ConcreteStrategyB();
   pContext->SetStrategy(pStrategyB);
   pContext->Do();
   
   delete pStrategyA;
   delete pStrategyB;
   delete pContext;
}

UML - class 다이어그램
참고
  • GoF의 디자인 패턴(개정판) 재사용성을 지닌 객체지향 소프트웨어의 핵심요소

2016년 1월 9일 토요일

Template Method Pattern (템플릿 메서드 패턴)

의도
  • 알고리즘의 뼈대만을 정의하고 각 단계에서 수행할 구체적 처리는 서브클래스 쪽에서 하는 패턴
이럴 때 사용하자.
  • 어떤 한 알고리즘을 이루는 부분 중 변하지 않는 부분을 한번 정의해 놓고 다양해질 수 있는 부분은 서브 클래스에서 정의할 수 있도록 남겨두고자 할때
  • 서브클래스 사이의 공통적인 행동을 추출하여 하나의 공통 클래스에 몰아둠으로써 코드 중복을 피하고 싶을때
코드
AbstractClass클래스
class AbstractClass
{
public:
   virtual void Operation1() = 0;
   virtual void Operation2() = 0;

   /* template method */
   void Operation3() {
      cout << "Operation3" << endl;
   };
};

ConcreteClass클래스
class ConcreteClass : public AbstractClass
{
public:
   void Operation1() {
      cout << "Operation1" << endl;
   };
   void Operation2() {
      cout << "Operation2" << endl;
   };
};

실행부분
void main()
{
   AbstractClass* pClass = new ConcreteClass();

   pClass->Operation1();
   pClass->Operation2();
   pClass->Operation3();

   delete pClass;
}

UML - class 다이어그램
참고
  • GoF의 디자인 패턴(개정판) 재사용성을 지닌 객체지향 소프트웨어의 핵심요소
  • http://psh85a.tistory.com/57

2016년 1월 8일 금요일

Visitor Pattern (방문자 패턴)

의도
  • 객체 구조를 이루는 원소에 대해 수행할 연산을 표현하는 패턴
이럴 때 사용하자.
  • 객체 구조가 다른 인터페이스를 가진 클래스들을 포함하고 있어서 구체적 클래스에 따라 이들 오퍼레이션을 수행하고자 할 때
  • 구별되고 관련되지 않은 많은 오퍼레이션이 객체에 수핼될 필요가 있지만, 오퍼레이션으로 인해 클래스들을 복잡하게 하고 싶지 않을 때
장점은?
  • 새로운 연산을 쉽게 추가 가능
  • 연산자들을 한 군데로 모으고 관련되지 않은 연산을 떼어낼 수 있음
단점은?
  • 데이터 은닉을 깰 수 있음
코드
Element, Visitor 클래스
class Element
{
public:
   virtual void accept(class Visitor& rVisitor) = 0;
};

class Visitor
{
public:
   virtual void visit(class This* pElement) = 0;
   virtual void visit(class That* pElement) = 0;
   virtual void visit(class TheOther* pElement) = 0;
};

This, That, TheOther 클래스
class This : public Element
{
public:
   void accept(Visitor& rVisitor) {
      rVisitor.visit(this);
   };
   string thiss() {
      return "This";
   };
};

class That : public Element
{
public:
   void accept(Visitor& rVisitor) {
      rVisitor.visit(this);
   };
   string that() {
      return "That";
   };
};

class TheOther : public Element
{
public:
   void accept(Visitor& rVisitor) {
      rVisitor.visit(this);
   };
   string theOther() {
      return "TheOther";
   };
};

UpVisitor, DownVisitor 클래스
class UpVisitor : public Visitor
{
   void visit(This* pElement) {
      cout << "do Up on" + pElement->thiss() << endl;
   };
   void visit(That* pElement) {
      cout << "do Up on" + pElement->that() << endl;
   };
   void visit(TheOther* pElement) {
      cout << "do Up on" + pElement->theOther() << endl;
   };
};

class DownVisitor : public Visitor
{
   void visit(This* pElement) {
      cout << "do Down on" + pElement->thiss() << endl;
   };
   void visit(That* pElement) {
      cout << "do Down on" + pElement->that() << endl;
   };
   void visit(TheOther* pElement) {
      cout << "do Down on" + pElement->theOther() << endl;
   };
};

실행부분
void main()
{
   Element* pArrayElement[] = { new This(), new That(), new TheOther() };
   UpVisitor upVisitor;
   DownVisitor downVisitor;

   for each (Element* pElement in pArrayElement) {
      pElement->accept(upVisitor);
   }
   for each (Element* pElement in pArrayElement) {
      pElement->accept(downVisitor);
   }

   for each (Element* pElement in pArrayElement) {
      delete pElement;
   }
}

UML - class 다이어그램
참고
  • GoF의 디자인 패턴(개정판) 재사용성을 지닌 객체지향 소프트웨어의 핵심요소
  • http://pusna25.blog.me/100197705146
  • https://ko.wikipedia.org/wiki/%EB%B9%84%EC%A7%80%ED%84%B0_%ED%8C%A8%ED%84%B4

2016년 1월 6일 수요일

Spring에서 Exception 처리 ( @ExceptionHandler, @ControllerAdvice )

@ExceptionHandler
같은 컨트롤러에 @ExceptionHandler 어노테이션을 적용한 메서드가 존재하면, 스프링은 그 메서드가 익셉션을 처리하도록 한다.
따라서, 컨트롤러에 발생한 익셉션을 직접 처리하고 싶다면 @ExceptionHandler 어노테이션을 적용한 메서드를구현해주면 된다.

@Controller
public class MemberDetailController {
   ...
   @RequestMapping("/member/detail/{id}")
   public String detail(@PathVariable("id") Long memId, Model model) {
      Member member = memberDao.selectById(memId);
      if (member == null) {
         throw new MemberNotFoundException();
      }
      model.addAttribute("member", member);
      return "member/memberDetail";
   }

   @ExceptionHandler(TypeMismatchException.class)
   public String handleTypeMismatchException(TypeMismatchException ex) {
      // ex 사용해서 로그 남기는 등 작업
      return "member/invalidId";
   }

   @ExceptionHandler(MemberNotFoundException.class)
   public String handleNotFoundException() throws IOException {
      return "member/noMember";
   }
}

이렇게하면 컨트롤러에서 에러가 날 경우  익셉션을 전달하는 것이 아니라, 컨트롤러 내부에서 직접 에러를 처리하게 된다.

@ControllerAdvice
@ControllerAdivice는 하나의 컨트롤러가 아닌 여러컨트롤러에서 하나의 익셉션을 처리할 때 사용된다.

@ControllerAdivce("chap13.spring")
public class CommonExceptionHandler {
   @ExceptionHandler(RuntimeException.class)
   private ModelAndView errorModelAndView(Exception ex) {
      ModelAndView modelAndView = new ModelAndView();
      modelAndView.setViewName("/error_common");
      modelAndView.addObject("exception", ex );
      return modelAndView;
   }
}

이렇게 M&V 를 사용하면   뷰와,  모델객체를 같이 보낼 수 있다.

참고
  • http://blog.naver.com/xcv1524/220497274201

2016년 1월 1일 금요일

Decorator Pattern (작성자 패턴)

의도
  • 클래스에게 동적인 기능이나 임무를 추가하는 패턴
이럴 때 사용하자.
  • 기존 객체를 유연성 있게 확장할 때 
장점은?
  • 객체의 추가적인 요건을 동적으로 추가
  • 서브클래스 통해 기능을 유연하게 확장할 수 있는 방법을 제공
단점은?
  • 서브 클래스가 많아지게 되면 관리하기에 복잡할 수 있음 (예] 자바의 I/O 클래스 구성체계)​
  • 상속을 통해 확장할 수 있지만, 디자인 유연성 면에서 좋지 않음
코드
Coffee 클래스
class Coffee
{
public:
   virtual int GetCost() = 0;
   virtual string GetIngredients() = 0;
};

DefaultCoffee 클래스
class DefaultCoffee : public Coffee
{
public:
   virtual int GetCost() {
      return 500;
   };
   virtual string GetIngredients() {
      return "Coffee";
   };
};

CoffeeDecorator 클래스
class CoffeeDecorator : public Coffee
{
public:
   CoffeeDecorator(Coffee* pCoffee) {
      m_pCoffee = pCoffee;
   };
protected:
   Coffee* m_pCoffee;
};

Milk, WhippingCream 클래스
class Milk :public CoffeeDecorator
{
public:
   Milk(Coffee* pCoffee)
      : CoffeeDecorator(pCoffee) {};
   virtual int GetCost() {
      return m_pCoffee->GetCost() + 200;
   };
   virtual string GetIngredients() {
      return m_pCoffee->GetIngredients() + ", Milk";
   };
};

class WhippingCream :public CoffeeDecorator
{
public:
   WhippingCream(Coffee* pCoffee)
      : CoffeeDecorator(pCoffee) {};
   virtual int GetCost() {
      return m_pCoffee->GetCost() + 100;
   };
   virtual string GetIngredients() {
      return m_pCoffee->GetIngredients() + ", Whipping Cream";
   };
};

실행부분
void main()
{
   auto_ptr<Coffee> pCoffee(new DefaultCoffee());
   cout << "-- DefaultCoffee -- " << endl;
   cout << "Cost: " << pCoffee->GetCost() << endl;
   cout << "Ingredients: " << pCoffee->GetIngredients().c_str() << endl;

   auto_ptr<Coffee> pCoffeeDec1(new Milk(pCoffee.get()));
   cout << "-- DefaultCoffee + Milk -- " << endl;
   cout << "Cost: " << pCoffeeDec1->GetCost() << endl;
   cout << "Ingredients: " << pCoffeeDec1->GetIngredients().c_str() << endl;

   auto_ptr<Coffee> pCoffeeDec2(new WhippingCream(pCoffeeDec1.get()));
   cout << "-- DefaultCoffee + Milk + WhippingCream -- " << endl;
   cout << "Cost: " << pCoffeeDec2->GetCost() << endl;
   cout << "Ingredients: " << pCoffeeDec2->GetIngredients().c_str() << endl;
}

UML - class 다이어그램
참고
  • GoF의 디자인 패턴(개정판) 재사용성을 지닌 객체지향 소프트웨어의 핵심요소
  • http://h_proms.blog.me/220383634118