2015-01-07 2 views
2

문제는 다음과 같습니다. 개체 ID로 쿼리 할 수있는 일종의 컨테이너 (예 :지도)를 캡슐화하는 클래스가 있습니다. 클래스는 또한 객체에 속하는 추가 데이터 (즉, 행렬)를 보유하는 두 번째 컨테이너를 캡슐화합니다. 내 클래스의 클라이언트가 객체를 조회 여부 그는 또한 추가 데이터를 가지고 싶어 처리 여부를 결정할 수있는 가능성을 가지고 있어야하는 것은 이런 식으로, 즉 반환 : 클라이언트가 추가 데이터를 요청선택적 매개 변수 + 선택적 반환 값을 처리하는 방법

ObjectData objData; 
Object obj = myClass.getObject(objectID, &objData); 

그러나 경우 만 쿼리 한 객체에는 추가 데이터가 연결되어 있지 않으므로 클라이언트가이를 알 수 있어야합니다. 나는. 내 함수는 다음과 같이 작동하는 경우 :

Object MyClass::getObject(ObjectID oID, ObjectData* objData) 
{ 
    // ... 
    if(objData && this->hasObjectData(oID)) 
     objData = this->getObjectData(oID); 
} 

을하고 클라이언트가 위의 방법으로 그것을 호출 GetObject 함수는 쿼리 객체가 그것으로 추가 데이터를하지 않고 그대로 전달 objData 포인터를 떠날 것이라는 점을 인식하고 있습니다. 그런 다음 클라이언트는 기본 생성 ObjectData 객체를 사용하여 자신을 찾습니다.이 객체가 기본 생성되었는지 또는 getObject 함수에 의해 매개 변수 반환 값으로 반환되는지 여부는 알 수 없습니다.

내 머리 위에 나는 힙에 데이터를 할당하는 것과 같은 추악한 솔루션 만 생각할 수 있습니다. 따라서 사용자는 nullpointers를 다시 가져 오거나 어떻게 든 함수 호출에 플래그를 추가 할 수 있습니다. 아마도 더 나은 디자인은 objectData를 완전히 따로 따로 질의하는 것이 겠지만 위의 방법은 멋지고 쉽습니다. 그래서 여전히 이런 식으로 우아하게 해결할 수 있을지 궁금합니다.

+1

[부스트 옵션] (http://www.boost.org/doc/libs/1_57_0/libs/optional/doc/html/index.html) 사용은 어떻습니까? –

+0

힙 할당/널 포인터 솔루션이 특히 추악하다고 생각하지 않습니다. 스마트 포인터를 사용하여 더 안전하게 만들 수 있습니다. 결국, 나는 두 번째 해결책을 선호 할 것이다. 'getObjectData'를 변경해, ObjectData 에의 참조를 취해, 데이터가 기입 해 졌는지 어떠했는지를 나타내는 bool를 돌려 줄 수도 있습니다. 이것은 조금 더 간결합니다. – Daerst

+0

필자의 코드는 작성한대로 사용자가 원하는 것을 수행한다고 생각하지 않습니다. 추가 데이터 또는 포인터의 복사본을 제공 하시겠습니까? 복사본을 원한다고 가정하면'* objData = this-> getObjectData (oID);를 읽어야합니다. 포인터를 제공하려면'ObjectData * '와 같은 것을 전달해야합니다. –

답변

0
getObject(objectID, &objData); 

이렇게하면 getObject을 사용하면 두 가지 책임을 부여하게됩니다. 첫 번째는 객체를 준비하고 두 번째로 추가 정보를로드 할 수 있는지 확인하는 것입니다. 이것을 두 부분으로 나누는 것이 좋습니다 (방법).

obj = getObject(objectID); // get the object based on definite 
          // info i.e 1st container. 
if(obj.isMatrixValid) 
    obj.setMatrixData(); 

여기서는 책임을 두 가지 방법으로 구분했습니다. 그러나 한 가지 단점은 생성 후 object 업데이트를 기억해야한다는 것입니다.

0

아마 더 나은 디자인은 완전히 별도로

예 ObjectData에를 조회하는 것입니다.

getObject에는 너무 많은 책임이 있습니다.

하지만 위의 좋은 쉬울 것이다

클라이언트는 실제로 다음 추가 객체 데이터에 대해 상관하지 않는다이 좋네요 쉽게 경우 : 대한 다음

Object obj = myClass.getObject(objectID) 

을 objectData에 대한 별도의 쿼리에는 몇 가지 옵션이 있습니다. 쿼리하기 전에 objectData가 있는지 클라이언트가 확인하도록 할 수 있습니다.

if (myClass.hasObjectData()) { 
    ObjectData data = myClass.getObjectData(); 
} 

또는 포인터를 반환 할 수 있습니다. 클라이언트가 ObjectData을 소유 할 필요가없는 경우 그냥 원시 포인터를 반환 할 수 있습니다.

std::unique_ptr<ObjectData> data = myClass.getObjectData(); 
if (data) { 
    // do something with data... 
} 

아니면 Boost.Optional을 사용할 수있는 유사한 방법 : 클라이언트가 내가 생각하지 않는 ObjectData을 소유 할 필요가있는 경우 스마트 포인터를 힙에 할당 및 반환에 대한 추한 것도있다.

추가 objectData가 없으면 Null Object pattern을 고려하고 NullObjectData 개체를 반환 할 수 있습니다.