2016년 11월 15일 화요일

C++ : Class Capsulation

가끔씩 따로 관리하던 두 가지를 한꺼번에 관리해야 할 경우가 생길 수 있습니다.

이를테면 다음과 같은 애완동물호텔을 만들었는데...

class Pet : public Animal
{
public :
    virtual void Feed() = 0;
    virtual void Bath();                  // Pet bathing
};

class Dog : public Pet
{
public :
    bool Feed() override;        // Dog feed
};

class Cat : public Pet
{
public :
    bool Feed() override;        // Cat feed
}


class Hotel
{
private :
    std::list<Pet *> m_List;
public :
    ....
    void Care()
    {
        for each(Pet *pet in m_List)
        {
            pet->Feed();
            pet->Bath();
        }
    }
};

그런데 갑자기 주인이 자동차나 오토바이 보관까지 하겠다고 나선다면 어떨까요? 더구나 자동차나 오토바이는

class Car : public Machine
{
   virtual void Fual() = 0;
   void Wash();            // car washing
};

class MotorCycle : public Car
{
   void Fual() override;   // fual Gasolin
};

class Sedan : public Car
{
   void Fual() override;   // fual Gasolin
};

class Jeep : public Car
{
   void Fual() override;   // fual Desel
};

class F1Formular : public Car
{
   void Fual() override;   // fual High grade Gasolin
};

와 같이 전혀 관계없는 클래스라면 더욱 난감해집니다.

이 경우 이런 클래스들을 감싸는 클래스를 만들면 비교적 손쉽게 됩니다.

class GuestBase
{
public :
    virtual void Feed() = 0;
    virtual void Bath() = 0;
    virtual void Fuel() = 0;
};

class GuestPet : GuestBase
{
private :
    Pet *m_Pet;
public :
    virtual void Feed()
    {
        m_Pet->Feed();
    }
    virtual void Bath()
    {
        m_Pet->Bath();
    }
    virtual void Fuel()
    {
        // Do nothing
    }
};

class GuestMachine : GuestBase
{
private :
    Machine *m_Machine;
public :
    virtual void Feed()
    {
        // Do nothing
    }
    virtual void Bath()
    {
        m_Machine->Wash();
    }
    virtual void Fuel()
    {
        m_Machine->Fuel();
    }
};



class Hotel
{
private :
    std::list<GuestBase *> m_List;
public :
    ....
    void Care()
    {
        for each(Guest *guest in m_List)
        {
            guest->Feed();
            guest->Bath();
            guest->Fuel();
        }
    }
};

댓글 없음:

댓글 쓰기