본문 바로가기
디자인패턴

상속(Inheritance)과 구성(Composition)

by 임동무 2023. 2. 10.

디자인 패턴을 학습하면서 구성이라는 단어를 마주했다. 

처음에는 ~ has A 정도로 그저 이해하고 넘어갔었다. 

하지만 읽으면 읽을수록 상속과 구성이라는 단어가 계속해서 번갈아서 언급되니 이 단어에 대한 정확한 이해가 있어야 문맥을 정확하게 이해할 수 있었다.

 

- 상속의 장점?

먼저 우리가 상속을 사용하는 이유는 다양하다. 

코드의 재사용, 변화에 대한 유연성 등 여러 장점들을 생각하고 사용하는데

실상은 상속을 정확하게 이해하고, 이를 바탕으로 적절하게 사용해야 이런 상속의 장점들을 발현시킬 수 있으며 그렇지 않은 경우 오히려 강한 결합을 가진 즉, 코드의 유연성을 해치게 된다.

 

- 상속이란

상속은 부모 클래스(상위 클래스 혹은 슈퍼 클래스) 와 자식 클래스(하위 클래스) 관계를 만들어 자식 클래스는 부모클래스의 멤버를 상속받아 사용할 수 있도록 하는 것을 말한다.

public class People {
    String name;
    int age;

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

class Worker extends People {
    String workPlace;

    public Worker(String name, int age, String workPlace) {
        super(name, age);
        this.workPlace = workPlace;
    }

    public String getWorkPlace() {
        return workPlace;
    }
}

위의 코드에서 People 이는 부모 클래스, Worker 는 자식 클래스로 상속하는 관계를 볼 수 있다. 

여기서 Worker 클래스에서 부모클래스의 getter 메서드들 또한 사용할 수 있다.

 

하지만 이런 상속관계는 추상화를 깨뜨린다 즉, 컴파일 단계에서 정적으로 결정되어 버린다.

만약 Worker 라는 객체 또한 고용주와 고용인으로 나누어진 상황을 생각해보자. 그 상황에서 String 타입의 workPlace 가 문자열이 아니라, enum 으로 직접 직장을 만들어서 설정하는 방식으로 바꾼다고 한다. 

 

그렇다면 우리는 Worker 객체 뿐만 아니라, Worker 객체를 상속하는 고용주 고용인에서도 해당 부분에 대한 코드 수정이 필요하다. 코드들의 결합력이 강하기 때문에 이런 상속관계가 많아지면 많아질수록 코드수정은 힘들어지고 결국 변화에 대처하기 힘들어진다. (유연성이 떨어진다.)


 

그렇기에 이를 해결하기 위한 방식이 Composition, 구성 방식이다.

 

구성이란 위의 코드를 다음과 같이 수정하는 것이다.

public class People {
    String name;
    int age;

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

class Worker {
    People people;
    String workPlace;

    public String getWorkPlace() {
        return workPlace;
    }
}

위의 코드를 보면 상속하는 관계 ( ~ is A ) 가 아닌 포함/구성 하는 방식 ( ~ has A ) 방식으로 바뀐 것을 확인 할 수 있다.

이 방식에서 중요한 점은 people 에 대한 기능이 필요한 경우 메서드를 호출하는 방식을 사용한다는 것이다. 

이를 사용하면 

1. 캡슐화를 유지할 수 있다.

2. 앞서 가정한 상황에서 Worker 에 대한 코드만 수정하고 고용인 고용주라는 개념이 도입되어도 workPlace 의 형식이 바뀌는 것과는 무관해진다. 

즉, 코드의 결합력이 약해지고 더 유연하게 코드를 작성할 수 있다.

 

 

 

물론 상속의 단점을 구상으로 해결할 수 있지만, 그렇다고 해서 구상만 사용하라는 것은 아니다. 상속을 정확하게 사용하면 상속이라는 기능은 강력한 무기가 될 수 있다. 하지만 그러기 위해서는 상속에 대해서 더 공부하고 적용해보며 바람직한 상속관계에 대해서 많이 생각해봐야겠다는 생각이 든다.

'디자인패턴' 카테고리의 다른 글

디자인패턴 - 옵저버 패턴 (Observer Pattern)  (0) 2023.02.06
디자인패턴과 전략패턴  (0) 2022.12.28

댓글