dev.log2005. 1. 13. 18:46

[먕] //네트웍 패킷 파싱.
  int header=packet.header;
  Message * pMsg;
  switch(header)
  {
  case HELLO_MSG:
    pMsg=new HelloMsg();
    break;
  case CHAT_MSG: 
    pMsg=new ChatMsg();
    break;
  }
[먕] 잠시
[먕] 위의 예를 보자고
[먕] HelloMsg,ChatMsg 는 모두 Msg 를 상속 받았다고 하고
[먕] 네트웍 패킷을 위처럼 파싱하고 있는데
(엄) Message 겠지;
(엄) 여튼.
[먕] 저런 switch 문을 쓰고 싶지 않고.
[먕] 해당 키 값에 따라 동적으로 클래스 인스턴스를 생성하고 싶으면
[먕] 어케 해야 되나?
(엄) 어차피 어딘가에는 스위치나. 테이블이 들어 가야 해 -_-
(엄) 뭐 그럴때 쓰는게
(엄) 프로토타입 패턴이긴 한데
(엄) 어차피 스위치나 테이블 둘중의 하나가
(엄) 코드에 포함되는건 피할 수 없지 ㅡ_-
(엄) 나도 저 문제로 열라 궁리 많이 했거덩 -_-
[먕] 음...
[먕] c로는 불가능 한거군.
[먕] java 에서는 저런 switch 문 없이
[먕] 동적으로 생성자 맵핑이 되거덩
(엄) 어뜨케?
[먕] 해쉬테이블이 구조체가 하나있고
[먕] hash.registerDecoder(HELLO_MSG,HelloMsg.class);
[먕] hash.registerDecoder(HCHAT_MSG,ChatMsg.class);
(엄) 그게
(엄) 프로토 타입이자너 -_-
[먕] 패턴이름은 모르겠고.
(엄) 뭐. 그렇게 하려면.
(엄) Message 클래스에
(엄) Message* Message::clone()
(엄) 등의 메소드를 선언하고.
(엄) Message* ChatMsg::clone() { return new ChatMsg( *this ); }
(엄) Message* HelloMsg::clone() { return new HelloMsg( *this ); }
(엄) 그리고 각 객체의 프로토 타입을 해쉬테이블에 등록하면 되지
[먕] 흑... 그건 아냐..
[먕] 잠시.
(엄) 어
[먕] 그럼 위에 처럼 할려면
[먕] 메시지 디코더 인스턴스가 하나씩 생성되어 버리는거 아냐?
(엄) 어차피 니가 쓴 자바 코드도
(엄) 해쉬테이블에
(엄) 타입태그와 타입클래스를
(엄) 등록해 놓는거 아냐
[먕] 자바에서는
[먕]
  NetMessageHandlerManager manager=getMessageHandlerManager();
  manager.registerHandler(DefaultChatMessage.makeIdentifier(ChatProtocol.LOGIN_SUCCESS),new UnSupportedMessageHandler());
  manager.registerHandler(DefaultChatMessage.makeIdentifier(ChatProtocol.PLAIN_MESSAGE),new ChatMessageHandler());
  manager.registerHandler(DefaultChatMessage.makeIdentifier(ChatProtocol.CHAT_MESSAGE_RECEIVE),new C
[먕] 이렇게 해놓으면 타입태그+클래스생성자 들이 등록되는거고
[먕] 위의 프로토타입 패턴을 쓰면.
[먕] 타입태그+클래스 인스턴스가 등록되고
(엄) 그르치
[먕] 그나마 깔끔하다.
(엄) 뭐 정 시르면
(엄) 그르니까
(엄) 해당 메시지의 인스턴스가 생기는게 정 시르면
[먕] 시로
(엄) 해당 클래스의
(엄) 오브젝트 팩토리를 등록해 놓든가 -_-
[먕] 잠시 고로케 한번 해볼께
[먕] 근데.
(엄) 어
[먕] 그렇게 하면 마찬가지로
[먕] 타입태그+팩토리 오브젝트가 맵핑되는거 아닌가 -_-
(엄) 그러치
(엄) 어차피.
(엄) 자바 코드도
(엄) Class 클래스의 객체가 등록되는 거자너
(엄) 별로 다를건 없는거 같은데? -_-
[먕] 잠시 비교 들어갔음.;
(엄) 웅
[먕] 근데
[먕] c 에서 팩토리 구현은 어떤 식으로 되는거야 ?
(엄) C에서?
[먕] c++ 이나
(엄) C에서는 좀 많이 돌아가야 되고 -_-
(엄) C++은.. 대개는
class abstract_factory
{
    object* produce() = 0;
};
class chat_factory : public abstract_factory
{
    object* produce() { return new chat_msg(); }
};
(엄) 뭐 이런 식으로 하지
[먕] 아 -_-
(엄) 아
(엄) virtual 빼먹;
class abstract_factory
{
    virtual object* produce() = 0;
};
[먕] 비지니스 오브젝트 생성 없이
[먕] 팩토리 오브젝트 생성으로 대신하는군
(엄) 어
(엄) 내가 그랬자너 -_-
(엄) 어차피 어딘가에서는
(엄) 테이블에 등록되던가 스위치가 들어가던가
(엄) 둘중의 하나가 불가결하다고 -_-
[먕] 절케 하려면
[먕] 또다시 N 개의 팩토리 클래스가 필요하네 -_-
(엄) 어
[먕] 아햏햏
(엄) 뭐, 물론 비즈니스 오브젝트의 불필요한 생성은 막을 수 있고....
(엄) 팩토리 패턴이 가지는 모든 장점도....
(엄) 차후에 적용할 수 있거찌 ㅡ_-
[먕] 아아...자바가 좋아~ =.=
(엄) 자바도 다를바가 없는거 같은데? -_-
(엄) 자바도
(엄) 어차피 클래스 로더가
(엄) 클래스 로딩하면
(엄) Class 클래스의 객체를 만들어 놓자너 -_-
[먕] 오브젝트의 동적타입을 실시간에 알 수 있으므로
[먕] C 보다는 져아~ =.=
(엄) 어. C++도 가능해
(엄) 컴파일할 때 RTTI 켜놓고 컴파일하면
(엄) typeid()던가
(엄) 하는 연산자를 쓸 수 있지;
[먕] RTTI 가 뭐야 ?
[먕] 첨들어 =.=
(엄) runtime type information
[먕] 오오....
[먕] 마이 컸네 C
[먕] =3
(엄) C++98 부터 있던 표준이야 ㅡ_-
[먕] 한번도 본적 없는걸 ㅡ.ㅜ
(엄) http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_pluslang_typeid_operator.asp
[먕] 저걸로 컴팔이 하면
[먕] 클래스 필드에 뭔가가 추가 되는거냐
(엄) 당연히 뭔가가 추가 되거찌?
[먕] 그럼 예상치 못한 문제도 생길 수 있겠군 -_-
[먕] 여튼..
[먕] 별게 다있군 오..
(엄) 뭐 그래서 로우-레벨한 걸 좋아하는. 대다수의 C++유저는..
(엄) RTTI잘 안쓰지 ㅡ_-
[먕] 특히 네트웍 플그램 에서도 =.=
(엄) 어
[먕] 니가 말한 팩토리 이용한 방법이
[먕] 가장.. 적합한것 같다
(엄) 내 생각도 -_-
[먕] OKI DOKI
(엄) 수고~
[먕] 어 수고~


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

결국, 가능한 최선의 해결책은 결국엔 하나로 귀결된다고나 할까.

저기서 약간의 첨언을 하자면, 각 팩토리 클래스는 템플릿으로 구현하면 약간의 손품을 덜 수 있다..

template <class T>
class concrete_factory : public abstract_factory
{
public:
    object* produce() { return new T(); }
};

위에서 T가 object에서 상속받기만 한다면, 다음과 같이 팩토리 패턴을 그대로 쓸 수 있다.

hash_table.register( ID_TYPE1, new concrete_factory<type1>() );
hash_table.register( ID_TYPE2, new concrete_factory<type2>() );
hash_table.register( ID_TYPE3, new concrete_factory<type3>() );
hash_table.register( ID_TYPE4, new concrete_factory<type4>() );

N개의 팩토리 클래스 대신, 1개의 팩토리 클래스 템플릿으로 대체가 되는 것이다!
템플릿과 함께하는 C++에 축복을! >_<


Posted by uhm