2015. 11. 30. 17:23

버그를 찾아라

자유게시판 2015. 11. 30. 17:23

직접 관할함으로써 혁신에 대한 영감을 찾을 수 있다.

하지만 숱한 삶의 길목에서 당신은 아주 기계적으로, 

무의식적으로 그 기회를 스쳐 지나가버리고 만다.

그러면 영감을 만나지 못한다.

당신이 밟고 다니던 길을 벗어나라.

그러면 발견할 수 있는 기회가 훨씬 더 많아진다.


여행, 특히 해외여행을 하거나,

새로운 운동을 시도하거나

새로운 활동을 경험할 때 그런 계기가 생긴다.


이런 때 당신은 마음을 좀 더 열고 어린이처럼 질문한다.

"왜 그럴까?" "왜 안 될까?"

이 같은 질문은 당신을 혁신으로 인도한다.


당신이 새로운 것을 경험할 때마다 신중하게 주의를 기울이고

인상, 반응, 의문등을 메모해야 한다.

특히 당신을 괴롭히는 문제를 더욱 주도면밀하게 써 놓아야 한다.

우리는 이런 메모를 '결점 리스트'라고 부른다.

그 리스트는 당신의 인생을 바꿀 수 있다.


숱한 기업들이 일상적인 일로 사람들이 허우적거리는 것을 관찰하면서,

그 문제를 어떻게 해결할까 궁리하고 있다.

이런 기횐느 바로 당신에게도 있다는 걸 잊지 마라

2015. 11. 16. 14:56

Command Pattern

프로그래밍/C++ 2015. 11. 16. 14:56

* 문제 사례 설명

- 예제

- 웹으로 게시판 서비스를 제공하는 프로그램을 작성한다고 가정

- 이 때 게시판 프로그램은 CGI(Common Gateway Interface) 형태로 작성

- 웹 브라우저로부터 전달된 요청이 웹 서버를 거쳐 표준 입력 형태로 게시판 프로그램에 전달

- 게시판 프로그램에서 표준 출력 형태로 전송한 결과가 웹 서버를 거쳐 이용자가 보는 웹 브라우저의 화면으로 전달되는 형태

- 이 때 웹 브라우저로부터 전달되는 요청의 종류는 "cmd=login"과 같이 cmd라는 이름의 값으로 지정되는 문자열에 의하여 


- 여기서 문제는 게시판에서 제공하는 서비스 항목이 처음부터 명확해지지 않고 개발도중에 점차 추가될 가능성이 많음

- 예를 들어 처음에는 이용자 로그인과 게시물 목록 보여주기, 게시문 본문 읽기 서비스 항목만 있다가 

- 점차 게시물 쓰기, 게시물 추천하기 등의 서비스 항목이 추가

- 이럴 경우 어떻게 하면 기존에 개발해 두었던 부분들을 수정하지 않고 쉽게 새로운 서비스 항목을 추가할 수 있는가?


* 다양한 접근 방법 및 Command 패턴

- CGI 형태로 게시판 프로그램을 작성할 때 게시판에서 제공하는 서비스 항목을 쉽게 추가할 수 있도록 설계

- 여기서 서비스 항목이 추가된다는 것은 뒤집어 생각하면 게시판 프로그램으로 전달되는 요청의 종류가 추가

- 이는 곧 요청에 따라 처리해야 할 작업이 추가

- 주어진 문제는 게시판 프로그램에 새로운 요청 처리를 수행하는 작업을 수시로 쉽게 추가하려면 어떤 구조의 설계를 하는 것이 좋은가?




Command Pattern 구현 관련 사항

- Execute() 멤버 함수의 구현에 대해 생각해보면

  단순히 요청을 처리할 객체의 멤버 함수를 호출하는 형태부터

  요청 자체를 직접 처리하는 형태까지 다양할 수 있다

- 이 때 후자 방식은 Command 클래스가 다른 클래스에 의존하지 않게 구현   하고 싶을 때나 요청 처리를 수행할 적당한 객체가 없을 때 또는

  작업 수행과 관련된 객체를 묵시적으로 알고 있을 때 유용


* 직접 처리하는 경우의 문제점

- 클라이언트 프로그램이 요청을 처리할 객체를 일일이 알고 있어야 함

- 새로운 종류의 요청 처리가 필요할 때마다 Client 프로그램을 수정


1. 클라이언트 프로그램이 요청을 처리할 객체를 일일이 알 필요가 없는 방법

- 요청을 처리하는 객체들의 클래스를 모두 동일한 상속 구조에 포함

- 여기서 클래스들을 동일한 상속 구조에 포함시켜 정의하는 것인 각 클래스들이 동일한 인터페이스를 가지도록 만드는 것

- 이렇게 되면 클라이언트는 처리해야 할 요청의 종류에 상관 없이 동일한 형태로 프로그램 작성이 가능

- 그러나 이 방법은 요청을 처리하는 객체들의 클래스가 별다른 관련도 없는데 같은 상속 구조 하에서 동일한 자료형으로 다루어지게 만드는 것


- 또 다른 방법

- 클라이언트가 하던 역할을 대신하는 객체를 두는 것

- 요청의 종류에 따라 처리 객체를 지정하는 일을 대신 수행하는 객체를 정의하고 클라이언트가 하던 역할을 모두 이 객체에게 위임

- 이 방법을 적용할 경우 클라이언트는 당연히 요청을 처리할 객체에 대해 일일이 몰라도 됨

- 왜냐하면 그 일을 위임받은 객체가 따로 존재하기 때문

- 그렇다면 이 때 클라이언트의 역할을 위임받은 객체의 클래스는 실제 어떻게 설계되는 것이 좋은가?

- 문제의 핵심은 요청의 종류에 따라 그것을 처리할 객체에 대한 정보를 저장, 관리하도록 만드는 것

- 이보다 좋은 방법은 요청의 종류 별로 별도의 클래스를 정의해서 그것을 처리할 객체에 대한 정보를 저장, 관리

- 단, 이때 클라이언트 프로그램에서 이들 클래스 객체들을 동일한 방식을 다룰 수 있게 만들어 주기 위해서는 이들 클래스의 상위에 Command 클래스와 같은 추상 클래스를 정의해주는 것이 필요


- 새로운 요청이 추가되더라도 클라이언트가 수정되지 않게 하는 방법

- 클라이언트가 수정되지 않게 만들려면 존재하는 조건 비교 문장이 사라짐

- 주어질 수 있는 값들과 그에 따라 실행해야 할 모듈들을 미리 등록해두었다가 요청이 들어오면 일치하는 모듈을 찾아서 곧바로 찾아서 실행

- 이 방법을 적용하려면 실행해야 할 모듈들을 일반화시켜 저장, 관리할 수 있는 자료형

- 한 가지 방법은 동일한 상속 구조 하에 정의, 각 인터페이스 명을 통일

- 불려질 모듈 별로 각각 별도의 클래스를 정의하고 이들이 동일한 상속 구조에 놓임


- 결국 별도의 클래스 상속 구조를 정의해서 활용





* Execute( ) 멤버 함수로 전달되어야 할 인자가 클래스마다 다를 경우

1. 각 클래스의 생성자의 인자로 

   Execute( ) 멤버 함수에서 사용할 인자를 미리 전달

   요청을 처리할 객체가 각 클래스마다 다르므로,

   생성자를 통해 미리 요청을 처리할 객체를 전달

2. Execute( ) 멤버 함수의 인자로 주어질 것들을 각각 클래스로 정의하고, 

   이들의 상위에 추상클래스를 정의함으로써 

   Execute( ) 멤버 함수가 동일한 자료형의 인자를 가지도록 만드는 방식

   Execute( ) 멤버 함수로 전달되는 인자를 Request 클래스로 정의한 것

   void Execute(Request& request);


* 여러 작업을 한꺼번에 처리할 수 있는 방법

- 삭제 후 삭제된 게시물의 목록 보여주기

  DeleteCommand( )

  ListCommand( )

- MacroCommand 패턴을 이용



* 새로운 요청이 추가될 때마다 

  Command의 하위 클래스를 매번 새로 생성하지 않고 실행할 수 있는 방법

- C++의 template 기법

template <typename Type>

class Command{

public:

    void Execute(Request& request){

        m_object->DoAction(request);

    }


private:

    Type* m_object;

};


다만 이 경우, 요청을 처리하는 객체의 인터페이스가 DoAction( ) 형태 통일


* Template Functor 방식

- 각 요청에 대한 처리 모듈을 미리 등록해두되, Command 패턴에서처럼

  작업을 처리할 객체와 작업 처리 모듈을 감싸주기 위한 클래스를 

  요청의 종류마다 각각 정의하지 말고, Functor라는 클래스를 이용

- 여기서 Functor 클래스는 실제 작업 처리 모듈에 대한 함수 포인터를 내부   적으로 가지고 있는 것

- 작업 처리 모듈이 객체의 멤버 함수일 경우에는 객체에 대한 참조 값과

  멤버 함수에 대한 포인터를 같이 저장, 관리할 수 있게 설계된 것

- 이 때 멤버 함수가 요청에 대한 처리 모듈일 경우 

  객체에 대한 참조 값이 함께 필요한 이유는 멤버 함수는 반드시 객체가 있   어야 실행 가능하기 때문

- Functor 클래스를 정의하는 데 template 기법을 사용하는 이유는

Functor 클래스 내부의 함수 또는 멤버 함수 포인터가 가리키는 실제 함수가

인자를 가진다든지 되돌리는 자료가 있을 경우 이들에 대한 자료형을 표현하기 위해서임

- 아무리 template 기법을 적용하더라도 형식 인자의 개수는 구체적으로 지정되어야 하기 때문에

  Functor 클래스는 내부의 함수 포인터가 가리키는 실제 함수가 몇 개의 인자를 가지는지,

또 되돌리는 자료형이 존재하는지에 따라 각각 다른 클래스로 정의



* Command 패턴 정리


- Command 패턴은 요청을 처리할 작업을 일반화시켜 요청의 종류와는 무관하게 프로그램 작성이 가능하게 만들어 주는 것

- Invoker는 실제 Command 클래스의 Execute() 멤버 함수를 호출해주는 것으로 별도의 클래스로 정의될 수도 있고 클라이언트도 될 수 있음


* 유용한 경우

- 그래픽 사용자 인터페이스(GUI) 등을 구현 시 메뉴나 버튼에 수행할 작업을 일반화 시켜 설정하고자 할 때 유용

- 경우에 따라서는 동일한 메뉴에 대해서 동적으로 다른 Command 클래스 객체를 설정함으로써 동일한 메뉴나 버튼이 선택되더라도 상황에 따라 다른 작업을 수행

- 작업 수행을 요청한 시점과 실제 작업을 수행하는 시점을 달리 하고 싶을 때에도 유용





* 결론

- Command 패턴은 외부로부터 요청이 전달될 때 

  이를 받아주는 프로그램 모듈은 미리 작성해 두고,

  각각의 요청에 대해 요청 처리를 수행하는 모듈은 개별 응용 프로그램마다

  플러그인 시키는 콜백(Callback) 형태의 프로그램 작성에 매우 유용

- 따라서 여러분이 충분한 이해와 함께 많이 활용할 수 있기를 기대






2015. 11. 12. 16:46

솔루션 탐색기에서 .cpp 파일을 지웠지만

실제 vcxproj 파일에서는 삭제되지 않은 경우이다


이 경우에는 vcxproj 파일을 메모장을 읽어들여서 열어서

해당 .cpp 파일이 들어있는 xml 부분을 삭제해주면 된다

2015. 11. 12. 13:41

오른손 좌표계 사용

+z : 화면 밖으로 나오는 방향

모든 각은 radian으로 표시

객체는 자신의 로컬 좌표 공간에서 묘사(object coordinate space)

신 그래프에서 모든 변환이 객체에 적용된 후에 월드 좌표 공간으로 변환

월드 좌표 공간에서 카메라와 빛(light)을 포함

2015. 11. 4. 21:51

- 요구사항 결정

- 인수 테스트 생성

- 우선 순위 설정


개발자 팀은 요구사항을 구현

구현이 인수 테스트를 통과하는지 확인

테스팅 팀은 구현이 원래 어떻게 동작해야 하는지, 

어떻게 동작하면 안되는지 검사

테스터는 고객팀을 도와 인수 테스트를 개발하고 개발팀은 테스트를 통과