포스트

깨지기 쉬운 베이스 클래스 문제(Fragile Base Class Problem)

Fragile/Brittle Base class Problem


  • 깨지기 쉬운 베이스 클래스 문제, 깨지기 쉬운 기반 클래스 문제, 취약한 기반 클래스 문제 등으로 불림
  • 부모 클래스가 변경되었을 때 자식 클래스에 어떤 영향을 줄 지 모르는 현상
  • 베이스 클래스의 인터페이스 변경이 파생 클래스에 예상치 못한 문제를 발생시키는 문제

The fragile base class problem is a fundamental architectural problem of object-oriented programming systems where base classes super classes are considered “fragile” because seemingly safe modifications to a base class, when inherited by the derived classes, may cause the derived classes to malfunction.

  • 베이스 클래스의 메서드를 개별적으로 검사해서는 베이스 클래스의 변경이 안전한지 여부를 확인할 수 없음
  • 상속과 관련된 일반적인 문제로, 상속을 지원하는 대부분의 언어에서 발생함

대표적인 예시

  1. 불필요한 인터페이스 상속 문제
  2. 메서드 오버라이딩 오작용 문제
  3. 부모클래스와 자식클래스 동시 수정 문제

    예시 - 메서드 오버라이딩 오작용 문제


    • 위 예시 중, 두번째 예시

초기 상태

1
2
3
4
5
6
7
8
9
10
11
12
class Base {
    int counter = 0;

	public:
	    virtual void inc1() { counter++; } 
	    virtual void inc2() { counter++; }
};

class Derived : public Base {
	public:
	    void inc2() override { inc1(); }
};
  • 베이스 클래스는 카운터를 증가시키는 inc1(), inc2()를 가지고있다
  • 파생 클래스는 베이스 클래스를 상속받아 inc2를 재정의 했다
    • Dervied.inc2()를 호출하면 Base::inc1()이 호출되어 카운터가 1 증가한다

Fagile Base class problem 발생

  • 그러나 베이스 클래스의 inc1()을 변경한 경우, fragile base class 문제가 발생한다
1
2
3
4
5
6
7
8
9
10
11
12
13
class Base {
    int counter = 0;

	public:
	    virtual void inc1() { inc2(); } // 변경됨.  
	    virtual void inc2() { ++counter; }
};

class Derived : public Base {
	public:
	    void inc2() override { inc1(); }
};
  • Base 클래스에서 inc1()는 호출해도 문제가 없으나, Derived 클래스는 문제가 발생함
  • inc2()를 재정의 했기 때문에 Dervied::inc2()Base::inc1()을 호출하고
    Base::inc1()Derived::inc2()를 호출하여 무한 재귀가 발생함!

해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
class Base {
    int counter = 0;

public:
    virtual void inc1() { Base::inc2(); } // <-- now safe 
    virtual void inc2() { ++counter; }
};

class Derived : public Base {
public:
    void inc2() override { inc1(); }
};
  • inc1()을 수정할 때, 명시적으로 Base::inc2()를 호출한다고 작성하면, 무한 재귀가 발생하지 않는다
  • 추상화 클래스템플릿등의 기법을 활용하여 문제를 예방할 수 있음.
  • java에서는 final 키워드를 통해 상속을 금지시킬 수 있다고 함

참조 :
Fragile base class

Can the fragile base class problem occur in C++?

오브젝트 10장 상속과 코드 재사용

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.