개발관련 도서/객체지향과 디자인 패턴

1-4 재사용 : 상속보다는 조립을 지향

prden 2021. 6. 2. 11:38

재사용 측면에서

1. 상속의 단점 : (변경의 유연함의 측면에서 치명적인 단점을 갖는다.)

1) 상위 클래스 변경의 어려움 :

상위 클래스를 변경할 경우 하위 클래스에 영향을 주게 된다. 따라서 클래스 계층도가 커질수록 상위 클래스를 변경하는 것은 점점 어려워진다. 

 

2) 클래스 수의 불필요한 증가 : 

예를 들어 Storage 클래스를 상속받아 CompressedStorage 클래스와 EncryptedStorage 클래스를 추가했다 가정하자. 이 상황에서 압축을 먼저 하고 암호화하는 저장소가 필요하다면 CompressedEncryptedStorage를 추가해야 하고, 암호화를 먼저 하고 압축을 해야 하는 저장소가 필요하면 EncryptedCompressedStorage를 추가해야 한다. 또한, 추가적으로 캐시를 제공하는 저장소가 필요하고, 암호화된 저장소에 캐시를 적용하려면 CaheableStorage를 만든 후 추가적으로 CacheableEncryptedStorage를 구현해야 한다. 이처럼 상속을 통한 기능 재사용을 할 경우 불필요하게 클래스의 수가 증가한다. 

 

3) 상속의 오용가능성이있다.

 

2. 조립을 이용

1) 객체지향 언어에서 객체 조립은 보통 필드에서 다른 객체를 참조하는 방식으로 구현한다. 

조립을 이용하여 앞서 상속을 통해 발생했던 문제들(클래스 수 증식, 상속의 오용 가능성 등)이 해결된다. 또한, 조립방식의 다른 장점은 런타임 시에 조립 대상 객체를 교체할 수 있다. 상속을 통한 기능을 구현했을 경우 1. 소스코드에서 다른 클래스를 상속받도록 변경한 후 2. 소스코드를 재 컴파일한 후에 3. 다시 배포하여야 하지만, 조립을 사용하면 런타임에 교체가 가능하다. 

 

2) 조립을 통한 재사용의 단점 : 상대적으로 상속보다 런타임 구조가 복잡해지며, 상속보다 구현이 어렵다는 단점이 있지만, 장기적 관점에서 구현/구조의 복잡함보다 변경의 유연함을 확보하는 데서 오는 장점이 더 크기 때문에 기능을 재사용해야 할 경우 상속보다는 조립하는 방식을 먼저 고려하자.

 

3) 위임

 위임이란 내가 할 일을 다른 객체에게 넘긴다는 의미로, 보통 조립 방식을 이용해서 위임을 구현한다. 

보통 위임은 조립과 마찬가지로 요청을 위임할 객체를 필드로 연결하지만, 객체를 새로 생성해서 요청을 전달해도 된다. 

 

※연산 속도가 매우 중요한 시스템에서는 많은 위임 코드가 성능에 문제를 일으킬 수 있지만, 대부분의 경우에는 위임으로 인해 발생하는 미세한 성능 저하보다 위임을 통해서 얻을 수 있는 유연함/재사용의 장점이 크다.

 

3. 그러면 상속은 언제 사용하냐?(재사용이 아닌 기능의 확장)

상속은 1. 재사용이라는 관점이 아닌 기능의 확장이라는 관점에서 적용해야 한다. 또한 2. 추가적으로 명확한 IS-A관계가 성립되어야 한다. 

다시 말해 명확한 IS-A관계에서 점진적으로 상위 클래스의 기능을 확장해 나갈 때 사용할 수 있는 것이다. 그럼에도, 클래스의 개수가 불필요하게 증가하는 문제가 발생하거나, 상위 클래스의 변경이 어려워지는 등 상위 클래스를 상속받을 때의 단점이 발생하면, 조립으로 전환하는 것을 고려해야 한다.