나는 인터페이스를 '발견'했고 그것들을 사랑하기 시작했다. 인터페이스의 장점은 계약이라는 것입니다. 계약을 이행하는 모든 개체는 해당 인터페이스가 필요한 모든 곳에서 사용할 수 있습니다.
인터페이스의 문제점은 기본 구현을 할 수 없다는 것입니다. 이는 평범한 속성에 대한 고통이며 DRY를 물리칩니다. 이것은 구현과 시스템이 분리 된 상태를 유지하기 때문에 좋습니다. 한편 상속은 더 긴밀한 결합을 유지하며 캡슐화를 깨뜨릴 수있는 가능성이 있습니다.
사례 1 (개인 구성원의 상속, 우수한 캡슐화, 밀접하게 결합)
class Employee
{
int money_earned;
string name;
public:
void do_work(){money_earned++;};
string get_name(return name;);
};
class Nurse : public Employee:
{
public:
void do_work(/*do work. Oops, can't update money_earned. Unaware I have to call superclass' do_work()*/);
};
void HireNurse(Nurse *n)
{
nurse->do_work();
)
사례 2 (인터페이스 만)
class IEmployee
{
virtual void do_work()=0;
virtual string get_name()=0;
};
//class Nurse implements IEmployee.
//But now, for each employee, must repeat the get_name() implementation,
//and add a name member string, which breaks DRY.
사례 3 : (두 세계에서 가장 좋은가?)
사례 1과 유사합니다 . 그러나 (가설 적으로) C ++에서 순수한 가상 메소드를 제외 하고 메소드를 대체 할 수 없다고 상상해보십시오 .
따라서 사례 1 에서 do_work ()를 재정의하면 컴파일 타임 오류가 발생합니다. 이 문제를 해결하기 위해 do_work ()를 순수 가상으로 설정하고 별도의 메소드 increment_money_earned ()를 추가합니다. 예로서:
class Employee
{
int money_earned;
string name;
public:
virtual void do_work()=0;
void increment_money_earned(money_earned++;);
string get_name(return name;);
};
class Nurse : public Employee:
{
public:
void do_work(/*do work*/ increment_money_earned(); ); .
};
그러나 이것조차도 문제가 있습니다. 3 개월 후 Joe Coder가 Doctor Employee를 작성하지만 do_work ()에서 incremental_money_earned ()를 호출하는 것을 잊어 버린 경우 어떻게해야합니까?
질문:
가 케이스 (3) 우수 사례 1 ? '더 나은 캡슐화'또는 '더 느슨하게 결합 된'또는 다른 이유 때문입니까?
가 사례 3은 우수 사례 2 는 DRY을 준수하기 때문에?