2010-04-26 2 views
2

여기 내 문제이며 C++에서 factory 메소드를 사용하려고합니다. 귀하의 의견은 무엇입니까?내 문제에 대한 공장 방식의 적절한 설계입니까?

기본 클래스와 많은 하위 클래스가 있습니다.

네트워크를 통해 TCP를 통해 개체를 전송해야합니다.

첫 번째 측면에서 객체를 만들고이 객체를 사용하여 바이트 배열 TCP 메시지를 만들고 다른쪽에 보냅니다.

반대쪽에서는 TCP 메시지를 분해합니다. 객체를 생성하고이 객체를 다형성 대기열에 추가합니다.

+0

당신이 묻고/생각하고있는 것이 확실하지 않습니다. 바이트 배열은 객체의 가변 부분과 가능하면 해당 하위 유형을 나타내는 "페이로드"의 일종입니까? 디 직렬화? 개체가 양쪽에서 사용되며 동기화가 필요합니까? 첫 번째 경우에 어떤 하위 클래스를 인스턴스화 할 것인지 결정하는 요인은 무엇입니까? –

+0

C++ CORBA 구현에서 사용하는 표준 직렬 처리기를 사용하지 않는 이유는 무엇입니까? –

+0

바이트 배열이 직렬화 목적으로 사용됩니다. 동기화, 한 쪽 보내기 및 다른 쪽 사용은 필요 없습니다. 바이트 배열의 하위 문자열을 사용하여 하위 클래스로 결정합니다. – metdos

답변

1

짧은 대답 : 예.

긴 답변 : 팩토리 메서드 패턴이 원하는 것입니다.

네트워크 메시지는 메시지 머리글에 역 직렬화 할 개체의 유형과 크기를 포함해야하며받는 사람 측에서는 나머지 메시지 본문을 소비하고 deserialize하여 개체를 구성 할 수 있습니다.

이 간단한 작업은 모든 클래스가 serialize하고 개인 구조체에서 전선을 통해 보낼 데이터를 저장하도록하는 것이 좋습니다. 다른 직렬화되지 않은 클래스 데이터는이 구조체 외부에 있습니다. 그렇게하면 최소한의 작업으로 전체 구조체를 네트워크에 덤프 할 수 있습니다. 분명히 크로스 플랫폼 (예 : 크거나 작은 또는 큰 엔디안)으로 이동하는 경우 바이트 순서 고려 사항을 고려해야 할 수 있습니다. 이 같은

뭔가 (I이 난 그냥 내 머리 위로 떨어져 그것을 쓰고 있어요 완벽과는 거리가 먼 확신) :

enum VehicleType 
{ 
    VehicleType_Car, 
    VehicleType_Bike 
}; 

class Vehicle 
{ 
    virtual size_t GetDataSize() = 0; 
    virtual void* GetData() = 0; 
}; 

class Bike : Vehicle 
{ 
private: 
    VehicleType _type; 
    size_t _dataSize; 
    struct BikeData 
    { 
     char[100] name; 
     // etc 
    } _data; 
public: 
    Bike(void* data) 
     : Bike(static_cast<BikeData*>(data)->name) 
    { 
    } 

    Bike(char[]& name) 
     : _type(VehicleType_Bike), _dataSize(sizeof(BikeData)) 
    { 
     memset(&_data.name, 0, 99); 
     strncpy(&_data.name, name, 99); 
    } 

    virtual size_t GetDataSize() { return _dataSize; } 
    virtual void* GetData() { return &_data; } 
}; 

class Car : Vehicle 
{ 
    // etc 
}; 


void SendVehicle(int socket, const Vehicle& vehicle) 
{ 
    write(socket, vehicle.GetData(), vehicle.GetDataSize()); 
} 

Vehicle* ReceiveVehicle(int socket) 
{ 
    VehicleType type; 
    size_t dataSize; 

    read(socket, &type, sizeof(VehicleType)); 
    read(socket, &dataSize, sizeof(size_t)); 

    BYTE* data = new BYTE[dataSize]; 
    read(socket, &data, dataSize); 

    Vehicle v* = CreateVehicle(type, dataSize, data); 
    delete[] data; 

    return v; 
} 

// The factory method. 
Vehicle* CreateVehicle(VehicleType type, size_t dataSize, void* data) 
{ 
    switch(type) 
    { 
     case VehicleType_Car: return new Car(data); 
     case VehicleType_Bike: return new Bike(data); 
    } 

    return 0; 
} 

당신도 버퍼를 사용하여 일부 메모리 단편화를 피할 수 소켓을 자전거의 _ 데이터 구조로 읽습니다.

항상 그렇듯이 사용중인 패턴을 읽는 것이 좋습니다. 여기에 Factory Method Pattern에 관한 위키 백과 문서가 있습니다.

Boost Serialization 라이브러리도 확인해야합니다. 이는 엔디안과 워드 크기가 다른 시스템에서 데이터를 직렬화하는 데 도움이됩니다. 위에서 설명한 방법은 매우 간단하며 그런 식으로 다루지 않습니다.

+0

이 줄의 의미 "자전거 (static_cast (data) -> 이름)" 작동합니까? 정적 포인터가 char 포인터를 struct 포인터로 바꿀 수 있습니까? 우리는 BikeData가 구조체의 첫 번째로 "이름"변수와 다른 변수를 지적 할 수 있습니까? – metdos

+0

static_cast (void * x)은 void * 인 x를 T *로 캐스트합니다. 정적 캐스팅은 이전 C 스타일 "(T *) x"캐스팅과 같습니다. 위의 코드는 약간 안전하지 않습니다. 이상적으로 당신은 생성자를 private으로 두어야하고 Bike 클래스는 공장 클래스의 친구가되어야합니다. 그렇게하면 공장 만 개인 자전거 (void * 데이터) 생성자를 호출 할 수 있습니다. 또는, 생성자를 Bike (BikeData * 데이터)로 변경하여 void *에서의 변환이 Bike 생성자 외부에서 수행되도록 할 수 있습니다. – orj

0

"매개 변수가있는 팩토리 메서드"는 deserialize의 매우 강력한 방법입니다. 개체를 가져 와서 해당 데이터를 기준으로 deserialize를 수행하십시오.

+0

"매개 변수화 된 팩토리 메서드"에 대해 좀 더 설명 할 수 있습니까? – metdos

+0

약간의 효과가있을 수 있지만 GoF Design Patterns 책에 사용 된 이름입니다. "Factory Method"는 직접 생성 할 수없는 클래스 (private 생성자)에 사용됩니다. "매개 변수화 된 팩토리 메소드"를 사용하여 원하는 서브 클래스를 지정하는 매개 변수를 전달합니다. – stefaanv

+0

그냥 수정 : GoF Design Patterns 책에 따르면. "팩토리 메서드"는 주로 추상 응용 프로그램에서 파생 된 응용 프로그램을 가져 오는 데 사용되며 파생 된 "CreateObject"메서드를 사용하여 개체를 만듭니다. 실제로 이것은 많이 사용되지 않으며 "Factory Method"는 이제 http://en.wikipedia.org/wiki/Factory_method_pattern의 예제에서 사용 된 "매개 변수화 된 팩토리 메서드"를 의미하는 데 더 많이 사용됩니다. UML은 여전히 ​​원래의 의미를 보여줍니다.) – stefaanv

0

올바르게 이해하면 현재 구현이 오류가 발생하기 쉽고 양쪽에 프로세서 아키텍처와 같은 많은 느슨한 부분이 있으므로 IMHO, CORBA가 더 적합합니다. 또는 적어도 일부 표기법을 사용하여 데이터를 전송할 수 있습니다. 전송 후 Prototype 및 Visitor 패턴을 제안하여 객체를 만들고 초기화 할 수 있습니다. 희망이 도움이됩니다.

+0

"롤 - 더 - 자신"솔루션의 팬은별로 없지만 "CORBA는 귀하의 사례에 더 잘 어울립니다"라는 귀하의 평가에 대해서는 동의하지 않습니다. 프로세서 아키텍처가 문제가 될 수 있다고 판단하기 위해 실제 상황에 대해 무엇을 알고 있습니까? 또는 프로젝트의 크기가 CORBA가 아닌 매우 가벼운 접근법을 허용한다는 것인가? –

+0

@ p.marino 그러면 질문을 자세히 설명해야합니다. 이것들이 제 답변의 코멘트입니다. 또한, 프로토 타입 및 방문자 패턴 접근에 초점을 맞추고 있지 않습니다. –

+0

나는 원래 포스터가 아니며, 아마도 나를 metdos와 혼동하고 있습니까? –

0

정확한 요구 사항에 따라 패턴 지향 소프트웨어 아키텍처 도서에서 찾을 수있는 Object-Request-Broker 패턴을 사용하는 것이 좋습니다.

관련 문제