2014-11-12 2 views
2

내가인터페이스 클래스의 파생 클래스를 선택하려면 코드를 숨기시겠습니까?

class car { 
    public: 
    virtual void move(double x, double y) = 0; 
    // etc etc 
}; 

같은 인터페이스 클래스와

class model8556 : virtual public car { 
    private: 
    void move(double x, double y) { 
     // ... 
    } 
    // etc etc 
}; 

같은 파생 클래스를 많이 가지고 있고 좋은 방법은 거기에있다

car* myCar;  
switch (foo) { 
    case 1: myCar = new model3434(); break; 
    case 2: myCar = new model8295(); break; 
    // etc 
} 

를 통해 모델을 선택 가정 수 있습니다 스위치 코드를 숨기고 car 클래스 자체로 옮길 수 있습니까? car 주위에 또 다른 클래스 (?)를 래핑 할 수 있습니다 (또는 전역 함수로 전환 코드를 이동 하시겠습니까?).하지만 좀 더 우아한 것이 있는지 궁금합니다.

도움을 주시면 감사하겠습니다.

답변

3

스위치 코드를 별도의 함수로 추출하여 코드 주위에서 중복되는 것을 피하는 것이 좋습니다.

클래스의 정적 함수에 넣을 수 있습니다. 어떤 사람들은 Car 자체에 넣을 것이지만, 유도 된 클래스에 Car을 연결하고 순환 종속성에주의해야하므로 추천하지는 않을 것입니다. 어떤 사람들은 그것을 자신의 클래스에서 정적 함수로 가질 것입니다. 이는 때로 Simple Factory으로 설명됩니다. 나는 그것이 포인터를 소유하기위한 좋은 방법입니다하지만 정상적으로 생각하는

#include <memory> 

class Car { 
    public: 
    virtual ~Car() {} 
    virtual void move(double x, double y) = 0; 
}; 

class Model3434 : public Car { 
    public: 
    void move(double, double) override { } 
}; 

class Model8295 : public Car { 
    public: 
    void move(double, double) override { } 
}; 

std::unique_ptr<Car> createCar(int foo) { 
    switch (foo) { 
     case 1: return std::make_unique<Model3434>(); 
     case 2: return std::make_unique<Model8295>(); 
     default: return nullptr; 
    } 
} 

int main() { 
    auto car1 = createCar(1); 
    auto car2 = createCar(2); 
} 

내가 대신 원시 포인터의 unique_ptr을 사용했습니다 :

그러나 C의

는 ++ 비 멤버 함수를 가지고 아무 문제가 없다 대략 동일하다.

정수 대신 공장의 함수에 열거 형을 전달하는 것이 좋습니다.

또한 글로벌 네임 스페이스를 오염시키지 않으려면 이름 공간에서 공장 기능을 사용하는 것이 좋습니다. Car과 동일한 네임 스페이스를 사용하는 것이 좋습니다.

0

factory pattern을 입력하고 create() (또는 무엇이든)을 모델 유형 (아마도 enum?)으로 제공하는 것처럼 보입니다.

// .hpp 

class factory 
{ 
    public: 
     static car* create(int model); 
} 

// .cpp 

car* create(int model) 
{ 
    switch(model) 
    { 
     // decide which car to make 
    } 
} 

: 그것은 그대로 작동하지 않을 경우 코드가 조금이라도 내 사과 있도록 테스트되지 않았습니다.

+1

"공장"패턴과 같은 것은 실제로 까다롭지 않습니다. 인식 된 패턴은 [Factory Method] (http://en.wikipedia.org/wiki/Factory_method_pattern) 패턴과 [Abstract Factory] (http://en.wikipedia.org/wiki/Abstract_factory_pattern) 패턴입니다. 당신이 말하는 것은 "[단순한 공장] (http://my.safaribooksonline.com/book/software-engineering-and-development/patterns/0596007124/4dot-the-factory-pattern-baking-) with-oo-goodness/simple_factory_defined_html) "이디엄. –

+1

@ChrisDrew, 질문을하는 사람의 이익을 위해 항상 패턴 특유의 미세한 점에 대해 토론하고 있습니다. '공장 패턴'이라는 단어가 자신의 시간에 자신의 인터넷 검색을 허용한다는 것을 알고 있습니다. . –

+0

'factory :: create'는 틀림없이 어쨌든 클래스에있는 이유는 무엇입니까? – doctorlove

1

정적 논리로 생성 논리를 숨기면 충분합니다.

static car* CreateInstance(int id) 
{ 
    case(id) 
     // etc etc 
} 

당신이 관심이 있다면, 당신이 얻을하려는 패턴은 Factory Pattern이라고하며 생성 논리가 훨씬 더 복잡하게 할 때 매우 유용 할 수 있습니다.

+0

/Factpry/Factory? – doctorlove

+0

@doctorlove HURRR – BlamKiwi

1

C++에서 이러한 종류의 작업을 쉽게 수행 할 수있는 팩토리 패턴이 있습니다. 다음은

가에 대한 의사 코드입니다 : -

class CarFactory 
{ 
    public: 
     static Car* createNewCar(std::string cartype) 
     { 
     if (cartype == bmw) 
      return new BMW(); 
     if (cartypr == GALLARDO) 
      return new GALLARDO(); 
     } 
}; 

루틴을 호출에서 당신이

BMW* bmw = CarFactory::createNewCar(bmw); 

을 할 수있는 것처럼 기본적으로 동일합니다 당신의/다른 블록 경우, 유일한 점은 지역화이다 유지 보수의 어려움을 피하기 위해 한 곳에서 객체를 생성합니다.

1

공장을 car 인터페이스 안에 넣는 것을 조심해야합니다. 새 차종을 만들 때마다이 값을 변경해야합니다.

cpp 파일에서 정의를 유지하고 정적 클래스에 넣는다면 다른 답변에서 제안한 것처럼 작동합니다. 그러나 이렇게하면 차는 간접적이지만 하위 유형에 종속됩니다. 생성 함수를 자유 함수로 유지한다는 것은 이러한 단점없이 유형을 추가 할 수 있음을 의미합니다.

오히려 글로벌 네임 스페이스에 이러는 것보다, 당신은 당신의 차에있는 네임 스페이스 중 사용할 수

을 더 일반적으로, 인터페이스의 관점에서 -. car의 단일 책임은 무엇인가가 차 경우 차 창조 공장? 이것은 나에게 함수가 다른 곳에 있어야한다고 제안합니다.

관련 문제