ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • '오브젝트' 책 보고 공부하기 - ⑩ 상속과 코드 재사용
    JAVA공부/JAVA 2023. 6. 19. 22:24

    1) 상속과 중복코드

    중복코드는 우리를 주저하게 만들뿐만 아니라 동료들을 의심하게 만든다. 

    두 코드가 중복인지, 중복을 없애도 괜찮을지 등등 여러가지 사안이 떠오르기 때문이다.

     

    DRY 원칙

    중복여부를 판단하는 기준은 변경이다. 요구사항이 변경되었을 때 두 코드를 모두 수정해야 한다면 이 코드는 중복이다.

    중복코드를 결정하는 기준은 코드의 모양이 아니다.

    DRY원칙은 Don't Repeat Yourself 간단히 말해 동일한 지식을 중복하지 말라는 것이다.

    한번, 단 한번 원칙 혹은 단일 지점 제어 원칙이라고 부른다.

     

    예제로 보여주는 NightlyDiscountPhone, Phone의 상속관계는 새로운 로직을 추가하기 위해 부모, 자식 메서드 모두 

    수정이 필요했다. 자식 클래스가 부모 클래스에 너무 강하게 결합되어있어 생기는 문제이다.

    자식 클래스의 메서드안에서 super참조를 통해 부모 클래스 메서드를 직접 호출하는 경우  두 클래스는 강결합이 된다.

    super 호출을 제거할 수 있는 방법을 찾아 결합도를 낮추자.

     

     


     

    2) 취약한 기반 클래스 문제

     

    부모클래스에 변경에 의해 자식 클래스가 영향받는 현상을 취약한 기반 클래스 문제라고 부른다.

    상속은 관계를 추가할수록 기능을 확장하는데 도움이 되지만 동시에 시스템의 결합도가 높아진다.

    상속은 코드 재사용을 위해 캡슐화의 장점을 희석시키고 구현에대한 결합도를 높여 객체지향이 가진 장점을 반감시킨다.

     

    변경만이 상속이 가지는 문제가 아니다. 불필요한 인터페이스를 상속받게 되면서,

    잘못된 인터페이스 사용시 오류를 범할 수 있다.

    상속받은 부모클래스의 메서드가 자식클래스의 내부 구조에 대한 규칙을 깨트릴 수 있다. (사용,반환타입의 문제)

     

    메서드가 오버라이딩을 사용하는 경우에도 문제가 발생한다. 자식클래스가 부모클래스의 메서드를 오버라이딩 하고

    부모 메서드를 호출하는 과정에서 또 다시  자식클래스의 메서드가 호출되는 경우 효과가 2번나타날 수 있다.

    자식 클래스가 부모클래스의 메서드를 오버라이딩할 경우 부모 클래스가 자신의 메서드를 사용하는 방법에

    자식 클래스가 결합될 수 있다.

     

    부모의 구현내용에 의해 자식 구현내용이 변경되어야 할 수도 있다. 비즈니스상 엮여있는 경우가 그런 경우이다.

    클래스를 상속하면 결합도로 인해 자식클래스와 부모 클래스의 구현을 영원히 변경하지 않거나,

    자식 클래스와 부모 클래스를 동시에 변경하거나 둘중 하나를 선택할 수 있다.

     


     

    3) Phone 다시 살펴보기

     

    취약한 기반 클래스 문제에서도 어느 정도 해결할 수 있는 방법은 추상화의 의존하는 방법이다.

    두가지 원칙이 존재하는데,

    1. 두 메서드가 유사하게 보이면 차이점을 메서드를 추출하여, 두 메서드를 동일한 형태로 보이도록 만들 수 있다.

    2. 부모 클래스의 코드를 하위로 내리지말고 자식 클래스의 코드를 상위로 올려라. 자식 클래스의 추상적인 메서드를

    부모의 추상 메서드로 만들면 재사용성과 응집도 측면에서 더 뛰어나다.

     

    차이점을 메서드를 추출하라는 것은 변하는것을 변하지 않는것과 분리하라, 변하는 부분을 찾고 캡슐화하라의 의미를

    메서드 단위에서 작용시킨 것이다.

    공통(중복) 부분을 부모 클래스로 올리고, 차이가 있는 부분을 부모클래스의 추상 메서드로 만들어 자식클래스에

    맞춰서 구현이 변경될 수 있도록 하자. 이때 protected를 선언하면 자식 클래스에서만 오버라이딩할 수 있다.

     

    추상화에 의존함으로써 확장에도 열려있게 되고 의존성 역전 원칙도 준수 할 수 있게된다.

    (추상메서드의 의존할 수 있음)

     

    이 방법은 객체의 행동 변경에 대해서는 좋은 방식이 될 수 있으나, 인스턴스 변수가 추가되는 경우는 다르다.

    인스턴스 변수가 추가되는 자식들의 구현된 추상메서드에 관해 영향을 미치기 때문에, 결국 수정이 필요하게된다.

    그러나, 인스턴스 초기화 로직을 변경하는 것보다 객체의 핵심 로직 중복을 막는것이 더 중요하다.

    객체 생성 로직은 유연하게 대응할 수 있는 부분이 존재하기 때문이다.

    사실 상속으로 인한 클래스 사이의 결합을 피할 수 있는 방법은 없기때문에 활용을 하자면 추상메서드를 이용하자.

     

     


     

    4) 차이에 의한 프로그래밍

     

    기존 코드와 다른 부분만을 추가함으로써 애플리케이션의 기능을 확장하는 방법을 차이에의한 프로그래밍이라 한다.

    중복을 제거하기 위해서 코드를 재사용 가능한 단위로 분해하고 재구성하자. 아주 잘게 분해하면 재사용성이 높아진다.

     

    상속은 코드 중복을 제거하는 강력한 도구지만, 맹목적으로 상속을 사용하는 것이 앞에서 말했듯 많이 위험하다.

    잘못 사용할 경우에 돌아오는 피해는 배 이상이되어버리기 때문이다. (결합도가 높기때문)

     

    다음장에서 공부할 '협력'으로 상속의 단점을 피하면서 코드 재사용을 잘 할 수 있게 해보자.

     

Designed by Tistory.