반응형

 

 

 
 
 
 

 

mediator 와 observer 의 차이는

 

observer 는 중심이 되는것이 밖에 있는 것들 즉 중계자가 중심이 되는 것이 아니고

 

중계자가 아닌 밖의 옵저버들이 대한 변경 사항을 subject(중계자) 에게 알리면 변경사항을 나머지 옵저버들에게 알려주는 것이

 

Observer pattern


 

 

A 의 오브젝트 변경사항을 나머지에도 적용 시키는 패턴

 

중간에 Subject 가 이를 반영한다

 

 

 

원래 처음 주어진 환경이 이런 환경

 

 

A(observer object) 에서 변경된 부분을  Subject  에게 전달해주고

 

Subject 는 A 가 업데이트 됐다면 Subject 가 A 에서 읽어와 나머지 오브젝트들(observer objects)에게 변경사항을 알려주는 것

 

 

switch 를 피하기 위해 동일한 인터페이스 사용

 

 

 

 

 

subject 클래스는 내부적으로 observer objects 를 리스트로 관리할뿐 구체적으로 어떤 observer object 들인지는 관여하지 않는다

=> 즉 동일한 인터페이스를 갖는다

 

 

서로 업데이트 하려고 하는 경우 같은 정보로 변경할 경우 subject 에서 정볼르 받아 쌓아놨다가 이전에 바꿨던것과 동일한가를 비교

 

이렇게 알려주려면 알려주기 위한 클래스를 생성 해야 한다

 

 

subject 가다른 observer objects 와 동일한 데이터 일경우 싱글톤으로 만들 수도 있다

 

 

subject 가 여러개가 있고 observer 가 여러개 있을 수 있다

 

 

 

업데이트시 this  를 넘겨줌

 

 


 

 

subject 가 소멸되는 경우 각 observer objects 들은 소멸 하거나 어떤 처리를 해야 함

 

 

 

setstate() 함수 호출의 순서를 조절할 수 있는 것이 themplate method 패턴을 참고

=> subject 에서 값변환 먼저 실행후 notify 실행, 각 옵저버 객체에서도 동일하게 추가 되야 함

 

 

 

-특정 값이 바뀌었을때는 subject 에 클래스를 미리 등록 시켜 놓고 관심 있는 옵저버 클래스에게만 알려 효율 올림

 

 

 

-


 

 

 

오브젝트 N 개 서브젝트 M 개 일때

 

중간에 change manager 를 두고 이 사이를 관리할 수도 있음

 

change manager 를 상속 받는 manager 의 종류를 또 분류하여, 변경사항을 다 통보해주는 매니저로 갈지

 

변경사항이 연관있는 옵저버오브젝트들에게만 알릴지를 정할 수도 있다( 전자의 경우 mediator 와 유사)

 


 

 

한 노드가  subject 와 observer 역할을 둘다 할 수도 있다

 

옵저버가 다른 옵저버와 연결 되는 경우

 

1. 다중상속

2. 다중상속이 힘든 환경이면 subject ,observer 클래스를 따로 구현 하지 않고 하나로 두어 구현

 

 

 

 


 

 

 

 

스트크래프트 미니 맵에서 적은 안보이고 우리만 보이는 상황

 

전체 오브젝트에 대해서 서브젝트가 가지고 있는데

 

Subject 에서 A편, B 편, 관람자들의 리스트를 따로 가지고 있어서

 

연관된 사람들에게만 오브젝트 위치를 보여준다

 

 

반응형

'디자인패턴과방법론 > 디자인패턴' 카테고리의 다른 글

strategy 패턴  (0) 2012.11.02
state 패턴  (0) 2012.11.02
memento 패턴  (0) 2012.11.02
iterator 패턴, 스택제거시 삭제되는 포인터(like 스마트포인터)  (0) 2012.11.02
interpreter 패턴  (0) 2012.11.02
반응형

 

 

 

 

 

 

 

 

상태정보 저장이 목적

 


 

 

undo, redo 같은 기능을 실행 하기 위해선 변경된 정보 , 심할 경우 변경된 상태의 전체 정보를

 

따로 저장 관리하는 클래스를 두는 것을 memento 패턴이라 한다

 

 

일반적으로 필요한 정보만 따로 모아 관리 하는 것을 말한다

 

 

 

 

행동:

저장할 필요 정보를 memento 에 저장했다가 다시 돌리고 싶을때 memento 에서 다시 불러온다

 

또한 해당 객체 상태를 직접 접근하는 것이 어려운 경우 상태 정보를 memento 로 빼놓아

 

클라이언트가 객체의 은닉성을 깨트리지 않고 상태 정보를 알기 위해 memento 로 저근하는 상황에서도 사용 될 수 있다

 

 

이처럼 직접 접근하지 못하게 경계 역할도 할 수 있다

 

 

하지만 원래 memento 에 상태를 저장하는 객체는 memento 객체를 마음대로 다루길 원함으로

 

friend 로 선언해 주는 것도 좋다

 

하지만 다른 것이 접근할때는 private 로 선언하는게 좋다

 

 


 

모든 값을 다 저장해서 가지고 있으면 비효율적이므로 변경된 부분만 관리 한다( 이부분 설계가 관건)

 

 

지나치게 memento 에 다른 클라이언트가 접근해 모두 막 상태를 바꾸는 구조는 좋지 않다

 

 

redo/undo 같은 경우  메모리가 많이 커질 수 있음으로 횟수의 제한을 두는 것이 좋다

 

 

command 패턴과 memento 패턴을 같이 사용하여 명령을 memento 에 저장해 놓으면 효과적이다

 

 

 

 

 

 


 

 

 

 

memento 할(저장할) 단위 설정이 중요

 

단위가너무 작으면 저장된는 것이 많아 질 수 있다

 

 

반응형

'디자인패턴과방법론 > 디자인패턴' 카테고리의 다른 글

state 패턴  (0) 2012.11.02
Observer 패턴  (0) 2012.11.02
iterator 패턴, 스택제거시 삭제되는 포인터(like 스마트포인터)  (0) 2012.11.02
interpreter 패턴  (0) 2012.11.02
command 패턴  (0) 2012.11.02
반응형

 

 

 

 

 

 

 

예를들어 list 의 경우

 

list 내부에 포인터를 두면 멀티플(멀티 쓰레드)로 list 에 접근할때 오류가 생길 수 있는데

 

이것을 객체로 두면 멀티플로 접근이 가능해진다

 

즉 접근 포인터를 객체로 둔것이 iterator 패턴이다

 

 

굳이 필요한 상황 아니면 type<T>::iterator it; 쓰는게 났다

 

 


 

 

 

리스트자체에서 리스트에 대한 이터레이터를 만들때의 구현

( iterator 가 없어질때 List 를 동적 또는 정적 할당 하지 않았음으로 삭제 과정은 필요 없고 new 한 Listiterator 만 삭제 하면 된다

pListiter 으로 함수 안에서 생성된 list 를 다룰 수 있다

 

ListIterator* pListiter = list.createiterator();

 

했을때..

 

       iterater* createiterator(){

            return new ListIterator(this);   // this 는 리스트의 주소

       }

 

 

 

class ListIterator: public Iterator {
  public :
    ListIterator(LinkedList* pList){  this->pList = pList;  }

 

  private :
    LinkedList* pList_;
};

 

반응형

'디자인패턴과방법론 > 디자인패턴' 카테고리의 다른 글

Observer 패턴  (0) 2012.11.02
memento 패턴  (0) 2012.11.02
interpreter 패턴  (0) 2012.11.02
command 패턴  (0) 2012.11.02
chain of responsibility 패턴  (0) 2012.11.02
반응형

 

 

 
 

 

 

 

문법에 대한 패턴, 간단한 연산 등 간단한 스크립트 같은거나 간단한 정규식 그리고 비교적 작은 형태일때

 

속도가 안중요할때 쓰임

 

처리 영역을 나누지 않고 한번에 처리할때

 

 

복잡한 경우에는 다루기 힘들다

 

 

interpreter 패턴은 파싱을 하지 않고 바로 객구조를 만들어 사용

 

interpreter 패턴에 멤버  함수를 정의하는 것이 번거로운 경우 vistor 패턴을 각 연산마다 적용하여

 

추상노드를 순회하도록함으로써 interpreter 패턴의 수행역할을 동일하게 할 수 있다

 

 

 

장점 : 문법에서 클래스 구조를 만들어 내고 만들어진 클래스 구조를 보고 다시 문법을 봐 성립하면 이것이 맞는 구조라 할 수 있음

 

 

 

 XML DTD 문법이 맞는지 체크하라

 

즉 간단한 문법이 있는데 이것을 프로그램으로 읽어 들였을때 맞는 것인지 확인

 

<!Element purchaseOrder (shipTo,BilTo,Item) >

<!Element shipTo (Name,Street,city,state,country,zip) >

<!Element BilTo (Name,Street,city,state,country,zip) >

<!Element Item (ProductNo,quentity, price, ItemName,orderDate) >

<!Element Name (#PCdate) >

 

 

위는 아래와 같다

 

purchaseOrder := shipTo & BilTo & Item +

shipTo := Name & Street .. 이런식

 

 

+ 는 한번이상 나타난다

* 는 0번 이상 나타난다

 

 

purchaseOrder,shipTo  왼쪽에 나타나는개 클래스 

 

 

XML 이 문법을 만드는 것인데 이 문법이 맞는것인지 아닌지를 확인 할때 interpreter 패턴을 사용 할 수 있다

 

 

 


 

클래스 구조적 포인트는

 

연산자이든, 문자열이든 동일한 부모 추상클래스를 두어서 실행시키는 함수를 virtual 로 정의해놓고 이 함수를

 

수행하는 것

 

 

즉 연산자와, 문자를 파싱할때 동일한 부모이니 연산자이든 문자이든 동일한 타입의 부모로 캐스팅 됨을 이용하여

 

보다 간결한 구조로 조사와 순회 할 수 있다는 것

 

반응형
반응형

 

 

 

 

 

command 패턴이란?

 

요청과 이 요청을 처리할 객체를 중계하기 위한 클래스 상속구조를 말한다

 

 

여라가지의 처리할 명령을 'A' 에서 요청할 경우 'A'쪽의 명령들을

 

Abstract Base class 기반으로 구성하여 각 명령에 대해 처리할 관련있는 클래스들끼리 참조 또는 할당하여 하나의 객체로 구성하여

 

map 등으로 명령과 클래스를 같이 갖고 있는 형태로 만들어 놓은후

 

B 쪽에서 이것을 처리할때

 

A 에서 만든 상속구조처럼 묶어 처리하는 패턴

 

오고 가는 것은 map 의 value 가 오고 가지만 이 value 에 대한 명령 처리를

 

B쪽에서는 해당 처리해야 할 서브 클래스에 대한 해당 명렬을 처리할 클래스를 추출해 낼 수 있음으로

 

이 둘의 연결 구조를 보다 각각의 지역적으로 분할된 형태로 처리 할 수 있다

 

 

 

 

2. callback 버튼 실행 명령 함수에 이를 대입할 수 있다

  C 함수는 괜찮은데 , 멤버 함수를 callback 으로 부를 경우 문제가 될 수 있는데 이때 사용 할 수 있다

 

3. redo, undo 에 적용 하기 쉽다

 

  각 명령에 대해서 동일한 인터페이스로 처리 가능

  즉 동일한 데이터 타입으로 명령을 처리 할 수 있고 필요 한 클래스들만 있으면 된다

  => 동일한 데이터만 핸들링 하면 된다

 

 undo/redo 의 순서는 memento 패턴으로 해결 하면 된다

 

 

 

또한 undo/redo 의 객체 상태 저장은 prototype패턴 or 바뀐부분을 저장하는 방법 memento 패턴을 활용(상태 값을 저장해 놓는 형태)

 

 

*undo/redo 는 연산을 했던걸 다시 역으로 하는 것보단, 상태값으로 그때의 상태를 제연하는 것이 좋다

 

 

4. protocal 과 같은 명령에 대한 처리에도 유용하다

 

5. makefunctor( (functor1*), ai, show );   <= 표기 정확하지 않음 대략적으로 표기

같은 것 또한 전역 함수나, 멤버함수를 동일한 형태로써 두개를 수행 할 수 있는 것과 같은 것도 command 패턴의 유형과 개념상 비슷하다고 볼 수 있다


 

 

명령종류의 자체가 많아 지면 command 들의 상위인 command 클래스가 필요한데 이렇게 명령의 종류가 많아지면

 

composite 패턴과 연동하여 한번에 처리 할 수 있게 한다

 

동일한 레벨을 묶고 있는게 composite 이니깐 동일하게 묶고 있는것에 대해 전체를  돌면서 다 실행하는 virtual 함수 실행

 


 

 

 

명령의 종류에 대해 나뉘어지는 형태이므로

 

다른 유사 명령과 교체하여 실행을 다르게 설정 할 수 도 있다


 

또한 복합적인 명령을 수행해야 하는 경우

 

서브 command 클래스를 만들 필요 없이

 

중간에 macrocommand 클래스를 만들어 두어 이 클래스에서 명령을 조합해 실행하는 클래스를 두는 것이 효과적이다

 

 

 


 

 

 

macrocommand 클래스를 활용할 경우 스크립트의 작업형태도 처리 가능하다

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

execute( ) 의 수행함수에서 인자를 줄려면 다 주던지 안주려면 다 안주던지 해야 한다

함수에 인자가 들어가면 인자타입이 다 틀려지고 부르는 쪽도 맞춰 틀려져야 하기 때문에 처리가 복잡해 진다

 

각 명령에 대해 한 클래스들이 명령을 처리할 클래스들을 생성자의 초기 값으로 넘겨주게 된다

이때의 생성자 초기 값은 상관 없음으로 명령을 수행할 execute() 함수만 불러주면 되기 때문

 

 

반응형
반응형

 

 

 
 

 

 

 

 여러 오브젝트가 있을때 현재 자신이 처리할 수 있으면 처리를 하고 끝내지만 현재 자신이 처리하지 못하면

 

다음 오브젝트로 일을 보내 처리하도록 한다

 

흐름적 이점 : switch  구문을 제거 할 수 있다

 

한 프로젝트의 도움말에 대한 사항을 분기문이 아닌 chain of responsibility  패턴으로 처리할 사항을 다음 클래스로 넘기며 처리 할 수 있는데

 

 

A, B ,C ,D, E, .... N 의 클래스가 있을때

 

 A 에서 처리할 수 있는 도움말이면 A 에서 처리 하지만 A 에서 처리 할 수 다음 포인터 주소를 통해 다음 클래스로

 

처리를 넘긴다

 

A                  

success() --------------->B

                                         success()--------------->C

                                                                                 success()---------------->

 

 

DNS 처리 또한 유사하게 처리 될 수 있다

 

단 처리 됐는지 처리 되지 않았는지 처리를 넘긴 다음에는 알지 못한다

즉 정확히 어떤 객체가 처리하는지 모른다

 

 

 


 

 

도움말, 프린트, 응용프로그램 등등에 대한 각 가지 다양한 종류에 대한 처리 사항을 클라이언트가 요청 할 수 있는데

 

그때는 요청의 종류 req->GetRequestofKind() 와 같은 종류를 구분 할 수도 있지만 좀 더 나은 방법은

 

Dynamic_cast 로 현재 넘어온 클래스가 어느 부류에 속하는 클래스인지 다운캐스팅 테스트를 해보아

 

 

Dynamic_cast  가 0 을 리턴하면 현재 상속구조의 클래스가 아님으로 다음 분기문에서 다시 다른 종류에 대한 클래스의 다운 캐스팅을

 

시도해보아 맞을때까지 분기문을 놓는 식으로 처리 한다

 

 


 

 

 

 

패턴을 오히려 너무 많이 남발하면 좋지 않다

 

적시 적소에 쓸 수 있어야 한다 chain of responsibility 패턴 과 쓰일 수 있는데

 

다음 노드로 넘어가야 하느냐 말아야 하느냐가 각 노드마다 공통인 부분이기 때문에 이 부분에 대해서 Template Method 패턴이 쓰일 수 있다

 

다음 으로 넘어가지 않는다고 하면 Template Method 를 지나쳐 다음을 수행 하면 되기 때문..

 

 

 

 

 


 

 

 

Template method 패턴이

 

 

 

반응형
반응형

 

 

 

 

기본 변하지 않는 클래스의 계층 구조에서 변하는 부분의 클래스의 추가, 정의 등이 필요할때

 

기존 구조를 거의 무너트리지 않고 변하는 부분을 만들 수 있는데 그것을 스트레티지 패턴이라 한다

 

 

point 는 포함 관계로 변화되는 클래스를 변하지 안흔 클래스의 부모에 포함 시켜서

 

클래슬르 만들때 원하는 행동의 클래스를 업케스팅해주면 된다

 

 

또한 기존에 돌아 가고 있던 행동을 쉽게 교체 하기 위해서도 많이 쓰인다

 

 


 

 

 

http://tongins.blog.me/80096279721

 

[패턴] Strategy Pattern  


복사http://tongins.blog.me/80096279721
 

 


 




스트레티지 패턴은 런타임 시점에서 알고리즘을 선택할 수 있는 독특한 디자인 패턴입니다.
이 패턴은 객체 지향 언어의 특성인 다형성을 사용한 패턴입니다.
스트레티지 패턴은 어플리케이션이 동작하는 상황에서 해당 기능에 대한 알고리즘을 교체하고자 할때 유용합니다.
이 패턴의 이름이 Strategy라고 불리우는 이유는 전쟁중에 이기기위해 싸우는 수단을 다양하게 바꾸는 상황과 프로그램이 동작하는 중에 알고리즘을 동적으로 교체하는 상황이 비슷하기 때문일 것입니다. 

 

 

스트레티지 패턴은 복잡하거나 어려운 패턴은 아닙니다.

프로그래밍을 하다 보면 if문을 제거하고 싶어질 때가 있습니다.

이때 자연스럽게 스트레티지 패턴을 만들어서 사용하게 될 때가 있습니다.

 

 

 

 

 

 

위 다이어 그램에 대한 C# 소스는 아래와 같습니다.

  1. using System;
  2.  
  3. namespace Pattern.Strategy
  4. {
  5.     class MainApp
  6.     {
  7.         static void Main()
  8.         {
  9.             Context context;
  10.  
  11.             // Three contexts following different strategies
  12.             context = new Context(new ConcreteStrategyA());
  13.             context.ContextInterface();
  14.  
  15.             context = new Context(new ConcreteStrategyB());
  16.             context.ContextInterface();
  17.  
  18.             context = new Context(new ConcreteStrategyC());
  19.             context.ContextInterface();
  20.  
  21.             // Wait for user
  22.             Console.ReadKey();
  23.         }
  24.     }
  25.  
  26.     /// <summary>
  27.     /// The 'Strategy' abstract class
  28.     /// </summary>
  29.     abstract class Strategy
  30.     {
  31.         public abstract void AlgorithmInterface();
  32.     }
  33.  
  34.     /// <summary>
  35.     /// A 'ConcreteStrategy' class
  36.     /// </summary>
  37.     class ConcreteStrategyA : Strategy
  38.     {
  39.         public override void AlgorithmInterface()
  40.         {
  41.             Console.WriteLine(
  42.                 "Called ConcreteStrategyA.AlgorithmInterface()");
  43.         }
  44.     }
  45.  
  46.     /// <summary>
  47.     /// A 'ConcreteStrategy' class
  48.     /// </summary>
  49.     class ConcreteStrategyB : Strategy
  50.     {
  51.         public override void AlgorithmInterface()
  52.         {
  53.             Console.WriteLine(
  54.                 "Called ConcreteStrategyB.AlgorithmInterface()");
  55.         }
  56.     }
  57.  
  58.     /// <summary>
  59.     /// A 'ConcreteStrategy' class
  60.     /// </summary>
  61.     class ConcreteStrategyC : Strategy
  62.     {
  63.         public override void AlgorithmInterface()
  64.         {
  65.             Console.WriteLine(
  66.                 "Called ConcreteStrategyC.AlgorithmInterface()");
  67.         }
  68.     }
  69.  
  70.     /// <summary>
  71.     /// The 'Context' class
  72.     /// </summary>
  73.     class Context
  74.     {
  75.         private Strategy _strategy;
  76.  
  77.         // Constructor
  78.         public Context(Strategy strategy)
  79.         {
  80.             this._strategy = strategy;
  81.         }
  82.  
  83.         public void ContextInterface()
  84.         {
  85.             _strategy.AlgorithmInterface();
  86.         }
  87.     }
  88. }

관련 URL:

http://www.cumps.be/design-patterns-strategy-pattern/

http://en.wikipedia.org/wiki/Strategy_pattern

 

 

반응형
반응형

 

 

 
 

 

A ,B , C,D ... N 개의 객체들간의 통신을 하려고 할때

 

그리고 이것들이 상속구조를 이루고 있다면 통신하기 위해 직접 연결 한다면 상당히 지저분한 상태에 이르고 만다

 

 

그래서 클래스 중계자(mediator) 하나를 둬서 변경 된 사항을 mediator 에게 던지고 적용시킬지니는 mediator 가 수행하는 패턴을

 

mediator 패턴 이라고 한다

 

 

observer 는 옵저버가 중점이고 mediator 는 mediator 가 중점이다

 


 

 

 

그래서 mediator 의 내부는 좀 복잡해 질 수 있고 통신할 것들에 대해 다 알고 있어야 한다

 

 

또한 mediator 와 연결될 다른 객체들도 mediator 를 연결해야 한다

다른 객채들과의 통신을 mediator 와 통신한다

 

 

장점 : 재사용이 쉬워진다 => A 객체만 재사용 하고 싶으면 A 하나 때내고 mediator 부분에서 A 에 대한 부분만 수정해 주면 됨으로

 

분산된 것을 한곳으로 모여줌 N:M 관계를 1:M 관계로 변경

 

차이:

Facade 와 차이점은 Facade는 일반적으로 단방향이지만 Mediator 는 양방향이다

 

차이:

Observer 는 중앙이 아닌 밖의 것이 중점이 된다

 

A 에서 값이 바뀌면 중계 해주는 곳에 A 가 알려주고  중계 해주는 곳이 나머지들에게  A 값이 바뀌었다고 알려주는 형태

 

구성형태는 Oberser 와 Mediator 와 같긴하다

 

 

 

변화 상태는 this 를 멤버함수 인자로 넘겨서 알리는 방법이 있다

 

 

 

활용

 

메신저 대화명 바꿀때

 

if A ,B 가 서로 친구 일때

 

중간 mediator 가 서로 연결된 친구라면 A 에서 대화명을 바꿨을때 바꾼 대화명을  B 에게 알려준다

 

 

또는 B 는 바뀌는게 싫다고 mediator 에게 요청하면 변경사항을 받지 않는 처리도 할 수 있다

 

 

 

기계가 여러대 있을때 기계 서로의 속도 제어등 전체 조정

 

하지만 각각의 기계가 각자 동작하진 않고 중앙관리 형태로 구성이 되야 한다는 것이 Mediator 패턴의 컨셉

 
 

 

반응형
반응형


블로그 이미지

3DMP engines


 가상 소멸자가 없을때 컴파일 오류 : error C2683: 'dynamic_cast' : 'A'은(는) 다형 형식이 아닙니다.

 


 

class A{
public :
 A(){}
 virtual ~A(){}
};

class C : public A{
public :
 C(){}
 ~C(){}
};


class B : public A{
public :
 int num;
 B(int dd) : num(dd) { }
 B() {}
 ~B(){}


};

 


int _tmain(int argc, _TCHAR* argv[])
{

 A* ci=new A;
 B* bi= dynamic_cast<B*>( ci );
 cout<<dynamic_cast<B*>( ci )<<endl;      // 000000000

 

 return 0;
}

 

 


[직렬상속구조]

 

A <- B <- C  상속 구조에서 자식이 어느 자식인지 확인하는 방법

 

#include <iostream>
#include <list>
#include <iterator>
#include <map>
using namespace std;

class Graphic {
public :
 Graphic(){}
 virtual void Draw(){
  cout<<"Graphic\n";
 }
};


class ComposedGraphic : public Graphic {
public :
 ComposedGraphic(){}


 void Add(Graphic *pObj) {
  cout << "ComposedGraphic" << endl;
 }
};

class SpecificComposedGraphic : public ComposedGraphic {
public :
 SpecificComposedGraphic(){}
 void Draw() {
  cout<<"SpecificComposedGraphic\n";
 }

 void Add(Graphic *pObj) {
  cout << "Specific-ComposedGraphic" << endl;
 }
};

void main()
{
 Graphic *pObj = new ComposedGraphic;
 
 cout<<dynamic_cast<ComposedGraphic*>(pObj)<<endl;                   // 주소값 존재
 cout<<dynamic_cast<SpecificComposedGraphic*>(pObj)<<endl;       // 000000000

 

                 // if 문으로 확인할 경우 제일 하단의 클래스부터 dynamic_cast 을 거처서 어느 자식의 클래스인지 확인해야함


 delete pObj;


 pObj = new SpecificComposedGraphic;

 cout<<dynamic_cast<ComposedGraphic*>(pObj)<<endl;                   //주소값 존재
 cout<<dynamic_cast<SpecificComposedGraphic*>(pObj)<<endl;       //주소값 존재


 delete pObj;
}

 

 





아래부터는 퍼온자료.....


[병렬상속구조]

 

Graphic<---- 클래스A

Graphic<-----클래스B

인 병렬 상속구조일때 해당 클래스가 어느쪽 자식 클래스인지 확인하는 방법

 

 

#include <iostream>
#include <list>
#include <iterator>
#include <map>
using namespace std;

class Graphic {
public :
 Graphic(){}
 virtual void Draw(){
  cout<<"Graphic\n";
 }
};


class A : public Graphic {
public :
 A(){}
 virtual void Draw(){
  cout<<"A\n";
 }
};


class ComposedGraphic : public Graphic {
public :
 ComposedGraphic(){}


 void Add(Graphic *pObj) {
  cout << "ComposedGraphic" << endl;
 }
};

class SpecificComposedGraphic : public ComposedGraphic {
public :
 SpecificComposedGraphic(){}
 void Draw() {
  cout<<"SpecificComposedGraphic\n";
 }

 void Add(Graphic *pObj) {
  cout << "Specific-ComposedGraphic" << endl;
 }
};

void main()
{
 Graphic *pObj = new A;
 
 cout<<dynamic_cast<ComposedGraphic*>(pObj)<<endl;                    // 00000000
 cout<<dynamic_cast<SpecificComposedGraphic*>(pObj)<<endl;         // 00000000
 cout<<dynamic_cast<A*>(pObj)<<endl;                                            // 주소값

 delete pObj;
}

 

 

 

 

 

 

 

 

 

 

 

 

 


반응형

'디자인패턴과방법론 > 패턴정리와스킬' 카테고리의 다른 글

GOF 디자인패턴 정리  (0) 2012.11.01
반응형



블로그 이미지

3DMP engines


[설계 과정]

 

1. 문제의 목적?

 

2. 어떤 패턴?

 

3. 세부적인 해결 방법

 


 

 

 

아키텍쳐 설계   : 큰 레벨에서 분류 하는 것

ex) 클라이언트 서버가 어떻게 돌아가느냐, 디비가 어떻게 있느냐

 

문제를 나누는 것

 

전체 문제를 쪼개는것 => 목적을 쪼개 나가는 것

 

 

이를 전체적으로 쪼개면 프로세스정도로 구분이 되고 이 프로세스를 설계할때

 

클래스 설계에서부터 패턴으로 올라가면서 설계한다

 

 

ex)

웹브라우저 -----> 웹서버 --------> WAS(웹 어플리케이션) [ 디비핸드링, 비즈니스 로직 ]

 

웹브라우저 ,웹서버 , WAS 까지 나누는 레벨이 아키텍쳐설계

 

웹브라우저를 짜겠다, 웹서버를 짜겠다  WAS 를 짜겠다는 것은(디비핸들링, 디브니스 로직 으로 들어가면)

클래스 디자인으로 들어감

 


 

 

 

 

클래스 정의는? : 클래스 정의는 알아서 한다( 클래스는 알아서 끌어낸다) 분석단계 등에서..

 

 

분석단계에서 데이터 모델링한다

(데이터 모델링 : 현실세계에 있는 것을 개체로 이끌어 내면서 구체화해 가는 과정 )

클래스는 명사를 찾아라

 

이런걸 이용해서 클래스를 끌어내야 한다, 클래스를 정의 해야 한다

 

이제 여기에서 클래스들을 어떻게 최적화 시킬것인가에 대한 패턴을 대보는것 => 디자인 패턴

그래서 디자인패턴은 상세설계에서 사용하게 된다

 

* 패턴도 패턴안에서 섞일 수도 있다 즉 => 목적두개가 겹친다

 

 

 디자인패턴은 클래스 구조( 화살표) 를 먼저 보는 것이 아닌 목적을 먼저본다음 클래스 구조를 봐야 한다

 

 

 


 

 

 

-product family 를 만들기 위한 패턴 = Abstract Factory

 

-부분 부분을 생성해서 전체를 생성하는것 = builder

 

-객체 생성을 대행해주는 함수 = Factory Method

 

-복제해서 객체를 생성하고 싶으면 = ProtoType

 

-Maximum  N 개까지만 객체를 생성하고 싶으면 = SingleTon

 

-기존 객체를 사용하고 싶은데 인터페이스가 틀리다 = adapter 

[구조] adapter 패턴 (잘 구현된 클래스에 구현할 기능이 있는 경우 클래스를 private 으로 상속 하는 패턴)

 

-처음 클래스를 설계하면서 interface 와 information 을 나누어서 설계하고 싶다 = bridge

[구조] bridge 패턴 (구현부와 인터페이스를 나누어버리는 패턴 ,여러 환경에서 조사된 가장 적합한 기능에 대해 연결해주는 패턴 대신 실행하는 패턴)

ex) 1.가장 적절한 클래스를 생성해 리턴(unix,window , etc... 등등...)

      2.여러 클래스가 해당 플렛폼에 대해 동일한 클래스(정보) 를 자동으로 플렛폼에 맞게 얻고자 할때

 

-tree 형태로 객체부수를 관리하고 싶다 = composite

 

-동적으로 객체의 기능을 확장시켜 나가고 싶다 = decorator

[구조] decorator 패턴 ( on,off 없이 윈도우에 추가되는 스크롤 같은것 연달아 추가 )

(객체 추가되면서 추가된것 다 실행됨 : 객체가 다음실행할 객체를 (중간)Decorator 클래스 포인터로 가지고 있음)

 

-서브시스템을 대표하는 인터페이스를 갖고 싶다 = Facade

 

-객체를 공유하고 싶다 = Flyweight

 

-중간 매개 개체를 이용해 원객체에 대해 접근제어라든지 추가적인 작업을 하고 싶다 proxy

 

-동적으로 수행할 역할을 이행 시키기, 위임시키기 위해 연결해 놓은 것을 처리 하고 싶다 = chain of responsibility

[행동] chain of responsibility (동적으로 처리할 역할을 연결해 놓은 것, 책임(조건)에 따라 처리 사항을 다음으로 넘기는 것, 처리를 분담)

// 현재 클래스에서 처리하지 못하면 부모클래스에서는 다음 객체포인터를 가지고 있어서 그 객체 포인터로 책임전가

  (객체 추가는 없고 고정된 상태)

 

-수행할 작업을 일반화 시켜서 핸들링 하고 싶을때 = command

  (하나의 함수 명령으로 수행)

 

-어떤 문법에 따라서 파싱하고 원하는 작업까지 동시에 하고 싶다 = interpreter

 

-어그리게이트의 구성요소를 차례로 접근하고 싶다 = iterator

 

-M:N 관계를 1:N 관계로 바꾸고 싶다 = mediator

 (중계자)

 

-객체의 상태정보를 별도의 객체에 저장하고 싶다 = memento

 (저장만 하는 것만!!)

 

-객체 상태정보를 저장하기도 하고 상태에 따라서 행위까지 핸들링 하고 싶으면  = state

 [행동] state 패턴 ( 각 상태에 대해 객체로 만들어 분리 처리하는 것 , 게임능력레벨에 해당하는 행동을 클래스로 분류해서 처리  )

 ex) 각 레벨에 따른 행동 또는 상태 정보가 각 레벨 클래스마다 있고 이 클래스들은 공통적인 것이므로 singleton 처럼 객체가 공유된다

 

-1:N  의 관계를 유지하면서 객체간의 행위를 분산하고 싶을때 = observer

subject 에게 observer 가 변경상태를 통지하면 subject 가 나머지 observer 들에게 변경 내용을 알려주어 변경 내용(상태)에 따라

나머지 observer 들이 그 내용에 맞게 수행하는 패턴

 

-동일 목적의 여러 알고리즘 들을 동적으로 변경시키고 싶다 = strategy

  [행동]Strategy 패턴 같은 목적을 수행하는 알고리즘을 동적으로 바꾸고 싶을때

 

-알고리즘의 기본 골격을 만들어 놓고 난다음 세부 알고리즘은 하위 클래스에서 알아서 바뀌도록 하고 싶다 = Template method

 [행동] Template Method 패턴 (공통된 알고리즘 부분이 고정적일때 사용, 기본 알고리즘 골격을 상위 클래스에서 갖도록 한다 ) 

 하위 클래스에서 구체적으로 처리하기 

  : instance 는 자식으로 생성해놓고 부모에만 정의된 함수를 호출하여 이 함수 안에 virtual 로 선언된 공통함수를 호출하여

    instance 를 만든 자식의 virtual 함수가 불리도록 하는 흐름

 

 

-작업 대상과 작업 종류 작업 항목을 분류해서 작업종류를 임의로 추가하는 것을 유연하게 하고 싶다 = visitor

 [행동] visitor 패턴 (고정부분과 동적인 부분을 클래스에서 분리)

 : 데이터 구조와 처리를 분리 하는 패턴.
   > 필요할 때 : 처리를 데이터 구조에서 분리해야 할 때. => 결합도를 낮춘다

  'strategy 패턴과 응용해서 사용


 

디자인패턴을 실제 어떻게 적용할 것인가?

 

 

한번만에 최적이 나오긴 힘들다, 한번 이터레이션 해보고 Localizatio of change(변경을 국지화) 를 할 수 있는가?

 

를 따져보고 된다면 판단하고 적용

 

 

변경 안되는 부분, 변경되는 부분을 고려햐여 고려

 

일단 패턴을 알면 보통이상의 퀄리티를 보장해 줄 수 있다

 

중요한 점은 어떤 목적으로 접근할 것인가 하는 것이다

많은 고민에 의해서 적용해야지 대강 생각해서 적용해버리면 일정 수준이상에서 퀄리티가 올라가지 않을 수 있다

생각을 많이 해보자

 

 

 

무엇을 할것인가? => 뭘 할껀데?   => 목적이 무엇인가

 

어떻게 할것인가 => 최적화적인것을 판단

 

 








이하 자료는 퍼온 자료들..



 

디자인패턴들의 상관관계

 

 

 

 

 

[관계도 설명]

 

 

-builder 패턴은 composite 객체를 생성하기 위해 사용 될 수 있다

 

-iterator 패턴은 Composite 객체를 구성하는 하위 객체들을 순회하기 위해 사용 될 수 있다

 

-Command 패턴은 MacroComand 클래스 등의 정의시 Composite 패턴을 활용 가능하다

 

-chain of responsibility 패턴은 객체들간의 연결 사슬을 composite 패턴을 이용하여 정의 할 수 있다

 

-composite 객체를 구성하는 각 하위 객체들에게 새로운 연산을 추가하 위해 visitor 패턴이 사용 될 수 있다

(트리 구조에서 각 노드마다 새로운 연산을 위해 함수들을 visitor 로 만들 수 있다)

 

-interpreter 패턴은 문법을 정의하는 과정에서  Abstract Syntax Tree 를 Composite 패턴으로 표현할 수 있다

  (트리가 composite로 표현)

 

-Composite 객체를 구성하는 하위 객체들은 Decorator 패턴을 이용하여 추가적인 역할을 수행하도록 설계 될 수 있다

 

- Flyweight 패턴은 Strategy, State, interpreter 패턴에서 알고리즘이나 상태정보, Terminal Symbol 들을 각각 공유하기 우해 사용 될 수 있다

 

- Decorator 패턴은 이미 존재하는 객체에 새로운 기능을 덧입히는 역할을 하는데 반해

Strategy 패턴은 객체 내부의 구체적인 동작이나 알고리즘을 외부 객체에게 위임시키는 형태이다

그래서, Decorator 패턴은 객체의 겉을 변경시켜주는 역할이고, Strategy 패턴은 객체의 속을 변경시켜주는

역할을 한다고 할 수 있다

 

- Memento 패턴은 Iterator 패턴이 반복 상태를 저장하기 위해 이용 할 수 있으며

  Command 패턴이 명령 수행 이전 상태로 되돌아가기 위해 사용 할 수 있다

 

- Observer 패턴은 객체들 간의 의존 관계를 분산 시켜 관리하는 데 반해 Mediator 패턴은

중앙 집중적으로 관리하기 때문에 복잡한 의존 관계를 한 곳에서 관리하고자 할 경우에는

Mediator 패턴이 효과적이다

 

- Template Method 패턴은 내부의 알고리즘 단계를 정의할 때(변하지 않는 부분) Strategy 패턴을 사용 할 수 있으며

, 대개 Factory Method 패턴을 사용하여 필요한 객체를 생성한다

 

- Abstract Factory 패턴은 종종 Factory Method 패턴이나 Prototype 패턴을 이용하여 구현되며,

  Singleton 패턴을 이용하여 하나의 공유되는 객체를 관리할 수 있다

 

- Singleton 패턴은 Facade 패턴에서도 하나의 객체를 공유하기 위한 목적으로 사용 될 수 있다

 


 

아래 있는건 다른곳에서 퍼온 것 


http://mrnoname.blog.me/130112026691

 

 

JAVA 언어로 배우는 디자인 패턴 입문

작가
유키 히로시
출판
영진닷컴
발매
2008.05.01

리뷰보기


 상반기 개인 학습 목표로 디자인 패턴을 선택한 관계로, 한 동안 'Java 언어로 배우는 디자인 패턴 입문' 이라는 책으로 디자인 패턴에 대해서 알아보았습니다.

 이미 책을 보기 전부터, 코딩을 하며 Singleton이라던지 Factory Method 패턴들을 접해보았고, 직접 적용도 조금 해봤기 때문에, 대략적으로 디자인 패턴이 무엇인지는 어렴풋이 알고 있었습니다. 그래서 이번에 디자인 패턴 학습에서는 '어떤 디자인 패턴들이 있고, 어떨 때 사용해야 될 까?'에 대해서 알아보는 것에 중점을 두었습니다.

 디자인 패턴 관련 서적 중에 가장 유명한 책은 'Head First 디자인 패턴'이었는데, 개인적으로 Head First 시리즈는 그냥 그냥 보기에는 좋지만, 나중에 머리에 남는 것이 별로 없는 것 같아서, 조금 딱딱해 보여도 실질적인 예제 코드들로 설명이 잘 되어있다는 'Java 언어로 배우는 디자인 패턴 입문'을 고르게 되었습니다.

 처음에는 처음부터 순서대로 읽어가면서 정리를 해보자는 생각으로 책을 읽기 시작했는데, 점점 정리를 하다 보니 '아, 이러면 안되겠구나…'라는 생각이 들었습니다. 예전에 개발을 하고 싶지만 전혀 못하던 시절, C++ 책만 이 책, 저 책 사서 보기만 하고 어려워서 포기하고 쉽다는 다른 책 사보고 했던 게 생각이 났습니다. '百聞이 不如一打'라고 개발 공부에는 백 번 보는 것 보다, 한번 쳐보는 게 훨씬 빨리 이해할 수 있을 텐데, 이렇게 책만 붙잡고 있는다고 해서 디자인 패턴에 대해서 얼마나 알 수 있겠나 싶었습니다. 그리고 이 책에 나오는 디자인 패턴을 모조리 다 외운다고 해서 실제 개발에 얼마나 써먹을 수 있을지에 대해서도 의문이 들었습니다. 그래서 그 때 부터는, 디자인 패턴에 대해서 간략하게만 설명해두고, 어떨 때 사용할 수 있는지, 어떨 때 적용하면 좋은지에 대해서만 정리 했습니다. 그러면 나중에 특정 디자인 패턴이 필요한 상황에서 적절한 디자인 패턴을 찾아서 적용시키기 좋을 것이고, 한번씩 정리하면서 어떤 디자인 패턴들이 있는지에 대해서도 숙지할 수 있을 것 같았습니다.

 그렇게 책을 한번 읽고, 정리하면서 어떤 디자인 패턴들이 있는지, 어떤 상황에서 사용해야 하는지, 어떤 방식으로 문제를 해결하는지에 대해서 알 수 있었습니다. 그리고 이번에 학습을 하면서 'Effective Java' 역시 함께 참고하였는데, 이 책에도 디자인 패턴에 관련된 내용들이 많이 나와서 좀 더 고급스러운 패턴 사용법들을 볼 수 있었습니다. 특히 실제로 자주 사용되는 디자인 패턴 중 하나인 Singleton 패턴을 구현 할 때, 자바 1.5 이상의 경우 Enum 타입으로 구현을 하면, 복잡한 직렬화나 리플렉션 상황에서도 직렬화가 자동으로 지원되며, 인스턴스가 여러 개 생기지 않도록 확실히 보장해 주기 때문에 가장 권장 하는 구현 방법이라는 것을 보고, 실제로 과제용 프로그램을 작성할 때 적용시켜 보기도 했습니다. (아래 정리에 예제 코드 포함)

 이번 디자인 패턴을 학습하면서, 여태까지 무심코 사용하고 있었던 코딩 기법들이 알고 보니 디자인 패턴들이었던 것 도 알 수 있었고,(기존 코딩 기법에 패턴이란 이름을 붙인 걸 수도 있겠네요) 디자인 패턴이란 것이 그렇게 특별한 것이 아닌 것 같다는 생각을 했습니다.
 디자인 패턴은 객체 지향 개념과 아주 밀접한 관계를 가지고 있는 것 같습니다. 저는 디자인 패턴이란 '객체 지향 개념(상속,재사용성,캡슐화,추상화 등등)을 어떻게 하면 더 깔끔하고 효율적으로 적용할 수 있을까? 에 중점을 두고 개발을 하기 위한 기법들을 정리한 것'이라고 생각합니다.

 아직은 개발 경력이 얼마 되지 않아서, 이런 디자인 패턴들을 언제 어떻게 적용해야 하는지, 또 적용 할 수 있을 지는 잘 모르겠지만, 이번에 디자인 패턴에 대해 알아 보면서, 객체 지향 개념에 대해서 좀 더 자세히 알 수 있게 된 것 같습니다.

 다음은 책 보면서 간단히 정리한 내용들인데, 각 패턴에 대해서 간략히 훑어보기에는 좋은 것 같습니다. 마지막에 디자인 패턴 Q&A 파트 중, 다음 내용을 처음부터 알았다면, 책을 처음부터 찬찬히 읽는 수고는 덜었을지도 모르겠네요…ㅠ

디자인 패턴은 모두 외울 필요가 없다
- 기계적으로 디자인 패턴을 외우는 것은 의미가 없다. 디자인 패턴이 문제를 어떻게 해결하고 있는지 이해하는 것이 중요하다.

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

시작하기전에
- 디자인 패턴은 클래스 라이브러리가 아니다
○ 클래스 라이브러리 안에서 디자인 패턴이 사용되고 있다
- 프로그램을 완성품으로 보지 않는다
○ 디자인 패턴의 목표는 재사용성
○ 어떤 기능이 확장될 가능성이 있는가?
○ 확장기능을 수행할 때 수정이 필요한 클래스는 무엇인가?
○ 수정이 불필요한 클래스는 무엇인가?
- 다이어그램은 보는 것이 아니라 읽는 것이다
Iterator 패턴 - 순서대로 지정해서 처리하기
Iterator(반복자) 패턴 : 무엇인가 많이 모여있는 것들을 순서대로 지정하면서 전체를 검색하는 처리를 실행하기 위한 것.
hasNext와 next를 이용해서 요소들을 탐색한다.
Iterator를 사용하는 이유 : 구현과 분리해서 하나씩 셀 수 있다.
Next는 틀리기 쉽다 : next의 정확한 의미는 returnCurrentElementAndAdvanceToNextPosition
hasNext도 틀리기 쉽다 : 최후의 요소를 얻은 뒤에false를 반환한다. 즉 "다음next를 불러도 괜찮은지 조사하는" 메소드.
Adapter 패턴 - 바꿔서 재이용하기
Adapter 패턴 : 이미 제공되어 있는 것과 필요한 것의 차이를 없에주는 디자인 패턴. (Wrapper 패턴)
a. 상속을 사용한 Adapter 패턴 : 인터페이스 + 클래스의 다중 상속
b. 위임을 사용한 Adapter 패턴 : 클래스 + 클래스의 경우 ->위임(Composition을 사용)
Adapter를 사용하는 이유 : 항상 처음부터 프로그래밍을 하는 것이 아니기 때문에, 구현하려는 기능이 이미 존재하고 검증 받았다면, 그것을 이용하는 편이 좋고, 그러기 위해서 Adapter 패턴을 이용하는 것이다.

Template Method - 하위 클래스에서 구체적으로 처리하기
Template Method 패턴 : 상위 클래스에서 추상메소드를 통해 뼈대를 결정하고, 하위 클래스에서 그 구체적인 내용을 결정하는 패턴. Java에서 Interface를 상속받아 구현하는 것과 같다.
Factory Method 패턴 - 하위 클래스에서 인스턴스 작성하기
Factory Method 패턴 : 인스턴스를 만드는 방법을 상위 클래스에서 결정하지만, 구체적인 클래스 이름 까지는 결정하지 않는 것. 인스턴스의 골격과 생성을 분리할 수 있다. Template Method 의 전형적인 응용.
Static Factory Method 패턴 : 생성자 대신 고유의 이름을 가지는 static method를 이용해 인스턴스를 생성하면, 생성자를 사용 할 때보다 다양한 이득이 있다.
Singleton - 인스턴스를 한 개만 만들기
Singleton 패턴 : 클래스의 인스턴스가 단 하나만 필요할 때, 인스턴스가 한 개 밖에 존재하지 않는 것을 보증하는 패턴.
Singleton 패턴의 구현 방법
a. INSTANCE를 public final 필드로 선언한다.
b. static factory method를 이용해서 Instance를 참조하도록 한다.(전형적인 getInstance() 메소드를 이용한 구현)
c. Enum 싱글톤 : 하나의 요소만 가지는 열거형(Enum)으로 선언.
public enum Elvis {
INSTANCE;
public void leaveTheBuilding(){…}
}

Prototype - 복사해서 인스턴스 만들기
Prototype 패턴 : 인스턴스를 new로 생성하지 않고 복사해서 새로운 인스턴스를 만드는 패턴. clone 메소드를 이용하여 새로운 인스턴스들을 생성한다. Clonable이 구현 된 클래스에만 적용가능.
Prototype 패턴을 사용하는 경우
a. 종류가 너무 많아서 정리할 수 없는 경우
b. 클래스로부터 인스턴스 생성이 어려운 경우
c. framework와 생성하는 인스턴스를 분리하고 싶은 경우
Builder - 복잡한 인스턴스 조립하기
Builder 패턴 : 전체를 구성하고 있는 각 부분을 만들고 단계를 밟아 만들어 나가는 패턴. 메소드 하나 하나가 메소드 전체를 완성시킨다.
Abstract Factory - 관련 부품을 조합해서 제품 만들기
Abstract Factory 패턴 : Factory Method 패턴과 비슷하지만 Abstract Factory 패턴은 객체 생성과정을 Interface화 시키고, Factory Method 패턴은 객체 생성 자체를 다른 메소드에 넘긴다.
Bridge - 기능 계층과 구현 계층 분리하기
Bridge 패턴 : 기능의 클래스 계층과 구현의 클래스 계층 사이에 다리를 놓는 것.
기능의 클래스 계층 : 새로운 기능을 추가하고 싶을 경우, 클래스 계층 안에서 자신의 목적과 가까운 클래스를 찾아내 그 하위 클래스를 만들어, 목적한 기능을 추가한 새로운 클래스를 만든다는 것.
구현의 클래스 계층 : 새로운 구현을 위해 추상 클래스의 하위 클래스를 만들어 추상 메소드를 구현하는 것.
사용하는 이유 : 구현과 기능의 클래스 계층을 분리하여 각각 계층을 독립적으로 확장할 수 있고, 새로 기능을 추가하더라도 모든 구현에서 사용할 수 있게 된다.
Strategy - 알고리즘을 모두 바꾸기
Strategy 패턴 : 알고리즘을 독립적으로 구현시켜 필요한 알고리즘을 필요할 때 삽입하는 패턴. 위임이라는 느슨한 연결을 사용하여 알고리즘을 손쉽게 교체할 수 있다.
필요할 때 :  알고리즘 교체를 쉽게 하고 싶을 때. (특히 동적으로)
Composite - 그릇과 내용물을 동일시하기
Composite 패턴 : 그릇과 내용물을 동일시해서 재귀적인 구조를 만들기 위한 디자인 패턴.
필요할 때 : 재귀적인 구조가 필요할 때. 트리 구조로 된 데이터 구조는 Composite 패턴에 해당한다. 
Decorator - 장식과 내용물을 동일시하기
Decorator 패턴 : 오브젝트에 기능을 추가해 나가는 디자인 패턴.
필요할 때
○ 내용물을 변경하지 않고 기능을 추가하고 싶을 때.
○ 동적인 기능을 추가하고 싶을 때.
Visitor - 데이터 구조를 돌아다니면서 처리하기
Visitor 패턴 : 데이터 구조와 처리를 분리 하는 패턴.
필요할 때 : 처리를 데이터 구조에서 분리해야 할 때.
Chain of Responsibility - 책임 떠넘기기
Chain of Responsibility 패턴 : 복수의 오브젝트를 사슬처럼 연결해 두면, 그 오브젝트의 사실을 차례로 돌아다니면서 목적한 오브젝트를 결정하는 패턴. 요구를 
필요할 때 : Client와 ConcreteHandler 을 유연하게 연결하는 것.
Facade - 단순한 창구
Facade 패턴 : 단순한 창구 역할을 하는 패턴. 클래스를 개별적으로 제어하지 않아도, 창구에 요구만 하면 역할이 끝난다.
필요할 때 : 내부에서 실행되고 있는 많은 클래스의 관계나 사용법이 복잡한 것들을 단순하게 보여줘야 할 때. 인터페이스(API)를 적게 하는 것이 핵심이다. 클래스나 메소드가 많으면 무엇을 사용해야 할 지 고르기가 어렵고, 틀리기도 쉽다. 이런 인터페이스들을 적게 해 주는 것이 Facade패턴.
Mediator - 중개인을 통해서 처리하기
Mediator 패턴 : 조정자, 중개자라는 의미로, 다수의 오브젝트 사이를 조정해야 할 경우 사용한다. 각각의 오브젝트들이 상호간에 통신을 하는 것이 아니라, 중개인을 통해서만 통신을 하는 패턴.
필요할 때 : 각 클래스에서 분산 시킬 것은 부산 시키고, 집중시킬 것은 집중시켜야 할 때, 중개자 패턴을 통해서 집중시킨다.
Observer - 상태의 변화를 알려주기
Observer 패턴 : 오브젝트의 활동을 관찰자가 기록하는 패턴. Observer는 Subject를 관찰하게 된다. MVC Model-View 관계는 Subject-Observer 관계에 대응한다.
실제로는 Observer가 관찰 한다기 보다는, Subject가 상태를 전달하는 것을 기다리고 있는 구조.
필요할 때 : 상태 변화에 따른 처리를 기술 할 때. 
Memento - 상태를 저장하기
Memento 패턴 : 어떤 시점의 인스턴스의 상태를 확실하게 기록해서 저장해 두고, 나중에 인스턴스를 그 시점의 상태로 되돌릴 수 있는 패턴. undo, redo, history, snapshot 등의 기능을 실행할 수 있다.
필요할 때 : 변해버린 인스턴스의 상태를 원래대로 돌려야 할 때, 캡슐화의 파괴에 빠지지 않고 저장과 복원을 실행해야 할 때.
State - 상태를 클래스로 표현하기
State 패턴 : 사물이나 모양이나 형편(상태)을 클래스로 표현하는 패턴.
필요할 때 : 사물의 상태의 변화를 표현하고 추가해야 될 때.
Flyweight - 동일한 것을 공유해서 낭비 없에기
Flyweight 패턴 : 인스턴스를 가능한 대로 공유시켜서, 쓸데없이 new 하지 않도록 하는 패턴. 인스턴스를 필요할 때마다 new 하는 것이 아니라, 이미 만들어져 있는 인스턴스를 사용할 수 있으면 그것을 공유해서 사용한다.
필요할 때 : 객체를 가볍게 해야 할 때. (메모리 사용량을 줄여야 할 때.)
Proxy - 필요해지면 만들기
Proxy 패턴 : 대리인이라는 의미로, 대리역할을 하는 클래스가 실제 클래스의 역할을 대신 하다가, 실제 클래스의 기능이 필요할 때가 되면 그때 실제 클래스의 인스턴스를 생성하는 패턴.
필요할 때 : 시간이 오래 걸리는 작업을 해야할 때. 초기화에 시간이 걸리는 기능이 많이 존재한 대규모 시스템의 경우, 기동 시점에 이용하지 않는 기능까지 모두 초기화 하면 느려지므로, Proxy 패턴을 이용하여 사용할 때 초기화 하도록 한다.
Command - 명령을 클래스로하기
Command 패턴 : 명령을 클래스로 표현하는 패턴. 명령을 나타내는 클래스의 인스턴스를 하나의 '물건'처럼 표현할 수 있다. 명령의 집합을 저장해 두면 같은 명령을 재실행 하거나, 복수의 명령을 모아서 새로운 명령으로 재이용할 수도 있다.
Interpreter - 문법규칙을 클래스로 표현하기
Interpreter 패턴 : 프로그램이 해결하려는 문제를 간단한 '미니 언어'로 표현하는 패턴. 구체적인 문제를 미니 언어로 기술된 '미니 프로그램'으로 표현한다. 그리고 그 미니 프로그램을 통역하는 프로그램을 만들고, 미니 프로그램을 실행할 수 있도록 한다.
디자인 패턴 Q&A
디자인 패턴이란?
○ 소프트웨어 설계시에 반복해서 발생하는 문제에 대한 해법.
적절한 디자인 패턴의 선택
○ 자신이 설계하고 있는 소프트웨어가 어떤 '문제'를 포함하고 있는지 알아야 한다.
디자인 패턴은 모두 외울 필요가 없
○ 기계적으로 디자인 패턴을 외우는 것은 의미가 없다. 디자인 패턴이 문제를 어떻게 해결하고 있는지 이해하는 것이 중요하다.
디자인 패턴과 알고리즘
○ 디자인 패턴과 알고리즘은 다르지만 밀접한 관계가 있다. 알고리즘을 문제해결의 수법으로 기술해서 패턴으로 표현할 수 있지만, 알고리즘=디자인 패턴은 아니다. 디자인 패턴은 알고리즘 이외에도 이디엄(코딩 시 자주 사용되는 관용구)과도 관계가 있다. 디자인 패턴은 구체적인 구현이라기 보다는, 구체적인 구현을 실현하기 위한 사고방식, 해법이라고 할 수 있다.

 

반응형
반응형

http://xper.org/LineReaderTdd/






LineReader TDD 동영상


LineReader를 테스트 주도 개발(TDD)로 만들어 나가는 과정으로, 김창준과 강규영이 직접 제작했습니다. 전체 상영 시간은 약 1시간 20분 가량 됩니다. 시청을 하실 때에는 윈도우즈 미디어 플레이어를 사용하시고, 되도록이면 전체화면 모드로 보세요. 

-- 김창준, 강규영 (2003년 7월)


동영상의 저작권은 김창준과 강규영에게 있으며, 허락없이는 재배포할 수 없습니다.

반응형
반응형





http://www.javajigi.net/display/OSS/TDD



TDD

Toggle Space Navigation Tree
Space Map

TDD와 JUnit을 이용한 테스팅 방법을 알아보고 효율적인 테스팅 방법에 대해 토의해봅시다.

오픈 소스 스터디

Table of Contents

Introduction

  • 개발자의 테스트 활동이 중요한 이유
    • 초기 단계에서 발견된 결함은 수정이 용이하다.
    • 개발 후기 단계에서 발견된 결함들을 수정하기에는 비용과 시간이 많이 소비되고,
      프로젝트가 실패될 확률이 높아진다.
    • 개발 단계에서의 효율적인 테스팅은 전체 프로젝트 시간을 감소시킨다.
  • 테스트의 종류
    • 단위테스트 : JUnit
      단위테스트는 단위 코드에서 문제 발생 소지가 있는 모든 부분을 테스트 하는 작업이다. 
      보통 클래스의 public method 를 테스트 한다. 
      좋은 단위 테스트란 모든 메서드를 테스트 하는 것이 아니라, 
      상식 수준의 확인을 통해 단위 코드가 의도한 대로 동작하는지 여부를 판단하는 단계이다. 
      이상적으로는 코딩전에 테스트 케이스를 작성하여 구현시 보조자료로 활용하는 것이 좋다. ( TDD의 기법 ) 
      단위테스트 후에 개발팀은 테스트를 프로젝트 테스트 스위트에 추가하여 매일 여러번 수행하고 모든 테스트를 항상 통과하게 해야 한다. 
      기회가 된다면 Code Coverage 를 하는 것이 좋은데 오픈소스로는 JCoverage 등이 있다.
    • 통합/컨테이너 내부 테스트 : Cactus
      좋은 단위 테스트는 시스템내의 복잡한 부분에 관계없이 클래스 내의 함수들을 검사하는 것이다. 
      단위 테스트는 가능한 의존성 없이 독립적으로 처리되어야 한다. 
      Mock Object 로 테스트를 하는 경우도 있지만, 
      Cactus 는 J2EE 컨테이너에 접근하는 방법을 제공한다. 
      컨테이너 안에서 코드 테스트가 가능하도록 하기 위해서 Cactus 는 상세하거나 또는 까다로운 
      실제와 같은 모형을(mock-ups) 개발자에게 제공한다. 
      이 방법은 실행되는 코드가 제품이 출시되는 환경에서 실행되기 때문에 또 다른 피드백 기준을 제공한다. 
      컨테이너 서비스와 상호 작용하는 단일 오브젝트 경우에 컨테이너 내부 테스트를 사용하여 간편한 단위 테스트를 할 수 있다.
    • 수락/기능 테스트 : HttpUnit
      기능 테스트는 전체 시스템이 의도한 바대로 동작하는 지를 검사하는 과정이다. 
      이 방법은 완성된 시스템을 고객으로부터 검사받는 방법이므로 수락 테스트라고도 한다. 
      기능 테스트는 구조적 기능에 대하여 어떤 프로그램의 기능에 대한 시험이며 진척 상태를 확인하고 
      이전의 테스트나 누락된 결점을 잡아내거나 미완성 또는 불완전한 부분에서 발생된 문제를 찾아내는 것이 중요하다. 
      수락 테스트는 고객에 의해 작성된다. 
      기능 테스트는 항상 100% 구현될 필요는 없으나 제품 출시 전에는 100% 수행 되어야 할것이다. 
      기능 테스는 종종 매우 구체적인 내용들을 테스트 하기도 한다. 
      아직은 통괄적인 수락 테스팅 툴은 나오지 않았고 Junit은 어떤 자바클래스에서도 수행될 수 있으나 
      수락 테스팅 도구는 특정 애플리케이션 요구에 따라 작성되어야 한다. 
      HttpUnit을 이용하면 테스팅 API를 이용하여 웹 리소스에 대한 호출과 응답 값 조회를 프로그래밍 할 수 있도록 한다.

TDD

자동화된 테스트로 개발을 이끌어 가는 개발 방식을 테스트 주도 개발이라 부른다. 
TDD는 분석 기술이며, 설계 기술이며, 개발의 모든 활동을 구조화하는 기술이다. 
작동하는 깔끔한 코드(clean code that works). 
이 핵심을 찌르는 한마디가 바로 테스트 주도 개발의 궁극적인 목표다.

테스트 주도 개발에서는 두 가지 단순한 규칙만을 따른다.

  • 오직 자동화된 테스트가 실패할 경우에만 새로운 코드를 작성한다.
  • 중복을 제거한다.

또한 위의 두 가지 규칙에 의해 프로그래밍 순서가 다음과 같이 결정 된다.

  • 빨강- 실패하는 작은 테스트를 작성한다. 처음에는 컴파일조차 되지 않을 수 있다.
  • 초록- 빨리 테스트가 통과하게끔 만든다. 이를 위해 어떤 죄악을 저질러도 좋다.
    (죄악이란 기존 코드 복사해서 붙이기-copy and paste, 테스트만 간신히 통과할 수 있게끔 
    함수가 무조건 특정상수를 반환하도록 구현하기 등을 의미한다.)
  • 리팩토링- 일단 테스트를 통과하게만 하는 와중에 생겨난 모든 중복들을 제거한다

TDD 따라해보기

  • MyProject 라는 프로젝트를 만들었다. 메뉴> New> Project
  • TestCase를 생성한다. 이클립스에서는 TestCase와 TestSuite의 기본 템플릿을 제공하고 있다.
    메뉴> New> Other을 누르면 다음과 같은 창이 뜬다.

  • 생성할 TestCase 파일 이름 및 테스트 대상 클래스를 입력한다. (①)
    만약 setup() 메소드나 teardown() 메소드를 사용할 때는 해당 체크박스를 선택한다. (②)

  • 다음이 생성되었다.

  • 할일 목록을 작성해보자. 작업을 끝낸 항목에는 표시를 하고,
    또 다른 테스트가 생각나면 할일 목록에 새로운 항목을 추가할 것이다.

  • 자, 그럼 구현을 하기 위해 어떤 객체가 있어야 할까?
    방금 이건 속임수다. 객체를 만들면서 시작하는 게 아니라 테스트를 먼저 만들어야 한다. 
    앞에서 언급한 TDD의 주기중 현재 단계는 빨강이다.
  • 그렇다면 어떤 테스트가 필요할까? 할일 목록을 보니 첫번째 테스트는 좀 복잡해보인다.
    작은 것부터 시작하든지, 아니면 손을 대지 않는 게 좋겠다. 이번엔 다음 항목인 곱하기를 보자. 
    대단히 어렵진 않겠지? 이걸 먼저 하는게 좋겠다.
  • testMultiplication이라는 테스트를 추가해보자.

  • 다음 코드를 돌리면 당연히 에러가 난다. 메뉴> Run As> JUnit Test

  • 할일 목록에 3가지를 추가한다.

  • 빨간 막대기를 가능하면 빨리 초록 막대기로 바꾸고 싶다.
    실행은 안 되더라도 컴파일만은 되게 만들고 싶은데, 가장 쉬운 방법이 뭘까? 
    이번 단계는 TDD주기에서 빨강에서 초록으로 넘어가는 과정이다.
  • 현재 네 개의 컴파일 에러가 있다.
    • Dollar 클래스가 없음
    • 생성자가 없음
    • times(int) 메서드가 없음
    • amount 필드가 없음
  • 네개의 컴파일 에러를 없앨 수 있는 가장 빠른 방법은 다음을 테스트 코드 아래 추가하는 것이다.


  • 당장의 목표는 완벽한 해법을 구하는 것이 아니라 테스트를 통과하는 것일 뿐이므로 최소한의 작업을 수행한다.

  • 테스트를 다시 실행해보자.

  • 드디어 초록색 막대가 나타났다. 하지만 아직 주기가 완성되지 않았으니까 서둘지 않는게 좋겠다.
    우리는 TDD의 주기중 빨강/초록을 넘었다.
  • 다음 단계는 리팩토링이다.코드를 다음과 같이 바꿔준다.

  • 테스트는 통과하고 테스트 막대 역시 초록색이다. 우리는 여전히 행복하다.

  • 이 단계가 너무 작게 느껴지는가? 하지만 기억하기 바란다. TDD의 핵심은 이런 작은 단계를
    밟아야 한다는 것이 아니라, 이런 작은 단계를 밟을 수 있는 능력을 갖추어야 한다는 것이다.
  • 5를 어디서 얻을 수 있을까? 이건 생성자에서 넘어오는 값이니 이걸 다음과 같이 amount 변수에 저장하면,

  • 그걸 time()에서 사용할 수 있다.
    인자 multiplier의 값이 2이므로, 상수를 이 인자로 대체할 수 있다.

  • 마지막으로 우리가 자바 문법을 완벽하게 알고 있다는 것을 보여주기 위해 *=연산자를 써주자.( 물론 중복을 제거하기 위해서다. )

  • 이제 첫 번째 테스트에 완료표시를 할 수 있게 되었다.

  • 마무리 - 우리는 다음과 같은 작업들을 해냈다.
    • 우리가 알고 있는 작업해야 할 테스트 목록을 만들었다.
    • 오퍼레이션이 외부에서 어떻게 보이길 원하는지 말해주는 이야기를 코드로 표현했다.
    • JUnit에 대한 상세 사항들은 잠시 무시하기로 했다.
    • 스텁 구현을 통해 테스트를 컴파일했다.
    • 끔찍한 죄악을 범하여 테스트를 통과시켰다.
    • 돌아가는 코드에서 상수를 변수로 변경하여 점진적으로 일반화했다.
    • 새로운 할 일들을 한번에 처리하는 대신 할일 목록에 추가하고 넘어갔다.

TDD의 특징

  • 격리된 테스트
  • 테스트 목록
  • 테스트 우선
  • 단언 우선
  • 명백한 데이터

TDD와 관련된 의문

  • 단계가 얼마나 커야 하나?
  • 테스트 할 필요가 없는 것은 무엇인가?
  • 좋은 테스트를 갖췄는지의 여부를 어떻게 알 수 있는가?
  • TDD로 프레임워크를 만들려면 어떻게 해야하나?
  • 피드백이 얼마나 필요한가?
  • 테스트를 지워야 할 때는 언제인가?
  • 프로그래밍 언어나 환경이 TDD에 어떤 영향을 주는가?
  • 거대한 시스템을 개발할 때도 TDD를 할 수 있는가?
  • 애플리케이션 수준의 테스트로도 개발을 주도할 수 있는가?
  • 프로젝트 중반에 TDD를 도입하려면 어떻게 해야 할까?
  • TDD는 누구를 위한 것인가?
  • TDD는 초기 조건에 민감한가?
  • TDD와 패턴의 관계는?
  • 어째서 TDD가 잘 동작하는가?
  • TDD와 익스트림 프로그래밍의 실천법 사이에는 어떤 관련이 있는가?

JUnit

▪ 다운로드 : http://www.junit.org/

JUnit 기본 클래스

1. TestCase 클래스 : 가장 간단하게 Junit을 사용하는 방법은 TestCase 클래스를 상속받은 클래스를 작성하는 것이다. 이 클래스에는 test로 시작하는 메소드만 나열하면 된다.

2. TestSuite 클래스 : testCase 클래스를 상속받은 클래스만을 사용하다 보면, 일부의 test 메소드는 간혹 실행하지 않고 싶거나 특정한 test 메소드만 실행하고 싶을 때가 생긴다. (①) 또는 Test 클래스를 한데 묶어서 한꺼번에 실행하고 싶은 경우(②)도 발생한다. 이때 사용하는 것이 바로 TestSuite이다.

3. Assersions

4. Fixture : 초기 값 설정 및 해제 - setUp(), teardown()


JUnit4.0에서의 변경사항

  • Test Annotation
    이전 버전에서 사용했던 TestCase를 대신에 org.junit.Test를 임포트하여 다음과 같은 형식으로 사용한다.
    • @Test public void functionName() { }
  • Expected Exception
    @Test Annotation은 "expected" 라는 파라메터를 option 으로 가지고 있는데
    이것은 Throwable의 서브 클래스들을 값으로 취한다.
    • @Test(expected= IndexOutOfBoundsException.class) public void empty() {
      new ArrayList<Object>().get(0); 
      }
  • Timeout
    @Test Annotation은 long형 파라메터를 통해 timeout을 설정할 수 있다.
    • @Test(timeout=100) public void infinity()
      Unknown macro: { for ( ; ; ); }
  • Fixture
    • setup - Before Annotation
      • import org.junit.Before;
        @Before public void functionName()
    • tearDown - After Annotation
      • import org.junit.After
        @After public void functionName()
  • Ignore Annotation
    때때로 일시적으로 테스트를 작동시키지 않을 때가 있는데 Ignore이라는 Annotation을 사용할 수 있다. 
    Ignore하는 이유를 옵션 파라메터를 통해 기록할 수 있다.
    • @Ignore("not ready yet") @Test public void something()

단위 테스트 지침 요약

일반 원칙

  • 망가질 가능성이 있는 모든 것을 테스트한다.
  • 망가지는 모든 것을 테스트한다.
  • 새 코드는 무죄가 증명되기 전까지는 유죄.
  • 적어도 제품 코드만큼 테스트 코드를 작성한다.
  • 컴파일 할 때마다 지역 테스트를 실행한다.
  • 저장소에 체크인하기 전에 모든 테스트를 실행해 본다.

자문해 봐야 할 사항

  • 이 코드가 옳게 동작한다면 어떻게 그것을 알 수 있는가?
  • 이것을 어떻게 테스트할 것인가?
  • ''''' 어떤 것이 잘못될 수가 있는가?
  • 이와 똑같은 종류의 문제가 다른 곳에서도 일어날 수 있을까?

좋은 테스트란?

좋은 테스트는 'A- TRIP' 해야 한다.

  • 자동적('A'utomatic)
    • 테스트가 혼자 실행되고 자신을 검증할 수 있어야 한다.
  • 철저함('T'horough)
  • 반복 가능('R'epeatable)
    • 모든 테스트가 어떤 순서로든 여러 번 실행될 수 있어야 하고, 그때마다 늘 같은 결과를 내야 한다.
  • 독립적('I'ndependent)
    • 확실히 한 대상에 집중한 상태여야 한다.
    • 환경과 다른 개발자들에게서 독립적인 상태를 유지해야 한다.
    • 어느 테스트도 다른 테스트에 의존하지 않는다.
  • 전문적('P'rofessional)
    • 좋은 설계를 위한 모든 일반적인 규칙, 캡슐화 유지, DRY 원칙 지키기, 결합도 낮추기 등은 제품 코드에서 그랬듯이 테스트 코드에서도 반드시 지켜져야 한다,

무엇을 테스트 할 것인가?

Right-BICEP (오른쪽 이두박근이라는 뜻)

  • Right - 결과가 옳은가?
    예) 
  • B - 모든 경계('B'oundary) 조건이 correct 한가?
    <경계 조건에서 확인해봐야 할 사항들 - 'CORRECT'>
    • 형식 일치('C'onformance) - 값이 기대한 형식과 일치 하는가?
      예) 최상위 도메인 이름이 없는 이메일 주소 fred@foobar 이 넘어온다면?)
    • 순서('O'rdering) - 적절히 순서대로 되어 있거나 그렇지 않은 값인가?
      예)
    • 범위('R'ange) - 적당한 최소값과 최대값 사이에 있는 값인가?
      예) 
    • 참조('R'eference) - 코드가 자기가 직접 제어하지 않는 외부 코드를 참조하는가?
      예) 
    • 존재성('E'xistance) - 값이 존재 하는가?
      예) null이 아님, 0이 아님, 집합 안에 존재함)
    • 개체 수('C'ardinality) - 확실히 충분한 값이 존재하는가? 개수를 정확히 필요한 만큼 갖고 있다던가, 정확히 필요한 만큼 만들었다는 것을 확인해야 한다.
      예) 울타리 기둥 에러, 하나 차이에 의한 오류
    • 시간 ('T'ime) (절대적으로 그리고 상대적으로) - 모든 것이 순서대로 일어나는가? 제시간에? 때 맞추어?
      예) 로그인하기 전에 문서를 출력하려고 시도하는 것
  • I - 역('I'nverse) 관계를 확인할 수 있는가?
    예) 
  • C - 다른 수단을 사용해서 결과를 교차 확인('c'ross-check) 할 수 있는가?
    예) 
  • E - 에러조건('e'rror condition)을 강제로 만들어 낼 수 있는가?
    현실 세계에서는 에러가 발생한다. 여러분은 강제로 에러를 일으켜 코드가 현실 세계의 문제를 제대로 처리한다는 것을 테스트 할 수 있어야 한다. 
    네트워크 에러 등을 시뮬레이션 하는 경우 모의객체(mock object)를 사용할 수 있다.
  • P - 성능('P'erformance) 특성이 한계 내에 있는가?
    예) 

프로젝트에서 테스트하기

1. 테스트 코드를 어디에 둘 것인가?

  • 같은 디렉터리
    • 장점: TestAccont가 Account의 보호된 멤버 변수와 메서드에 접근할 수 있다.
    • 단점: 테스트 코드가 제품 코드 디렉터리의 공간을 잡아먹으면서 어질러져 있다.
  • 하위 디렉터리
    • 장점: 태스트 코드를 적어도 제품 코드와 똑 같은 디렉토리에 있지 않게 떨어뜨려 놓을 수 있다.
    • 단점: 테스트 코드가 다른 패키지에 있으므로 필요한 멤버들을 노출시키는 제품 코드의 하위 클래스를 사용하지 않는다면 테스트 코드는 보호된 멤버에 접근할 수 없다.
  • 병렬 트리
    • 장점: 테스트 코드와 제품 코드가 정말로 분리되었다. 테스트 코드가 같은 패키지에 있기 때문에 선택적으로 접근할 수 있다.
    • 단점: 편하게 쓰기에는 너무 멀리 떨어져버린 건지도 모른다.

2. 테스트 예절

  • 혼자하는 테스트와 다른 사람과 함께하는 테스트의 가장 큰 차이점은? 테스트 코드의 동기화
  • 팀 환경에서 코드를 체크인 할 때는, 그 코드가 단위 테스트를 완료하였고,모든 단위 테스트가 통과했다는 것을 확인해야한다.
    사실상, 전체 시스템의 코든 테스트가 새로운 코드에 대해 계속 통과해야 한다.
  • 잠재적 위반사항 목록을 만들자
    • 불완전한 코드(예: 클래스 파일 하나만 체크인 하고 그것이 의존할 수 있는 다른 파일은 체크인 하는 것을 잊어버린 경우)
    • 컴파일 되지 않는 코드
    • 컴파일 되기는 하지만, 다른 코드를 망가뜨려서 컴파일 되지 않게 만드는 코드
    • 대응하는 단위 테스트가 없는 경우
    • 단위테스트가 실패하는 코드
    • 자신의 테스트는 통과하지만, 시스템의 다른 테스트를 실패하게 만드는 코드

3. 테스트 빈도

  • 새 메서드를 작성할 때마다 지역 단위 테스트들을 컴파일하고 실행한다.
  • 버그를 고칠 때마다 버그를 드러내는 테스트를 시행한다.
  • 성공적으로 컴파일 할 때마다 지역 단위 테스트들을 실행한다.
  • 버전 관리 시스템에 체크인할 때마다 모든 모듈 또는 시스템의 단위 테스트들을 실행한다.
  • 따로 배정된 특정 컴퓨터가 자동으로 하루 종일(주기적으로, 또는 버전 관리 시스템에 체크인 할 때마다),
    처음부터 전체 빌드와 테스트를 수행하고 있어야 한다.

4. 테스트와 레거시 코드

  • 이미 있던 코드의 경우 : 가장 망가진 부분을 위한 테스트를 가장 먼저 추가하는 편이 좋다.
    이런 환경에서 실시하는 단위 테스트는 뒷걸음 질을 막는다. 
    즉, 유지 보수하기 위해 수정하고 개선하다가 이미 있는 부분들에 버그를 만들어 내는 죽음의 나선을 피할 수 있다.
  • 연속적 빌드-테스트 프로그램을 사용하여 코드가 저장소에 전송될 때마다
    자동으로 단위테스트가 실행되게 만든다면 불량코드가 전체 회사에 돌아다니는 일을 방지할 수 있다.

5. 테스트와 검토

  • 코드 검토를 수행할 때, 그 검토과정의 필수 구성요소로 테스트 코드를 끼워넣어라
  • 코딩과 검토를 다음 순서로 하면 좋다
  • 테스트 케이스나 테스트 코드, 둘 다를 작성한다.
    1. 테스트 케이스나 테스트 코드, 또는 둘 다를 검토한다.
    2. 테스트 테이스나 테스트 코드, 또는 둘 다를 검토할 때마다 수정한다.
    3. 테스트를 통과하는 제품 코드를 작성한다.
    4. 제품코드와 테스트 코드를 검토한다.
    5. 검토할 때마다 테스트 코드와 제품코드를 수정한다.
    6. 모든 팀원을 이 과정에 참여시킴으로써 팀의 의사소통을 증진시킬 수 있다.
      다른 이들이 어떻게 테스트 하는지, 팀의 규칙이 무엇인지 알게된다.

설계와 관련된 문제들

1. 테스트의 용이성을 높이는 설계

2. 테스트를 위한 리팩토링

3. 클래스의 불변성(invariant)을 테스트 하기

  • 구조적
    • 주문 정보 입력 시스템은 다음과 같은 불변성을 가질 수 있다.
      • 모든 개별 항목은 어떤 주문에 속해야 한다.
      • 모든 주문은 개별 항목 하나 이상을 가져야 한다.
    • 데이터 배열을 다룰 때 인덱스 노릇을 하는 멤버 변수는 다음과 같은 불변성을 가질 수 있다.
      • 인덱스는 >=0이어야 한다.
      • 인덱스는 < 배열 길이여야 한다.
  • 수학적
    • 은행 계좌의 입금 부분과 출금 부분을 계산하면 잔고와 맞아 떨어져야 한다.
    • 다른 단위로 측정된 양은 변환 후에 맞아떨어져야 한다.
  • 데이터의 정합성(consistency)
    • 쇼핑 카트에 들은 항목 목록, 전체 판매액, 그 쇼핑 카트에 들은 전체 항목 개수는 밀접한 관련이 있다.
      항목 목록의 구체적인 내용을 알면, 다른 두 수치를 이끌어 낼 수 있다. 이 수치들이 조화를 이루어 맞아 
      떨어진다는 사실은 불변성이 되어야 한다.

참고문헌

  • 이클립스 기반 프로젝트 필수 유틸리티 CVS,Ant,JUnit (민진우 & 이인선 공저, 한빛미디어)
  • 테스트 주도 개발 (켄트 벡 저, 김창준 & 강규영 역,인사이트)
  • 실용주의 프로그래머를 위한 단위 테스트 with JUnit (데이비스 토머스 & 앤드류헌트 공저, 이용원 & 김정민 역, 인싸이트)
  • 참고 싸이트 - TDD를 공부하고 싶다면?
    http://wiki.tdd.or.kr/wiki.py
    http://c2.com/cgi/wiki?TestDrivenDevelopment
    http://xper.org/wiki/xp/

문서에 대하여

최초작성자 : 오혜진
최초작성일 : 2006년 2월 19일
버전 : 1.0 ? ㅎㅎ 
문서이력 :

  • 2005년 2월 19일 오혜진 문서 최초 생성
  • 2005년 2월 20일 JUnit4.0에서의 변경사항 추가
  • 2005년 2월 21일 오픈소스스터디 1기 장회수님 자료 참고하여 보완, 테스트의 종류 추가
  • 2005년 2월 24일 프로젝트에서 테스트하기 항목 추가 및 문서 구조 수정

반응형
반응형

http://cafe.naver.com/vslinlin/50

 

 

먼저 [3탄] TortoiseSVN을 이용한 업데이트 글에 다시 빌드하라는 내용은 빠졌는데
혹시나 하고 모르실 수도 있기에 언급해드립니다.
업데이트 하신 후 소스 수정하시고 빌드하지 않으면 업데이트 하나마나입니다.^^
까먹지 마시길...



이번에 다뤄질 내용은 TortoiseSVN 응용입니다.

검색을 활용하면 얼마든지 사용법은 나옵니다.
그래서 여기서는 소스구축 후 패치파일 제작과 적용만 소개하고자합니다.

업데이트 할 때마다 매번 config 폴더의 파일을 수정해야합니다.
물론 처음 시작할 땐 일부로라도 그렇게 진행하시는 게 좋습니다.
구축 후 설정법을 익히는 데 도움이 될 수도 있습니다.

이제 매번 똑같은 설정 바꾸기 귀찮아지게 되면 한번쯤 "쉽게 하는 방법 없을까"라는
고민은 대부분 구축해본 분들이라면 해보셨을꺼라 생각합니다.
물론, 여러가지 방법이 있지만 여기서는 TortoiseSVN으로 패치파일을 만들고
다시 적용하는 법을 소개하겠습니다.

1. 주요 변경파일 패치파일 제작

우선 아래의 폴더로 이동해서 각각의 파일들을 본인 서버 구성에 맞게 수정합니다.
수정할 때는 EditPlus 등의 프로그램을 이용하시면 편리합니다.

\AE-go_GameServer\config\administration\
\AE-go_GameServer\config\main\
\AE-go_GameServer\config\network

\AE-go_LoginServer\config\network\


수정을 다 마치고 저장하면 아래 그림처럼 아이콘에 느낌표 표시가 생깁니다.
이 느낌표의 의미는 내용이 원본 소스와 다르게 수정이 되었다는 의미지
파일에 문제가 있다는 표시가 절대 아닙니다.


해당 아이콘의 설명은 TortoiseSVN 설정에 보면 나와있으니 참고하세요.


아래와 같은 방법으로 패치파일을 만들겠습니다.
소스 최상위 폴더 오른쪽 마우스 클릭 -> -> TortoiseSVN -> 패치 생성


수정된 내역이 뜨고 체크가 된 파일들에 대한 패치 파일을 만들겠다는 내용입니다.


"저장 위치"를 선택하고 "파일 이름"을 쓴 다음 "저장" 버튼을 눌러주세요.


아래 그림처럼 패치파일의 내용을 보여 주면서 지정한 위치에 파일이 저장됩니다.


이로써 다음에 업데이트 후 한방에 변경하기 위한 패치파일 제작은 끝났습니다.


2. 리비전 업데이트하기 전 되돌리기

일단, 소스에 인위적인 수정이 들어갔으므로
업데이트 하기 전에 원본 소스로 되돌리는 작업을 진행합니다.
이유는 업데이트시 충돌이 발생할 수도 있기 때문입니다.
방법은 매우 간단합니다.
노보팩 기준으로 \SVN AIONEmu Source\aion-emu 오른쪽 마우스 클릭해서
아래 그림처럼 되돌리기를 실행해줍니다.
여기서 되돌리기란 원본 리비전으로 복원한다는 의미입니다.


모두 선택하고 확인을 누릅니다.


모두 진행된 후 확인을 눌러주면 원본 리비전으로 복원됩니다.



3. 리비전 업데이트

리비전 업데이트 합니다. 방법은  [3탄] TortoiseSVN을 이용한 업데이트 글에 나와있습니다.


4. 패치하기

빌드를 진행하기 전에 먼저 만들었던 패치파일을 이용해서 패치를 진행합니다.
패치파일에서 오른쪽 마우스 클릭해서 하는 방법과
소스폴더에서 오른쪽 마우스 클릭해서 하는 방법이 있습니다.

여기서는 패치파일에서 패치적용을 진행해보도록 하겠습니다.
아래와 같이 만들어진 패치파일을 오른쪽 마우스클릭 -> TortoiseSVN -> 패치 적용 클릭합니다.


위에서 패치 새성할때 소스의 최상위 폴더를 선택했듯이 패치 적용시에도 동일하게 선택합니다.


아래와 같은 창이 뜨면서 패치될 파일들을 보여주게 되는데그 창에서
오른쪽 마우스 클릭 -> Patch all을 실행합니다.
각각의 파일을 더블클릭하면 어떻게 수정이 되는지 TortoiseMerge를 통해서 확인할 수도 있습니다.


아래 그림처럼 패치가 완료되면 파일리스트 색상이 회색으로 바뀌면서
마지막 파일의 패치전과 패치후가 TortoiseMerge에 보여지게됩니다.


이로써 매번 수정해야하는 주요 설정 파일을
미리 만들어둔 패치파일을 통해 간단히 변경할 수 있습니다.

간혹 패치될 원본소스가 이전과 다르게 업데이트 되어 수정되는 경우도 있습니다.
그럴땐 패치될 파일을 보여줄때 빨간색으로 간혹 나오기도합니다.
TortoiseMerge라는 프로그램이 충돌한 파일을 해결하는 역할도 하긴 하는데
되도록이면 이럴 경우엔 강제로 진행하기보다는
일단은 빨간색으로 나온 파일을 더블클릭해서


정상적으로 바뀌는 지 확인 한 후 패치를 진행하도록 합니다.
아래 내용의 뜻은
- 라고 표시되는 줄을 삭제하고
+ 라고 표시되는 줄을 넣겠다는 의미입니다.


다른 사람이 올린 패치파일을 적용하다보면 위와 같은 상황이 많이 생깁니다.
제가 마지막으로 올린 패치파일(유닉2021_kit_end.patch)도 현재 최신리비전에 적용시 충돌이 발생하며
정상적으로 병합도 되지 않는 문제가 발생합니다.
이를 개인적으로 충돌이 나지 않게 해결하는 방법은 분명히 있습니다.
원본과 패치되는 부분을 자세히 비교해서 수동으로 수정해 주는 것이 가장 현명하다고 판단됩니다.

이제 빌드하고 서버 구동하면 됩니다.
수고하셨습니다.

 

반응형
반응형

 

Global ignore Pattern : 부분에

 

아래와 같이 쓴다

 

*.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a *.pyc *.pyo *.rej *~ #*# .#* .*.swp .DS_Store *.Debug Debug *.Release Release ipch *.sdf *.ipch *.exe *.ncb *.opt *.plg *.vsp *.lib LIBD LIB dump *.dmp errorReport log

반응형
반응형

누군가 퍼포스사이트의 기술도큐먼트를 번역해 놓은 것

 

원본 : http://www.perforce.com/documentation/perforce_technical_documentation

 

 

http://meongryul.tistory.com/30

Perforce Client (P4V) 사용법

 | 
Perforce는 현재 여기저기서 많이들 쓰고있는 소스 관리 시스템이다.
서버 설정방법은 내 알바 아니고, 이 시스템에 접근 할 수 있는 GUI를 지원하는 클라이언트(P4V)의 사용법을 적어둔다.
공식 싸이트의 내용이다.

P4V 사용법

P4V, the Perforce Visual client, is Perforce's cross-platform graphical user interface. 
P4V는 퍼포스 비쥬얼한(그림으로 인터페이스가 구성된) 클라이언트인데 다양한 플렛폼을 지원하는 그래픽 유저 인터페이스다.
You can use P4V on Windows, Macintosh, UNIX and Linux computers and benefit from an identical interface regardless of platform. 
따라서 넌 윈도우에서건 맥에서건 유닉스나 리눅스에서건 P4V를 쓸 수 있다.
This introductory guide provides some Perforce basics and an orientation to P4V's layout and features. For more details about P4V, consult its online help. To learn more about Perforce, consult the user documentation on our Web site.
이 소개글은 퍼포스의 기본개념과 P4V의 화면구성과 요소들을 소개한다. 추가 보를 원하면 온라인으로 상담해라. 또 많은 정보가 웹싸이트에 문서로 있으니 참고해라
To use Perforce to manage files, you typically connect to a Perforce server using a client program like P4V. 
퍼포스를 사용해서 파일을 관리하기 위해, 대게의 경우 너는 P4V를 써서 퍼포스 서버로 접속할 것이다.
P4V enables you to check files in and out, and perform the various other necessary tasks. The following sections tell you how to perform basic tasks and point out powerful features and shortcuts.
P4V는 파일을 집어 넣거나 뺄 수 있고(check in, check out), 기타 다양한 필요 업무를 볼 수 있을 것이다. 아래는 그런 기본 내용이다.

Basic Concepts
개본 개념
P4V connects your computer to a Perforce server to move files between Perforce depots and your workspace, as shown below.
P4V는 파일을 퍼포스 메인 창구(이하 : Perforce depots)와 너에 워크 스페이스 사이에서 주고받기 위해 니 컴터를 퍼포스 서버로 연결한다.(아래 처럼)

(역자주 : 워크스페이스라는컨 '사용자의 로컬에 컴터에있는 공간'을 말하고 글로 파일들의 카피본이 들어간다고 표현하고 있고, P4V가 도는 니 컴퓨터는 서버에 접속되어있는 거다.. 라고 써있고. 서버란건 관리하는 중심 머신이라고 써있고, 디폿은 퍼포스의 관리 아래있는 파일들이 담겨있는 레포지터리 라는 뜻이고)

The definitions for these Perforce terms are as follows:
이런 퍼포스가 사용하는 용어는 아래와 같다.
Workspace: folders or directories on the client computer where you work on revisions of files that are managed by Perforce. 
워크 스페이스 : 클라이언트 컴터에 잇는 폴더 또는 디렉토리, 니가 작업하는 작업공간. 퍼포스가 파일 버전을 관리하는데 이를 리비전이라고 하고 넌 이 리비전으로 묶여있는 파일들을 워크 스페이스에서 쓰게 된다.
Client application: P4V (or another Perforce client application), running on your computer, sending commands to the Perforce server and receiving results (files, status information, and so on).
클라이언트 어플리케이션 : 니 컴터에서 도는 P4V (또는 다른걸) 말한다. 이 클라이언트란건 커맨드를 퍼포스서버로 보내고 결과(파일이나 상태 정보)를 받는다.
Server: the program that executes the commands sent by client programs, maintains depot files, and tracks the state of workspaces. The Perforce Server typically runs on a central machine, connected to client machines by the network.
서버 : 클라이언트한테 받은 커맨드를 실행시키고 depot를 관리하고, 워크스페이스들의 상태를 관리하고 있는 프로그램. 퍼포스 서버는 전형적으로 중앙의 머신에서 돌고 네트워크에 클라이언트들과 물려있다.
Depot: a file repository on the Perforce server. It contains all existing versions of all files ever submitted to the server. There can be multiple depots on a single server. The examples in this guide show a single depot.
디폿 : 서버내에 있는 파일 저장소. 존재하는 파일로부터 접수받은 모든 파일들이 버전단위로 존재한다. 한 서버에 다수의 depot이 있을 수 있다.
이 문서 내에서는 하나의 디폿만 다룬다.
Connecting to a Server
서버에 접속해보자.
To gain access to your depots, you must connect to a server. The first time you launch P4V, the Connection Setup Wizard (Macintosh: 
Connection Setup Assistant) guides you through the process of configuring a connection, during which you specify the server, user, and workspace.
디폿에 접근하려면 서버에 접혹해야한다. 니가 P4V를 키자마자 보이는건 '접속 위자드 창'인데 (이걸 맥에선 뭐라고 따로 한다) 얘가 접속 설정과정을
가이드 한다.
To launch the wizard/assistant in subsequent sessions, choose Connection > Set Up Connection...
키고나서 일반상태에있을 때 이 설정창을 다시 열고 싶다면 메뉴에 있다 찾아봐라.
Alternately, you can configure connection settings on a single dialog, as follows:
아래처럼 넌 커넥션을 교체 가능하게 설정 할 수 있다.
1.
P4V를 클릭해서 시작하면 아래 창이 보인다.
2.
Specify the following settings (your Perforce administrator can provide you with this information)
아래의 설정을 하라. (니네 시스템 관리자가 말해준데로)
Port: the port number assigned to the server
포트 : 서버에 할당된 포트 번호
User: your Perforce user name
유저 : 니 유저 아이디
Workspace: the name of your client workspace.
워크스페이스 : 니 클라이언트의 워크 스페이스 이름
To display a list of existing users and workspaces, click Browse. (The server and port must be specified before clicking Browse.)
If you have incorrectly specified a server setting, P4V displays a message like the following:
사용자와 워크 스페이스 리스트를 출력하기 위해서, Browse를 클릭해 봐라. (서버와 포트가 그전에 먼저 설정되있어야 한다.)
만약 잘못된 서버 세팅이 되어있다면 P4V는 아래와 같은 메세지를 출력한다.
Connect to server failed; check $P4PORT.
TCP connect to bigserver failed.
bigserver: host unknown.

3.
To connect, click OK. P4V displays its main screen, as shown in the following figure.
다썼으면 OK를 눌러라 아래처럼 메인 화면이 나온다.
The next section describes the main screen panes.
다음 섹션에서 메인 화면을 설명한다.

Navigating the Main Screen
메인 화면 보기.

The following figure points out the panes and important features of the main screen. 
아래 그림은 각 칸들과 중요한 요소들에 을 설명한다.
To see what a button or screen element does, hold the mouse cursor over it. P4V displays a descriptive tooltip.
버튼과 스크릭 속성들을 알아보기 위해 마우스 커서를 위에 갖다 대라. 툴팁 도움말을 보여줄것이다.
( 역자주 : 좌측 글 : 왼쪽 판 워크스페이스와 디폿 안의 파일과 폴더를 디스플레이 해준다.
오른쪽 상단 글 : 툴바 판은 판을 교채하고 하는 버튼들이 있고 한다.
우측 하단 글 : 우측하단 판은 선택된 오브젝트에 대한 세부 항목을 보여준다.
하단 글 : 로그 판은 서버 명령어들을 보여준다. 데시보다른건 현 상태와 진행하는 업무를 보여준다.)
Setting up your workspace
워크 스페이스 세팅하기
Your Perforce administrator can do this for you, but it's advisable to learn a few important aspects of configuring your workspace, specifically (1) configuring the client root directory and (2) configuring the client view.
퍼포스 서버 관리자가 니 워크스페이스를 세팅 해 줄수도 있다. 하지만 니 워크스페이스를 설정하는데 필요한 중요한 것들은 알아둘 필요가 있다.
특히 클라이언트 루트 디렉토리를 설정하는 것이나, 클라이언트 뷰를 설정하는것들이 중요하다
To define a workspace, choose Connection > New Workspace.... and, when prompted, enter a name for the workspace. To edit your current workspace specification, choose Connection > Edit Current Workspace... 
워크스페이스를 정의하기 위해선 Connection -> New Workspace로 가라 거기에 들어가서, 워크스페이스 이름을 쳐라. 현재 켜져있는 워크 스페이스를 정의하기 위해선 Connect -> Edit Current Workspace를 선택하라.

P4V displays the specification details in the lower portion of the right pane; for example:
참고로 세부내용은 우측 판낼의 하단부분에서 보여진다니( 역자주 : 왼쪽글 - 디폿에 니가 접근할 수 있는 파일을 제한한다. 니가 원하는 것들만 보이는지 한번 확인해라.
오른쪽 글 - 니 컴퓨터에 디폿내용이 담길 루트 디렉토리를 설정한다.)
To display and set the client view graphically, click the View tab. Browse to desired files and folders and context-click to include them or exclude them from the client view, as shown in the following figure.
클라이언트 뷰를 그림을 이용해서 세팅하고 디스플레이하기 위해 Veiw탭을 클릭해라. 원하는 파일들이나 폴더를 브라우저 버튼을 눌러서 오른 크릭해라.
그것들을 클라이언트 뷰에 넣고 빼기 위해 오른클릭(context-click)하라. 아래 그림에서 그걸 보여준다.

(역자주 : 해보니 어떤 것들을 넣고 빼고 하는게 클라이언트 뷰에넣고 빼긴 하지만 디폿의 클라이언트 뷰였다. 디폿은 위에서 말한데로 서버에있는 레포지터리다 거기다 넣고 빼고 하다니?)

Managing your Files
내 파일들 관리하기. 
To manage files using Perforce, you typically perform the following sequence of tasks:
퍼포스를 사용(?)하는 파일들을 관리하기 위해서, 넌 대게 아래와 같이 행동 해야 한다.
1.
Get files from the depot.
파일을 디폿에서 다운 받는다.
2.
Check out files you need to edit.
원하는 파일을 다운(Check Out) 한다. (역자주 : 채크아웃 했다는 말이 SVN과 좀 차이가 있어 보인다)
3.
Edit files.
파일을 편집한다.
4.
Check in your changes.
바꾼 파일을 넣는다(check in)
The following sections provide details about these and other common file management tasks.
아래 섹션은 이런저런 파일 관리 방법에 대한 세부 내용을 제공하고있다.

Getting files from the depot
디폿에서 파일 받기.
To copy files from the depot to your workspace:
디폿에서 파일들을 워크스페이스로 카피 받는 받법
1.
In the left pane, click the Depot tab.
왼쪽 판에 디폿 텝을 클릭하라
2.
Browse to the folder or file you want to retrieve.
니가 획득하기 원하는 폴더나를 찾아라.
3.
Context-click the file or folder. To get the most recent version, choose Get Latest Revision. To get an older version, choose Get Revision...and specify the version you want. 
그 파일이나 폴더를 오른클릭하라. 최신 버전을 받고 싶으면 Get Latest Revision을 누르고, 오래된 버전을 획득하고 싶으면 Get Revision을 누러서 원하는 리비전 번호를 정의해라.
In the Log pane, P4V displays a message like the following.
로그 판에서 P4V는 아래와 같은 메세지를 출력할 것이다.
p4 sync //depot/Misc/manuals/...#head
//depot/Misc/manuals/recommended_configuration.doc added c:\p4clients\bruno-1492\Misc\manuals\recommended_configuration.doc
//depot/Misc/manuals/triggers.doc added c:\p4clients\bruno-1492\Misc\manuals\triggers.doc
//depot/Misc/manuals/vendor_branches.doc added c:\p4clients\bruno-1492\Misc\manuals\vendor_branches.doc
Sync copied 3 files to workspace (including 3 that were added)
Sync removed no files from workspace
Sync completed with no warnings or errors.
(역자주 디폿에있는 어떤파일이 c:의 어디로 카피 되었는지 나와있다. 3개의 파일이 카피 되어잇는게 보인다.)
In the left pane, note that the files display green dots, indicating that they are present in your workspace
메인화면의 왼쪽판에서 파일에 초록색 점이 찍혀이는걸 유념하라. 니 워크스페이스로 들어왔다는걸 말한다.
:Before you can edit the file, however, you must check it out.
그런데 (그림)니가 그파일들을 애드트할수있기 전에 반드시 그것을 채크아웃해야 할 수 있을것이다.


Checking out files from the depot
디폿에서 채킹 아웃 하기.

To check out a file in your workspace:
니 워크스페이스에서 파일 하나를 채크아웃 하기 위해서.
1.
Browse to the desired file in the left pane Depot tab. 
원하는 파일을 디폿탭에서 채크아웃해라.
2.
Context-click the file and choose Check Out.
오른 클릭해서 채크아웃 하라.
In the Log pane, P4V displays a message like the following:
로그 판에서 아래와 같은 메세지가 나올 것이다.
p4 edit //bruno-1492/Misc/manuals/recommended_configuration.doc
//depot/Misc/manuals/recommended_configuration.doc#1 - opened for edit
Opened 1 files for edit
In the left pane, note that the file displays a red check mark, indicating that you checked it out:
왼쪽 판에서 붉은 채크가 된것을 확인해라 니가 그것을 채크 아웃했다는 표시다.
Note that, when you check out a file, Perforce adds it to a changelist, which is a list of related files. You can use changelists to group related files, 
니가 파일하나를 채크아웃했을때, 퍼포스는 그것을 체인지 리스트에 둔다는걸 유념해라. 채인지 리스트란건 관련된 파일들의 리스트를 말한다. 넌 채인지리스트를 관련된 파일들을 그룹화 하는데 사용 할 수 있다.
for example, all files that contain changes required to implement a new product feature. To view the changelist, choose View > Pending Changelistsor click in the toolbar.
예를 들면, 새로운 요소를 구현하기 위해 바뀌어진 부분을 가지고 있는 모든 파일들을 구룹화 하는 걸 예로 들 수 있다. 채인지 리스트를 보기위해 View > Paending Changelist를 보거나 툴바에 잇는 버튼을 클릭해라.
Now you're ready to edit your files.
이제 넌 에디트 할 준비가 되었다. (역자 주: 디폿에 있는걸 그냥 막 건들 수 있구나)
Editing files in your workspace
니 워크 스페이스에 있는걸 에디트 하기
To edit a checked-out file, double-click it (or context-click it and choose Open With, then select the desired application). P4V launches the corresponding editing application. Make changes and save the file. 
체크 아웃 된 파일들을 에디트하기위해서 그걸 더블클릭해라 (또는 오른클릭해서 나오는 메뉴에 Open With를 눌러라 그리고 원하는 어플리케이션(vi edit 같은)을 선택해라. P4V는 관련된 에디팅 어플리케이션을 킬것이다. 내용을 바꿀껄 바꾸고 저장하라.
To select an application with which to open a file, choose File>Open With>Choose Application. Note that you can configure editors on thePreferences dialog Editors tab. 
파일을 열 에디트 어플리케이션을 선택하기 위해서. File ->Open With -> Choose Application을 선택해라. 넌가 니가 에디터를 선호 다이얼로그 에디터 탭(Preferences dialog Editors tab)에서도 선택할 수 있다.

Diffing files to view your edits
니가 에디트한파일들을 디프 떠보기 (같은 파일에서 편집한 부분이 무엇인지 드러나도록 원본파일이나 원본에서 파생된 다른 파일과 비교해 보는 것을 Diff 뜬다 라고 한다.)
To enable you to see what changes you've made, you can compare (diff) your edited file with the version you checked out. 
니가 뭘 바꿨는지 확인하기 위해서, 네 에디트된 파일과 니가 채크 아웃했던 원본 파일과 비교 할 수 있다.
To diff, context-click the checked-out file in the left pane and choose Diff Against Have Revision. 
디프를 뜨기 위해, 왼쪽 판(pane)에서 채크 아웃된 파일을 오른클릭(context-click)하고 Diff Against Have Revision(디폿이 가지고 기존 버전의 파일과 디프뜨기)를 눌러라.

P4V launches P4Diff, displaying the differences between the two files. For example:
P4V는 P4Diff라는 퍼포스 디프 프래그램을 돌릴 것이다. 그놈이 투 파일간에 차이를 표시 해줄 것이다.
Discarding edits by reverting
되돌아가기를 통해서 에디트 취소하기.
If you decide you want to discard your changes:
만약 니가 니가 바꾼걸 취소하고 싶다면
1.
Context-click the file in the left pane and choose Revert. P4V displays a warning dialog. 
왼촉판에 있는 파일을 오른클릭해서 Revert를 눌러라. P4V는 경고 메세지를 출력한다.
2.
Click OK. In the Log pane, P4V displays a message like the following:
OK를 눌러라 아래 로그 판에 아래와 같은 메세지가 보일 것이다.
Checking your edits into the depot
니가 수정한 것을 디폿에 넣기
To check your changed file into the depot, perform the following steps.
수정한 파일을 디폿에 넣기 위해 아래와 같은 절차를 수행하라.
1.
Display pending changelists: click  in the toolbar. P4V displays a list of pending changelists, as shown in the following figure. To display the files in a changelist, expand it
아직 처리되지 않은 지연되어있는 채인지 리스트들을 보기 위해 툴바의 세모 삼각형을 클릭해라, 아래 보여지는데로 아직 처리되지 않은 채인지 리스트들이 보여진다. 애친지 리스트안에 있는 파일들을 보기 위해서 그 체인지 리스트 들을 펴라.

2.
Double-click the changelist in which your file is open. P4V displays the details, as shown in the following figure.
채인지 리스트를 니가 수정한 파일이 오픈되어있는 체인지 리스트를 더블 클릭해라. 아래 그림에서 보여지듯 말이다.
3.
Enter a description explaining the changes you made and click Submit. The Log pane displays a message confirming that your changelist was submitted, similar to the following.
디스크립션 텍스트 박스로 들어가서 니가 바꾼 부분에 대해 쓰고 Submit (제출) 하라. 하단의 로그 판에는 니 채인지리스트가 제출되었다는 확인 매세지가 아래 비슷하게 나온다.
Change 813 submitted.
submit complete. 1 file affected.
Displaying a file's revision history
파일들의 버전 히스토리를 출력하기.
To view the changes made to a file or folder, context-click the file or folder and choose File History or Folder History. The history for the selected file or folder is displayed in the right pane. 
파일이나 폴더의 수정된 내용을 보기 위해, 폴더나 파일을 오른클릭 해서 파일 히스토리나 폴더 히스토리를 선택하라. 선택된 파일이나 폴더의 히스토리가 오른쪽 판에 출력 된다.

For example, the following figure shows the history of a folder, listing every submitted changelist that affected a file in the folder.
예를 들어 아래 그림은 어떤 폴더가 지금 깨지 제출 된 채인지리스트중 자기가 가진 파일에 영향을 주는 채인지리스트들을 리스팅 하고 있는 것이 보인다.
Graphical Reporting Tools
그래픽적인 보고서 제작 툴(역자주 : 정도)
P4V includes several valuable graphical reporting tools:
P4V는 몇가지 귀한 그래킥적 보고 툴을 포함하고 있다.
Revision Graph: displays a diagram that shows the evolution of a selected file, including files related by branching operations.
버전정보 그래프 : 선택된 파일의 발전과정을 보여주는 다이어그램(도표)를 출력한다. 또 체인지 리스트를 만들어 내는 브렌칭 작업과 관련된 파일들도 보여준다.(?)
Time-lapse View: shows how the contents of a selected text file changed from revision to revision. You can easily sweep through revision ranges to locate passages of interest and see when they were created and how they changed.
시간 경과에 따른 뷰 : 선택된 파일의 내용들이 버전별로 어떻게 바뀌었는지를 보여준다. 넌 관심이가는 'passages'를 위치 시키기 위해(?) 쉽게 버전정보를 정보를 훑을 수 있을 것이다.
Folder diff tool: enables you to see how the contents of a folder changed.
폴더 디프 뜨는 툴 : 어떤 폴더 안에 바뀐내용이 무었인지 알게 해줄 것이다.
The following sections provide more details about these tools.
아래는 이런 툴들에 대한 세부 내용을 보여준다.
Viewing file revisions as a diagram
파일 버전을 보는 다이어그램 툴

To display the revision diagram for a file, context-click the file in the left pane and choose Revision Graph. P4V launches the tool, which displays a diagram like the following one.
파일을 위한 버전 다이어그램을 출력하기 위해, 왼쪽 판의 원하는 파일을 오른 클릭하고 Revision Graph를 선택하라. P3V는 툴을 킬것이다. 이 툴은 아래 와 같은 다이어그램(도표)를 보여준다.
This diagram shows you when the file was created and how it was branched, and enables you to view details about each version submitted to the depot and navigate through the graph using the navigation map. For more details about the information displayed in the revision graph, consult P4V online help.
이 다이그램은 니가 언제 파일이 만들어졌고 그게 어떻게 브렌치 됐는지 네게 보여준다. 그리고 디폿에 제출되었던 각 버전의 의 세부 사항을 보여주고, 네비게이션 맵이라는걸 활용해서 그려주는 그래프를 통해 그런 정보를 쉽게 찾아 볼 수 있다. 버전 그래프안에 출력되는 정보에 대헤 더알고 싶거든 P4V 온라인 핼프를 봐라.
Browsing file revisions using Time-lapse View
시간 경과 뷰를 활용해서 파일 버전정보 보기
To browse the changes made to a text file, context-click the file in the left pane and choose Time-lapse View. P4V launches the utility, which displays a screen like the following one. 
파일에 변화를 관찰 하기 위해 왼쪽 판에 해달 파일을 오른 클릭하고 Tile-lepse(시간 경과 뷰)를 선택하라. P4V는 그놈을 킬 것이고 그놈은 아래와 같은 스크린을 보여줄 것이다.
(역자 주 : 우측 슬라이더, 버전 변화에 따라 주욱 살펴볼수 잇는 슬라이드 바가 있다.
채인지 딕테일 : 텍스트가 바뀌고 더해지고 지워진 내역들을 상세하게 보여준다)
Using Time-lapse View, you can sweep through all revisions of the file using the slider, noting when changes were made and who made them. Again, for details, consult P4V online help.
Time-lapse뷰의 슬라이더를 활용해서 해당 파일의 모든 버전 정보를 주욱 훑어 볼 수있다. 아무것도 바뀐게 없는데 누가 그걸 만들 었을 경우 아무것도 표현 안될 것이다. 역시 P4V 온라인 헬프를 참조하라.
Displaying folder history using the folder diff tool
폴더 히스토리를 folder diff tool을 이용해 디스플레이 하기 
The folder diff tool enables you to see how the contents of a folder have changed: which files have been added, changed, or deleted. To view changes to a folder:
폴더 디프툴은 니가 어떻게 폴더의 내용물을 바꾸어 왔는지 보여준다. (어떤 파일을 더했고 바꿨고 지웠는지 말이다), 바뀐내용을 보기 위해서 아래와 같이하라.
1.
Context-click the folder in the left pane Depot or Workspace tab and choose Folder History. 
왼쪽 판에있는 디폿이나 워크 스페이스 템에 폴더를 오른 클릭하라. 그리고 Folder History를 선택하라.
In the right pane, P4V lists changelists that affected the folder, for example:
오른 쪽 판에 보면 P4V는 해당 폴더에 영향을 주는 채인지 리스트를 출력할 것이다. 예를 들면 아래와 같다.
2.
To display the changes that occurred between two revisions of a folder, drag and drop one of the revisions on the other. 
한 폴더에 관련해서 두 버전사이에 변화를 출력하고 싶다면, 하나의 리비전을 비교하고 싶은 다름 버전에 끌어다 놓아라.
P4V displays the changes as shown in the following figure. This example shows that, between the selected revisions, a file was edited and checked in. File highlights are color-coded to indicate additions, changes, and deletions. Expand folders and scroll to locate changes of interest. To skip to the next or previous change, click the right and left arrows
P4V는 아래와 같이 바뀐내용을 보여준다. 이 예제는 선택된 두개의 버전들 사이에 어떤 에디트되고 채크인된 하나의 파일을 표현하고 있다. (역자주 : 하나의 파일은 안보이는거 같은데, 하나의 폴더가 바뀌었다고 보라색 마킹되어 있는게 보인다. 맨위의 보라색 마킹은 바뀐 폴더를 가진 상위 폴더니까 마킹 되어있을 테고)
.
Important and Useful Features
중요하고 유용한 요소들
Among the many features provided by P4V, the following are especially useful:
P4V에 의해 제공되는 많은 요소중, 아래내용이 특히 중요하다.
Tooltips: to get more information about an object, place your mouse cursor over it. P4V displays a popup dialog containing more details.
툴팁 도움말 : 해당 버튼이나 판같은 객체애 더 많은 정보를 우너하므녀 마우스 오버해서 툴팁을봐라 팝업 다이얼로그를 보여주는데 더 많은 정보가 있다.
Drag and drop: P4V includes numerous drag and drop shortcuts for common operations.
드래그 앤 드랍 : P4V는 그래그 앤 드랍을 할수 있는 많은 단축아이콘들을 품고있다 그리고 드래그앤 드랍했을때 다양한 동작을 할 수 있다.
File views: P4V enables you to preview graphics files using thumbnails.
파일 뷰 : P4V는 thumbnails 라는걸 사용해서 그래픽파일들(JPG 같은)을 미리 볼 수 있게 해준다.
Tear off windows: to create a separate window displaying a specification you want to keep on display, you can tear it off.
떼어 낼 수 있는 윈도우들 : 별도의 윈도우 출력을 위해 넌 니가 원하는 화면구성을 만들 수 있다. 각 윈도우를 떼어 낼 수 있다.
The following sections provide more details.
아래 글은 위에 말한걸 자세히 말하고 있다.
Tooltips
툴 팁
P4V provides tooltips for many objects on the screen. For example, to display the status of a file, hold the mouse cursor over the file in the left pane. P4V displays a tooltip like the following one.
P4V는 스크린 위에 있는 많은 오브젝트에툴팁을 제공하는데 예를들어, 파일 상태를 출력하고 싶으면 마우스크서를 왼쪽 판에 그 파일에 마우스를 오버하고 있어봐라. 아래와 같은게 보여질 것이다.
Another example: to display a changelist description, click in the toolbar and hold the mouse cursor over the changelist in the right pane. There are tooltips for all the P4V buttons, too.
다른 예로 채인지리스트 설명을 출력하고 싶으면 툴바에 파란 삼각형을 클릭하고 오른 쪽 판에 채인지리스트에다 마우스 오버 해라. 또 P4V버튼들에 대한 툴팁 또한 많다
Drag and drop
드래그 앤 드롭

P4V provides drag and drop shortcuts for common tasks. Drag and drop can simplify operations on large groups of files. For example, to check out all the files in a folder, drag the folder to a changelist. 
P4V는 드래그 앤 드랍 단축아이콘들을 제공하고 이런 드래그 앤 드랍으로 일반적인 작업을 할 수 있다. 드래그 앤드랍은 큰 파일 그룹을 대상으로 단순한 동작을 수행하도록 할 수 있는데 예를 들어 폴더내에 모든 파일을 채크 아웃 하기 위해 폴더를 채인지 리스트로 끌어다 놓으면 된다.
To diff two files, drag one to the other. For details about drag and drop shortcuts, refer to the P4V online help.
두 파일 디프뜨기, 하나의 파일을 다른 하나의 파일로 드래그하라. 세부 정보는 P4V온라인 헬프를 따라라.
File views
파일 뷰
If you use Perforce to manage graphics files, P4V's thumbnail views enable you to preview the files. To display thumbnails, click the Files tab in the right pane, then select the desired thumbnail size from the title bar
만약 그래픽 파일을 관리하는데 퍼포스를 쓰고 있다면, thumbnail뷰라는게 그림을 볼 수 있게 해준다. thumbnails을 디스플레이 하기 위해서 오른 판에 파일을 클릭하고 타이틀 바에서 원하는 thumbnail 사이즈를 선택해라.
.
P4V displays thumbnails as shown in the following example.
P4V는 아래와 같이 thumbnails 로 디스플레이 한다.
Tearing off tabs
탭들 떼어 내기
To keep a tab open, you can undock it. For example, context-click a file and choose File History, then choose Window > Undock Tab. P4V opens a separate window for it, as shown in the following figure.
하나의 탭을 열려있는 상태로 두기 위해서 는 그을 떼어 낼 수 있다. 예를 들어 하나의 파일을 오른클릭하고 File Hestory를 선택하고 Window -> Undock를 선택하면 P4V는 따로 떨어진 창을 열어둔다 아래와 같이 말이다.
To restore it to the main window, choose Window > Dock Window.
다시 복구 하고 싶으면 Window -> Dock Window를 선택하면 된다.
Setting Preferences
선호도 세팅
To configure P4V, edit its preferences (Mac: P4V > Preferences, Windows: File > Preferences). The Editor tab enables you to associate applications with file types, overriding any operating system associations. 
P4V를 설정하기 위해 선호도 세팅을 해라 (맥에서는 : P4V > Preferences, 윈도우에서는 : File -> Preferences). 에디터 텝은 니가 니 OS에서 돌아가는 파일 타입에 따른 에디터 어플리케이션을 설정하는데 이때 어떤 OS에서건 기본적으로 되어있는 파일 대 사용 어플 관계를 오버라이딩 하게 된다.
The Diff and Merge tabs enable you to configure external applications, in case you prefer tools other than those that are bundled with P4V.
디프나 머지 탭에선 니가 외부어플리케이션을 설정 할 수 있게 해준다. 니가 P4V에 들어있는 툴말고 다른 툴을 선호 할 때 말이다.
Migrating from P4Win
P4Win에서의 이주
If you're moving from P4Win to P4V, here's a list of equivalent operations to help you in your transition
만약 니가 P4Win를 쓰다가 P4V를 쓰기로 했다면 여기 같은 기능을하는 것들끼리 묶어 놓은 리스트가 있다. 니 이주를 도울 것이다.
(P4Win써 본적이 없으므로 패스)
Add to Source Control...
Applies only to files in the Workspace Tree
Graphical annotation tool
Diff 2 Files, Folders orRevisions
Or context- click on file and choose:
Diff Against Have Revision
Integrate Using Filespec or Branchspec
File properties are displayed in the Details pane at the bottom of the Files in Folder view
Remove fromWorkspace
Alternatively context click on file and choose File History
Alternatively context click on file and choose Open
Applies only to folders in the Workspace Tree
Find File Under Selected Folder...
Restrict to client view by choosing:
View>Filter Depot>Tree Restricted to Workspace View
(anyspecification menu)
Navigate directly to desired specification
Show the entire depot by choosing:
View>Filter Depot>Entire Depot Tree
Local View of Client Tree
Show Deleted Depot Files
Favorite Connections
Set Password for (current user)...
Superusers can manage users and groups from within P4V

Next Steps 
다음 장에서 
This guide helps you to start working with files using P4V and points out important basic features, but P4V enables you to do much more: create jobs, branch groups of files, and handle file conflicts that arise in team development settings. 
이 장에서 니가 P4V를 사용해 파일 작업 하는걸 가이드했고, 중욯나 기조 속성을 말했다. 하지만 P4V는 더 많은 걸 할 수 있다. 잡을 만들수있거나 파일 그룹을 브랜치 딸수 있거나 팀단위 개발 세팅을 통해서 하나의 파일을 두 팀원이 동시에 작업하느라 한쪽이 재작업해야하는 갈등 문제등을 제어 할 수 있다.
Perforce administrators can perform administrative operations by choosing Tools > Administration. Using the Administration tool, superusers can manage users and groups, and their access to files and folders within the depot. Some administrative functions must still be performed using the Perforce command-line client (p4). For details, see the Perforce Command Reference and the Perforce System Administrator's Guide. 
퍼포스는 관리자는 관리하는데 필요한 동작을 Tools -> Administration 에서 찾아 수행 할 수 있다. 이 관리 툴을 이용해서 관리자는 사용자와 그룹을 관리 할 수 있고 그들이 디폿 안에있는 파일이나 폴더에 대한 접속을역시 관리 할 수 있다. 어떤 관리적 동작들은 아직도 Perforce Command-line(P4)를 통해서 수행된다. 자세히 알고 싶거든 퍼포스 커맨드 참조와 퍼포스 시스템 관리 가이드를 참조해라.
To become expert with P4V:
P4V전무가가 되기 위해
Consult the P4V online help and read the Perforce user documentation available from the Perforce Web site.
P4V 온라인 핼프를 참조하고 퍼포스 웹싸이트에 있는 퍼포스 유저 문서를 읽어라.
Use tooltips.
툴 팁을 활용해라
Pay attention to the file icons and decorations in the left pane. The decorations and icons display a great deal of information about the type and status of a file. 
파일 아이콘과 오니쪽 판에있는 장식이나 아이콘들을 주의깊게 봐라, 장식이나 아이콘들은 상당히 많은 양의 상태정보나 타입 정보를 보여준다.
Start reading the Log pane.
로그 판에 있는 걸 읽어라.
Learn drag and drop shortcuts to simplify operations on large sets of files.
그래그 앤 드롭 단축 아이콘을 통해 많은 양의 파일들이 해야할 동작을 단순하게 돌리는 법을 배워라.
Use P4V views and filtering features to enable you to selectively display information.
P4V 뷰와 필털이 요소들이 있는데 그것들은 정보를 선택적으로 활용할수 있게 도와 줄 것이다.
To get the whole picture, read the P4V online help, Introducing Perforce and the Perforce System Administrator's Guide. 
청사진을 그리기 위해서 P4V 온라인 헬프를 읽어라 그것들중엔? 퍼포스를 소개와 관리자 가이드가 잇다.
The guides, which are available from the Perforce web site, describe the full set of features that the Perforce Server provides. 
공식 싸이트에 있는 그 가이드에는 퍼포스 서버의 모든 요소들에 대해 풍부하게 설명하고 있다.
Perforce Technical Support is always ready to help you, and there's a thriving community of Perforce users active on the perforce-user mailing list. Consult our web site for details.
퍼포스 사용자 지원팀도 있다는둥.. 커뮤니티고 활발하고 지들 좋으니까 쓰라는 둥.. 잘좀 부탁한다는 둥..

반응형
반응형

http://www.phpk.org/archives/181

 

프로그램을 개발하면서 SVN 서버가 필요한 경우가 있습니다. VisualSVN Server는 Windows 기반에서 간편하게 SVN 서버를 구성해 줍니다.

웹 사이트에서 VisualSVN Server를 내려 받으신 후 msi 파일을 실행하면 설치를 시작합니다.

화면 1 VisualSVN Server 설치 시작 화면

VisualSVN Server는 Apache 웹 서버와 Subversion을 포함하고 있습니다. 이미 설치하려는 시스템이 Apache가 설치되어 있어도 Apache가 사용하는 포트가 중복되지만 않는다면 문제 없이 사용할 수 있습니다.

 

화면 2 서버 설정 화면

VusialSVN Server를 설치할 위치와 소스 코드를 저장할 저장소(Repositories) 위치를 지정할 수 있습니다. 기본 서버 포트는 8443이며 SSL을 통해 접속하게 되어 있습니다. SSL을 사용할 필요 없으시다면 Use secure connection에 V 표시를 없애면 됩니다.

인증 (Authencation)에서는 VisualSVN Server에서 사용자 그룹과 사용자를 관리할 것인지 Windows 에 이미 지정된 사용자 그룹과 사용자 정보를 사용할 것인지를 선택합니다.

 

Subversion authentication과 Windows authentication 차이

인증 방법의 차이는 아래 화면처럼 Subversion authentication을 선택하면 VisualSVN Server에서 사용자 그룹을 생성하고 사용자를 관리할 수 있습니다. 반면 Windows authentication 을 선택하면 Windows 에 등록된 사용자 이름과 비밀번호로 접근할 수 있습니다.(제어판 -> 사용자 계정)

여러 사람과 같이 사용해야 하는 경우라면 Subversion authentication을 사용하는 것이 보다 안전할 것으로 생각됩니다.

화면 3 Subversion authentication 사용 화면

 

설치 후 가장 먼저 사용자를 추가합니다. 원하는 사용자 이름과 비밀번호를 입력하여 사용자를 추가합니다.

화면 4 사용자 추가 화면

그리고 사용자 그룹을 만듭니다. 원하는 사용자 그룹 이름을 입력합니다. 사용자 그룹 추가 화면 아래 Add 버튼을 클릭해서 사용자 그룹에 포함할 사용자를 선택합니다.

화면 5 사용자 그룹 추가 화면

화면 6 사용자 그룹에 사용자를 추가하는 화면

이제 왼쪽 트리 화면에서 VisualSVN Server를 선택하여 시작 화면으로 돌아오면 오른쪽 화면의 Status 항목에 SVN Server URL을 클릭하여 저장소에 접근할 수 있습니다.

Internet Explorer로 URL에 접속하면 보안 인증서에 문제가 있다는 경고 화면을 보게 됩니다. 이 경고는 SSL 인증서가 사설 인증서라는 것을 알려주는 것인데 VisualSVN Server에서 https 사용으로 선택했기에 나타나는 화면이므로 “이 웹 사이트를 계속 탐색합니다(권장하지 않음).”을 선택하면 됩니다.

화면 7 보안 인증서 문제 안내 화면

사용자 이름과 비밀번호를 입력하면 VisualSVN Server의 SVN 저장소를 볼 수 있습니다.

화면 8 VisualSVN Server의 SVN 저장소 화면

저장소 생성

SVN 저장소는 시작 화면에서 “Create new repository…” 를 선택하거나 마우스 오른쪽 버튼을 눌러 문맥 메뉴를 통해 생성할 수 있습니다.

화면 9 저장소 생성 문맥 메뉴

저장소 생성 창이 뜨면 저장소 이름을 입력합니다. 개발팀에서 사용할 저장소라면 화면과 같이 DevTeam 이라고 짓는 것도 좋은 예입니다.

화면 10 저장소를 생성하는 화면

저장소가 생성되면 화면 왼쪽에 DevTeam 이 추가됩니다. 이제 화면 오른쪽 상단에 있는 URL을 SVN 클라이언트를 이용해 접속하면 소스 코드를 관리할 수 있습니다.

화면 11 저장소가 생성된 화면

VisualSVN 웹사이트 : http://www.visualsvn.com/

반응형
반응형

지난번 svn 설치방법에 대해 포스팅 한 후 드디어 svn 연동을 해 보았다!!!!

이번 소프트웨어실습3 프로젝트를 위해서 서버를 임대를 하여 svn을 설치하고 기타 등등을 설치해서 활용을 하려 했으나 금전적 이유로 인해 고민중에 병희형에게 구글code에 대해 듣게 되었다.

구글 code에서 새로운 프로젝트를 생성하며 원하는 소스 관리 툴을 선택하게끔 되어 있으며 난 svn을 선택하였다.

자! 이제 연동을 해보자!

지금부터 진행 될 내용은 일단 svn이 뭐하는 것인지 알고 있으며, 해당 url과 계정을 가지고 있으며, visual studio에 이전에 포스팅한 svn 설치 방법대로 설치했다는 가정 하에 진행하겠다!

Step1. 해당 Subversion 메뉴 접근

 

 

Step2. 해당 Subversion Url 입력

위 그림의 작은 박스 안의 아이콘을 클릭하면 Url을 입력할 수 있는 화면이 활성화 된다. 우리가 알고 있는 Svn 레파지터리 Url을 입력 후 Ok 버튼 클릭

 

Step3. 해당 Svn 레파지터리 내에서 프로젝트 선택

해당 Svn Url이 유효하다면 위와 같이 하위 폴더들이 노출 된다.

우리가 원하는 프로잭트 파일을 선택하여 Open 버튼을 클릭 해준다. 

필자는 이미 Svn 계정 정보를 입력하였으며 저장하기를 하였기 때문에 노출이 안되었다.

계정이 없을 경우 Svn 관리자에게 생성 요청을 하자!

 

Step4. 해당 프로잭트를 Check out 받을 위치 선택

본인이 원하는 Local Directory를 선택 하고 OK 버튼 클릭

 

 

Step5. 해당 프로잭트를 Check out 중!!!!!! 두둥!

 

Step6. 간단한 Svn 연동한 프로젝트 파일 구성

 빨강 박스로 된 파일(Program.cs)과 파란채크표시가 된 프로젝트 등이 보일것이다.

빨강 박스로 된 파일, 폴더, 프로잭트는 Commit할 대상

파란 채크 표시가 된 파일, 폴더, 프로잭트는 최종적으로 자신이 checkout이나 update받은 대상

간단한 SVN용어 설명

Commit - 우리 로컬에 있는 파일 등을 Svn에 반영하는 작업

Update - 우리 로컬에 있는 파일에 Svn의 최신버전으로 변경하는 작업 ( 만약 수정중파일(빨강박스)의 경우 충돌이 발생할수 있음, 이건 적절한 경험을 해봄으로 습득 가능)

Checkout - 우리 로컬에 최초로 Svn 레파지터리에 있는 것을 다운 받는 작업

 

 

 

Step7. 간단한 바로가기 메뉴 설명

필요한 메뉴 항목에 대해서만 설명

Commit - svn서버로 반영

Show Changes - 현재 파일과 svn서버에 있는 파일과 비교

View History - 해당 파일이나 선택한 폴더 등의 이력을 노출

Revert - 현재 파일의 버전으로 원복(최신이 아닌 것을 유념)

 View History

 

 Show Changes

 

Revert

 

 

Commit - Log Message를 남겨주는 것은 필수!

 

자 이상으로 SVN 연동 및 테스트는 끝이 났다!

반응형
반응형

AnkhSvn-2.3.10838.vol1.egg 

AnkhSvn-2.3.10838.vol2.egg 

AnkhSvn-2.3.10838.vol3.egg



SVN을 사용해 왔기에

Visual studio 2010에서도 svn을 사용하기 위하여 설정 해 보았다.

 

http://ankhsvn.open.collab.net/downloads

 

무슨 정보등을 입력해야 한다... ㅎㅎ

 

파일첨부를 하였으니 다운받아 압축 풀고 긍정적인 방향으로 설치 하길 바라다.

 

visual studio가 켜져 있었다면 프로그램 재시작~

 

1. 도구 > 옵션 으로 들어간다.

2. 아래와 같은 화면의 메뉴에서 플러그인 변경

 

3. 변경 후 아래와 같이 svn 사용이 가능해진다. 

 

4. 연동은 추후 해본 후 블러깅 하겠당~

반응형
반응형

 AnkhSVN

http://ankhsvn.open.collab.net/

 


 

출처 : http://yonomi.net/?p=87

 

 

 

 

Visual Studio 2010에서도 Subversion을 이용해서 형상관리를 할 수 있게 되었나보다.

* 설치
(VS2010이 설치된 상태에서) AnkhSVN을 설치한다.
* Source Control 설정
   1. Tools > Options
   2. Source Control > Plug-in Selection
   3. Current source control plug-in 리스트에서 AnkhSVN – Subversion Support for Visual Studio를 선택

Select AnkhSVN for source control
* Repository 탐색
   1. View 메뉴 > Repository Explorer
   2. Add repository URL 선택하여 URL 추가
   Add a URL to the Repository Explorer
   3. 아이디와 비밀번호 확인(옵션)

반응형
반응형

TortoiseSVN in Visual Studio 비주얼스튜디오 SVN 연동 팁

http://ssogarif.tistory.com/873
 

TortoiseSVN in Visual Studio

Filed under:  — David @ 7:44 pm

Update October 2 2007: Someone posted a link to Gary’s Bit Patterns where there is a settings file you can just import instead of doing all these manual steps.

I also fixed the quotes in the commands so they shouldn’t cause trouble anymore.

Ever wanted to use TortoiseSVN from VisualStudio? Well, now you can! 1

Contents

  1. Introduction
  2. Menu
  3. Toolbar
  4. Icons
  5. Done

Introduction

I have created a toolbar with Update, Log, Check, Revert, and Commit tortoise toolbar. The commands work the same as if you right clicked the folder containing the solution. Follow the steps below to get your own tortoise toolbar.

Menu

Select Tools > External Tools… from the Visual Studio menu. Add a tool using the following info.

adding tortoise to the menu

FieldValue
#1 
TitleTortoise &Update
CommandC:\Program Files\TortoiseSVN\bin\TortoiseProc.exe
Arguments/command:update /path:"$(SolutionDir)" /notempfile
#2 
TitleTortoise &Log
CommandC:\Program Files\TortoiseSVN\bin\TortoiseProc.exe
Arguments/command:log /path:"$(SolutionDir)" /notempfile
#3 
TitleTortoise Check for &Modifications
CommandC:\Program Files\TortoiseSVN\bin\TortoiseProc.exe
Arguments/command:repostatus /path:"$(SolutionDir)" /notempfile
#4 
TitleTortoise Re&vert
CommandC:\Program Files\TortoiseSVN\bin\TortoiseProc.exe
Arguments/command:revert /path:"$(SolutionDir)" /notempfile
#5 
TitleTortoise &Commit
CommandC:\Program Files\TortoiseSVN\bin\TortoiseProc.exe
Arguments/command:commit /path:"$(SolutionDir)" /notempfile
  • $(SolutionDir) is the path to the directory the solution is in
  • /notempfile is required when running from the command line
  • The ampersands make that letter a shortcut for use in the menu

You should have the commands in your tools menu. Try them out and make sure they all work.

tools menu with tortoise commands

Toolbar

Add the toolbar by right-clicking your toolbar and select customize. Make a new toolbar and call it Tortoise. Close the customize window and right-click again, this time adding the tortoise toolbar.

Now go back to customize, select the commands tab, and scroll down to the tools category. You should see a bunch of commands like External Command 1, External Command 2, etc. Drag those on to your new toolbar. This may require some trial and error.

You can rename the commands in the toolbar by selecting a button with the customize window open, then clicking the Modify Selection button, then Name:.

changing the toolbar names

Icons

Now to add the icons. I haven’t found an easy way to do this yet. Here’s what I did:

Go to http://tortoisesvn.tigris.org/svn/tortoisesvn/trunk/src/Resources/ (user guest, blank password). Browse to the image you want then right click the image and select Copy Image (note: this was on Firefox). With the customize window open right click the button and select Paste Button Image.

The pasted image won’t be transparent, so you need to edit the image. Right-click and select Edit Button Image. Then erase all the black area.

erasing the transparent part of the icons

Done

Your toolbar should look something like this: tortoise toolbar

  1. Well, you could have before if you wanted. I’m sure I’m not the first to come up with this. I know a few people already do this because it came up on the TortoiseSVN mailing list a while back.

반응형
반응형

-연속메모리 컨테이너 : vector, string( or rope), deque = 배열로 이루어졌으며 재하당 이 일어날 수 있다

-노드기반 컨테이너 :  set, multiset,map,multimap, 요소 삽입을 임의의 위치에서 삽입 불가능( 순서가 있으므로 )

                               (balanced tree 로 구성됨)

 

-해쉬컨테이너와 slist(단일연결리스트) 의 경우 양방향 반복자로 접근될 수 없다

 

-배열 구조와 호환되어야 한다면 vector밖에 쓸 수 있는게 없다

 

-탐색속도가 관심사라면 => 1.해쉬컨테이너, 2.정렬된 vector, 3. 표준 연관(set,map, 외..) 컨테이너 중 하나 의 순으로 접근한다

 

- 참조카운팅이 고려할때는 string 을 쓰지 말 것(string 내부에서 참조카운팅을 사용 할 수 있다=> 동일한 문자열에 대한 참조카운팅 )

   rope 또한 마찬가지 => 참조 카운팅 기반으로 구현되어 있다

   : 대신할 수 있는 것 vector<char>

 

-트렌젝션이 가능하거나 포인터,반복자, 참조가의 무효화가 최소화 되어야 하는가? => 노드기반 컨테이너( list, set, map )

 

 

 

삽입 


set,map 의 경우 push_back, push_front 를 지원하지 않는다 => insert 로 써야 함, 순서유지

list 의 경우에는 지원

 

 

예약

vector 에서는 reserve,capacity 가 있지만 list, deque 에서는이 멤버함수가 없다(내부 구조 때문)

 

반응형
반응형

이펙티브 STL 카페


http://cafe.naver.com/ArticleList.nhn?search.clubid=10513818&search.menuid=59&search.boardtype=Q

이펙티브 STL 게시글


http://cafe.naver.com/cppstl.cafe?iframe_url=/ArticleList.nhn%3Fsearch.clubid=10513818%26search.menuid=59%26search.boardtype=Q







http://cafe.naver.com/cppstl

반응형
반응형

내가 STL에 조예가 깊어서 글을 남기는 것이 아니라, Effecitve STL 을 공부하는 사람들이 이 글을 보고, 도움이 되었으면 하는 생각과, 혹시 내가 틀린것이 있다면 지적해 주시지 않을까 란 생각으로 글을 올리는것임을 미리 밝힙니다. - 최익필





이번 항목은 두 알고리즘의 사용 방법을 알아보자는 취지로 이야기 된 것 같다. 그러므로 나는 두 알고리즘의 사용 법을 기준으로
 설명을 하도록 한다

두 알고리즘 전부 algorithm 안에 들어 있다.

각각 어떻게 사용 하는지, 그 소스코드를 보자.

#include <iostream>
#include <algorithm>
#include <vector>
 
int main( void )
{
    int a[10];
    std::vector<int> v(10);
    for( int i = 0; i < 10; i++ )
    {
        a[ i ] = i;
        v[ i ] = i;
    }
    // 일부러 틀리게 셋팅
    v[ 3 ] = 10;
 
    // 비교 후 틀리면
    // 틀린 위치의 a 배열 값과 v 컨테이너 이터레이터를 뱉어냄
    std::pair<int*, std::vector<int>::iterator > p =
        std::mismatch( &a[0], &a[9], v.begin() );
 
    // 만약 틀린게 없다면, 둘다 끝의 값을 p 에 저장함
    std::cout << *p.first << std::endl;
    std::cout << *p.second << std::endl;
     
    return 0;
}


한가지 주의 해야 할 점은 첫번째 범위 데이터는 두번째 범위데이터 보다 짦은 범위의 인자를 넣어야 한다는 것이다. 다른것은 그냥 컴파일 해보면 알수 있을 것이다.

#include <iostream>
#include <algorithm>
#include <vector>
 
int main( void )
{
    int a[10];
    std::vector<int> v(10);
    for( int i = 0; i < 10; i++ )
    {
        a[ i ] = i;
        v[ i ] = i;
    }
    // 일부러 틀리게 셋팅
    v[ 3 ] = 10;
 
    // 기본적으로 less 비교를 한다.
    // 리턴값 : 첫번째 범위 구역의 값들 중 두번째 범위구역 값들보다
    // 작거나 같으면 TRUE 아니라면 FALSE
    if( std::lexicographical_compare(&a[0], &a[9], v.begin(), v.end()) )
    {
        std::cout << "성공" << std::endl;
    }
    else
    {
        std::cout << "실패" << std::endl;
    }
 
    return 0;
}

주의 해야 할 구역은 주석을 달아 두었다.


관련링크
http://ilu8318.egloos.com/833073
http://turboc.borlandforum.com/impboard/impboard.dll?action=read&db=cpp_tip&no=19
http://www.winapi.co.kr/clec/cpp4/42-1-4.htm - mismatch 설명

반응형
반응형

상등 ==  set.find

동등 < 로 판정 find(

 

set 멤버 비교, 동등비교

ex) set의 멤버함수인 find,  그냥 find 알고리즘

 

set멤버함수 find 함수는 동등 비교

그냥 알고리즘 비교 -> 상등 비교

 


반응형
반응형

http://ohyecloudy.com/pnotes/archives/243


[STL] 문자열과 integer,float 사이의 변환 (atoi, stringstream)

 

#include <cstdlib>
#include <cstdio>
#include <cerrno>
 
int main()
{
    char    *str = NULL;
    int     value = 0;
 
    str = "-123124";
    value = atoi( str );
    printf( "Function: atoi( \"%s\" ) = %d\n", str, value );
 
    str = "3336402735171707160320";
    value = atoi( str );
    printf( "Function: atoi( \"%s\" ) = %d\n", str, value );
    if (errno == ERANGE)
    {
        printf("Overflow condition occurred.\n");
    }
 
    return 0;
}

 

문자열에서 integer, float로 캐스팅이 필요할 때, 주로 atoi, atof, strtol 등 CRT 함수를 사용한다. underflow, overflow가 발생하면 errno이 ERANGE로 세팅되고 최대값 혹은 최소값을 반환한다. 위 예제 코드는 MSDN 에서 가져왔다.

 

 

int stoi(const string& from)
{
    std::stringstream oss(from);
 
    int to;
    oss >> to;
    assert(!oss.fail() && !oss.bad() && oss.eof());
    if( oss.fail() || oss.bad() || !oss.eof() )
    {
        // 예외 처리
    }
 
    return to;
}

atoi를 STL에 있는 stringstream class를 사용해서 구현할 수 있다. “123d”와 같은 문자열을 문자열 스트림에 넣고 int로 출력하면 d 이전까지만 출력된다. 이 경우 스트링 문자열에 문자가 남아있게 된다. 이렇게 입력 문자열이 숫자로만 구성됐는지를 검사하려면 eof 플래그를 검사하면 된다. “d123″ 같이 처음부터 출력하지 못하는 경우나 overflow나 underflow 경우에는 fail이나 bad 플래그가 세팅된다. 그래서 이 세 개의 플래그를 검사해서 예외 처리를 하면 된다. underflow, overflow 같은 경우는 atoi를 사용한 예제처럼 errno 값을 검사해서 확인할 수도 있다.

 

#include <sstream>
#include <iostream>
#include <string>
#include <assert.h> 


template<typename TO, typename FROM>
TO NumberStringCast( const FROM& from )
{
    stringstream ss;
    ss << from;
 
    TO result;
    ss >> result;
 
    assert(!ss.fail() && !ss.bad() && ss.eof());
    if( ss.fail() || ss.bad() || !ss.eof() )
    {
        // 예외 처리
    }
 
    return result;
}
 
int main()
{
    cout << NumberStringCast<int>("123") << endl;
    cout << NumberStringCast<string>(12.5f) << endl;
    cout << NumberStringCast<float>("123.3e10") << endl;
 
    return 0;
}

템플릿 클래스로 만들면 추가 코드 작성 없이 변환을 할 수 있다.

실행 속도는 당연히 CRT 함수인 atoi 시리즈가 당연히 빠르다. 속도에 민감하지 않는 부분이면 stringstream을 사용해서 편하게 캐스팅하는게 나을 것 같다. stringstream는 iostream 클래스를 상속받기 때문에 iostream처럼 다룰 수 있다는게 최고 장점이다. 이런게 있다는 것만 알고 사용하지 않았는데, 사용해보니 상당히 편하다.

반응형
반응형

tolower ,toupper a~z, A~Z 의 범위를 변환 시킨다






http://neodreamer.tistory.com/267



std::string 의 문자열을 대소문자 변환이 필요해 찾아보았는데 쉽게 처리할 수 있는 방법을 찾았다.

std::transform 함와 cctype 헤더의 tolower() 와 toupper() 함수를 이용하면 쉽게 해결이 되었다.

transform 함수는 이외에도 응용할 부분이 많아보인다. container 의 각 원소에 특정을 변형을 주어
바꾸거나 다는 container에 넣을 수도 있다. transform 함수에 대해서는 좀더 공부를 해서 나중에 포스팅을 한번 해야겠다.



#include <cctype> // for toupper & tolower
#include <string>
#include <algorithm>
using namespace std;


	// 대문자로 바꾸기
	string s1 = "sample string";
	transform( s1.begin(), s1.end(), s1.begin(), toupper );
	// 결과 : s1	"SAMPLE STRING"

	// 소문자로 바꾸기
	string s2 = "HELLO";
	transform( s2.begin(), s2.end(), s2.begin(), tolower );
	// 결과 : s2	"hello"


	// 첫 문자만 대문자로 바꾸기
	string s3 = "title";
	transform( s3.begin(), s3.begin() + 1, s3.begin(), toupper );
	// 결과 : s3	"Title"

반응형
반응형



bitset 으로 int 를 이진수로 표현하기



#include <bitset>
#include <iostream>
using namespace std;

 

 

 

int dd=3;
cout << "dd as binary short : " << bitset<numeric_limits<unsigned short>::digits>( dd ) << endl;


or

 

cout << "3 as binary short : " << bitset<numeric_limits<unsigned short>::digits>( 3 ) << endl;






http://www.borlandforum.com/impboard/impboard.dll?action=read&db=cpp_qna&no=563



10진수를 진법을 변환한다고 한다면 문자열로 변환한다는 거겠죠? 

방법 1) 
stdlib.h 에 있는 
itoa(), ltoa(), ultoa() 함수를 쓰면 (Windows에만 있습니다. ANSI C 호환 안됩니다.) 
int, long, unsigned long 형을 2~36진법(숫자 10 + 영문자 26)까지 선택하여 
char* 형으로 변환할 수 있습니다. 

itoa의 원형은 다음과 같습니다. 
char *itoa(int value, char *string, int radix); 

예제는 다음과 같습니다. 

int main() 

   int number = 123; 
   char string[25]; 

   itoa(number, string, 2); 
   printf("integer = %d string = %s\n", number, string); 
   return 0; 


방법2) 
2진법만으로의 변환이라면, 
ANSI C++ 라이브러리의 bitset.h에 있는 bitset 클래스를 사용하면 됩니다. 
10진수 -> 2진수, 2진수 -> 10진수로의 변환도 쉽게 할 수 있습니다. 
물론 속도는 itoa()보다 빠릅니다. 

예제는 다음과 같습니다. 

int main() { 
  const bitset<12> mask(2730ul); 
  cout << "mask =      " << mask << endl; 

  bitset<12> x; 

  cout << "Enter a 12-bit bitset in binary: " << flush; 
  if (cin >> x) { 
    cout << "x =        " << x << endl; 
    cout << "As ulong:  " << x.to_ulong() << endl; 
    cout << "And with mask: " << (x & mask) << endl; 
    cout << "Or with mask:  " << (x | mask) << endl; 
  } 

  return 0; 


출력은 다음과 같습니다. 

mask =      101010101010 
Enter a 12-bit bitset in binary: 111000111000 
x =        111000111000 
As ulong:  3640 
And with mask: 101000101000 
Or with mask:  111010111010 

참고) 정수를 16진수로 변환할 때는 VCL의 IntToHex()도 많이 사용합니다. 
단 이 경우는 AnsiString으로 변환합니다.



반응형
반응형

출처 : [msdn]


numeric_limits::infinity 

Visual Studio 2005

The representation of positive infinity for a type, if available.

static Type infinity( ) throw( );

The representation of positive infinity for a type, if available.

The return value is meaningful only if has_infinity is true.

// numeric_limits_infinity.cpp
// compile with: /EHsc
#include <iostream>
#include <limits>

using namespace std;

int main( )
{
   cout << numeric_limits<float>::has_infinity <<endl;
   cout << numeric_limits<double>::has_infinity<<endl;
   cout << numeric_limits<long double>::has_infinity <<endl;
   cout << numeric_limits<int>::has_infinity <<endl;
   cout << numeric_limits<__int64>::has_infinity <<endl;

   cout << "The representation of infinity for type float is: "
        << numeric_limits<float>::infinity( ) <<endl;
   cout << "The representation of infinity for type double is: "
        << numeric_limits<double>::infinity( ) <<endl;
   cout << "The representation of infinity for type long double is: "
        << numeric_limits<long double>::infinity( ) <<endl;
}

Output

1
1
1
0
0
The representation of infinity for type float is: 1.#INF
The representation of infinity for type double is: 1.#INF
The representation of infinity for type long double is: 1.#INF

Header: <limits>

반응형
반응형

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

int main(){


 std::vector<int>   vecTest;
 vecTest.push_back( 10);
 vecTest.push_back( 20);
 vecTest.push_back( 30);
 vecTest.push_back( 40);
 vecTest.push_back( 50);
 std::vector<int>::iterator Ite;

 //copy( vecTest.begin(),vecTest.end(), ostream_iterator<int>() );

 Ite = lower_bound( vecTest.begin(), vecTest.end(), 3); 
 cout<<*Ite<<endl;           // 10출력

 Ite = lower_bound( vecTest.begin(), vecTest.end(), 17); 
 cout<<*Ite<<endl;           // 20출력

 Ite = lower_bound( vecTest.begin(), vecTest.end(), 20); 
 cout<<*Ite<<endl;           // 20출력

 // Ite = lower_bound( vecTest.begin(), vecTest.end(), 53); //vecTest.end() 리턴
 // cout<<*Ite<<endl;           // 에러발생 - Ite가 vecTest.end() 이라서 예외처리 해줘야한다.

 cout<<endl;

 Ite = upper_bound( vecTest.begin(), vecTest.end(), 0); 
 cout<<*Ite<<endl;     //10     


 Ite = upper_bound( vecTest.begin(), vecTest.end(), 10); 
 cout<<*Ite<<endl;      //20    

 Ite = upper_bound( vecTest.begin(), vecTest.end(), 45); 
 cout<<*Ite<<endl;          //50

 Ite = upper_bound( vecTest.begin(), vecTest.end(), 40); 
 cout<<*Ite<<endl;   //50

 //Ite = upper_bound( vecTest.begin(), vecTest.end(), 50);  //에러아님
 //cout<<*Ite<<endl;         // 에러 발생

 

 

 return 0;
}

반응형
반응형

transform(), copy() 알고리즘과 같이 연산을 하거나 단순 복사를 하는 알고리즘을 사용할 때, 결과물을 쓰기 위한 반복자(iterator)를 함수 인자로 받는다. = operator로 값을 쓰기 때문에 결과물을 특정 컨테이너 뒤에 삽입하려면 귀찮은 과정을 거쳐야 한다. 이럴 때 쓰라고 만들어 놓은 게 반복자 어댑터이다. 내부 구현을 보면 = operator 를 오버로딩해서 push_back(), push_front(), insert() 를 호출한다.



// 벡터 정의
int arr1[] = { 0, 1, 2, 3, 4 };
int arr2[] = { 5, 6, 7, 8, 9 };
 
typedef std::vector<int>    IntegerVector;
IntegerVector v1(arr1, arr1 + sizeof(arr1) / sizeof(arr1[0]));
IntegerVector v2(arr2, arr2 + sizeof(arr2) / sizeof(arr2[0]));
 
// v1 벡터의 원소를 v2 벡터에 append한다.
v2.resize(v1.size() + v2.size());
std::copy(v1.begin(), v1.end(), v2.end() - v1.size());
 
// 콘솔 출력
std::copy(v2.begin(), v2.end(), std::ostream_iterator<int>(std::cout, " "));
반복자 어댑터를 사용 안 하면 resize()와 반복자 연산을 해야 한다.




v2.reserve(v1.size() + v2.size());
std::copy(v1.begin(), v1.end(), std::back_inserter(v2));
reserve()는 원소가 많을 때 여러 번의 메모리 할당을 막으려고 호출한다. 확실히 반복자 어댑터가 간편하고 코드도 더 직관적이다. 이거 땜씨롱 반복자 어댑터를 쓰는 거지.



inserter(),back_inserter(),front_inserter() 는 각각 insert_iterator, back_insert_iterator, front_insert_iterator를 생성하는데, back_insert_iterator의 구현을 살펴보면,

template<class _Container>
class back_insert_iterator : public _Outit
{    // wrap pushes to back of container as output iterator
public:
    explicit back_insert_iterator(_Container& _Cont)
        : container(&_Cont)
    {    // construct with container
    }
 
    back_insert_iterator<_Container>& operator=(
        typename _Container::const_reference _Val)
    {    // push value into container
        container->push_back(_Val);
        return (*this);
    }
 
protected:
    _Container *container;    // pointer to container
};
= operator를 오버로딩해서 push_back을 호출한다. preincrement, postincrement, dereference 연산자는 반복자와 같은 동작을 한다.




back_inserter 

Visual Studio 2005

Creates an iterator that can insert elements at the back of a specified container.

template<class Container>
   back_insert_iterator<Container> back_inserter(
      Container& _Cont
      );

Parameters

_Cont

The container into which the back insertion is to be executed.

back_insert_iterator associated with the container object _Cont.Remarks

Within the Standard Template Library, the argument must refer to one of the three sequence containers that have the member function push_backdeque Classlist Class, or vector Class.

// iterator_back_inserter.cpp
// compile with: /EHsc
#include <iterator>
#include <vector>
#include <iostream>

int main( )
{
   using namespace std;
   int i;

   vector<int> vec;
   for ( i = 0 ; i < 3 ; ++i )  
   {
      vec.push_back ( i );
   }
   
   vector <int>::iterator vIter;
   cout << "The initial vector vec is: ( ";
   for ( vIter = vec.begin ( ) ; vIter != vec.end ( ); vIter++)
      cout << *vIter << " ";
   cout << ")." << endl;

   // Insertions can be done with template function
   back_insert_iterator<vector<int> > backiter ( vec );
   *backiter = 30;
   backiter++;
   *backiter = 40;

   // Alternatively, insertions can be done with the
   // back_insert_iterator member function
   back_inserter ( vec ) = 500;
   back_inserter ( vec ) = 600;

   cout << "After the insertions, the vector vec is: ( ";
   for ( vIter = vec.begin ( ) ; vIter != vec.end ( ); vIter++ )
      cout << *vIter << " ";
   cout << ")." << endl;
}

Output

The initial vector vec is: ( 0 1 2 ).
After the insertions, the vector vec is: ( 0 1 2 30 40 500 600 ).

Header: <iterator>

반응형

+ Recent posts