(C++ : Design-pattern) abstract class, interface, coupling

Posted by : at

Category : Cpp   Design-pattern


abstract class

추상 클래스는 반드시 특정 함수를 만들라고 강제하고 싶을때 사용된다.

class Shape     // 순수 가상함수를 포함할 경우 추상 클래스라 한다.
{
public:
    virtual void Draw() = 0;        // 순수 가상함수 : 구현부가 없다.
};

int main()
{
    Shape s;        // error - 추상 클래스는 객체를 생성할 수 없다.
    Shape* p;       // ok - 단, 포인터 정도는 만들 수 있다.
}
class Rect : public Shape
{
public:
    virtual void Draw() {}      // 구현부를 제공하면 추상 클래스가 아니다.
};

int main()
{
    Rect r;     // ok
}

interface & coupling

#include <iostream>
using namespace std;

class Camera
{
public:
    void take() { cout << "take picture" << endl; }
};

class People
{
public:
    void useCamera(Camera* p) { p->take(); }
};

int main()
{
    People p;
    Camera c;
    p.useCamera(&c);
}

새로운 카메라가 나왔다고 가정해보자.

class HDCamera
{
public:
    void take() { cout << "HD take picture" << endl; }
};

class People
{
public:
    void useCamera(Camera* p) { p->take(); }
    void useCamera(HDCamera* p) { p->take(); }
};

int main()
{
    People p;
    Camera c;
    p.useCamera(&c);

    HDCamera hd;
    p.useCamera(&hd);       // 이게 뭔 지랄?
}

좀 더 객체지향적으로 만들어보자
멋진말로 OCP(Open Close Principle) - 기능 확장에는 열려있고, 코드 수정에는 닫혀 있어야 한다.(새로운 기능이 추가되어도 기존 코드의 수정이 없도록 만들어야 한다는 말.)

문제의 원인은 People과 Camera가 useCamera를 통해 강한결합으로 연결되어 있다.
이 부분을 약한결합으로 변경하면 될 것.

#include <iostream>
using namespace std;

// 규칙 : 모든 카메라는 아래 클래스로부터 파생되어야 한다.(=모든 카메라는 아래 인터페이스를 구현해야 한다.)
struct ICamera
{
public:
    virtual void take() = 0;
    virtual ~ICamera() {}
};

class Camera : public ICamera
{
public:
    virtual void take() override { cout << "take picture" << endl; }
};

class HDCamera : public ICamera
{
public:
    virtual void take() override { cout << "HD take picture" << endl; }
};

class People
{
public:
    void useCamera(ICamera* p) { p->take(); }
};

int main()
{
    People p;
    Camera c;
    HDCamera hd;

    p.useCamera(&c);        // ok
    p.useCamera(&hd);       // ok
}
  • 이렇게 구현하는 구조를 약한 결합이라 한다.
    • 객체가 서로 상호 작용 하지만, 서로에 대해 잘 알지 못 하는 것.
    • 교체/확장 가능한 유연한 디자인
    • 객체는 상호 간에 인터페이스를 통해서 통신 해야 한다.

About Taehyung Kim

안녕하세요? 8년차 현업 C++ 개발자 김태형이라고 합니다. 😁 C/C++을 사랑하며 다양한 사람과의 협업을 즐깁니다. ☕ 꾸준한 자기개발을 미덕이라 생각하며 노력중이며, 제가 얻은 지식을 홈페이지에 정리 중입니다. 좀 더 상세한 제 이력서 혹은 Private 프로젝트 접근 권한을 원하신다면 메일주세요. 😎

Star
Useful Links