sol 개발 블로그 로고
Published on

객체지향 프로그래밍 익히기 (2)

Authors
  • avatar
    Name
    Chan Sol OH
    Twitter

목차

개요

SOLID는 High Cohesion(높은 응집도), Loose Coupling(낮은 결합도)를 목표로 하는 객체지향 설계원칙이다.

S = Single Responsibility (단일책임)

하나의 모듈은 하나의 책임을 가진다.

예를 들어 상품 삭제 모듈이 있다고 가정했을 때, 그 삭제 모듈 안에 상품 컨텐츠 삭제, 상품 옵션 삭제, 그리고 상품 상세 내용 삭제 코드가 모두 들어가 있을 때, 그 중 한 부분을 삭제하려고 하면 다른 관계 없는 부분까지 영향이 가기 때문에 유지보수 측면에 불이익이 있다.

그래서 단일책임이라는 원칙 하에 각 삭제 코드를 다른 모듈로 분리하는 것이 유지보수 측면에서 더 유리하다.

O = Open-Closed (개방폐쇄)

확장에 열려있지만, 수정에 닫혀있다.

예를 들어 자동차라는 클래스를 상속하는 슈퍼카, 범퍼카, 그리고 쓰레기차 클래스가 있다. 범퍼카는 자동차의 속성에서 부딪혀도 괜찮은 속성을 추가했다. 이처럼 범퍼카는 자동차의 속성을 확장할 수 있다.

그리고 만약 범퍼카의 속성을 바꾼다고 자동차의 속성을 바꾸게 되면 자동차를 상속한 다른 클래스 (슈퍼카, 쓰레기차)가 예상할 수 없는 영향을 받게된다. 이러한 상황은 유지보수 측면에서 불리하다. 조상 클래스는 최대한 변화 없이 자손 클래스에게 속성을 나눠줘야하기 때문에 조상 클래스는 수정할 수 없다.

L = Liscov Substitution (리스코프 치환)

자녀 클래스는 상속 시 부모 클래스의 가정을 충족

리스코프 치환 원칙은 다형성과 관련된 부분이다. 다형성은 조상 클래스의 참조변수로 자손 클래스의 인스턴스를 참조할 수 있는 특징이다. 조상 클래스의 참조변수로 자손 클래스의 인스턴스를 사용할 수 있다는 것은 조상 클래스가 들어가서 정상적으로 동작하는 부분에 자손 클래스가 들어가서 정상적으로 동작할 수 있어야하는 것을 의미한다.

개발자는 인터페이스를 보고 작업하는데 만약 자손 클래스가 인터페이스의 메서드를 온전히 구현하지 않는다면 개발과 유지보수 측면에서 문제가 생길 수 있다. 따라서 자손 클래스는 조상 클래스를 온전히 대체할 수 있어야한다.

I = Interface Segregation (인터페이스 분리)

인터페이스 내에 메소드 최소화

인터페이스 분리는 리스코프 치환과 단일책임이 연결된 부분이 있다. 만약 한 인터페이스에 과도하게 많은 역할을 부여해서 그 자손 클래스가 인터페이스를 온전히 구현하지 못한다면 리스코프 치환을 충족시키지 못한다. 그리고 과도하게 많은 역할을 가진 인터페이스가 있다면 이를 구현한 클래스는 단일책임 원칙을 위배한 것으로 볼 수 있다.

그렇기에 인터페이스를 역할 단위로 분리하고 메서드를 최소화해야한다.

D = Dependency Inversion (의존성 역전)

인터페이스로 구현체를 연결

OOP에서 포함관계로 큰 클래스를 작은 클래스 여러개를 모아서 만들면 유지보수 측면에 좋다고 설명했다. 하지만 그 작은 클래스 중 하나의 로직을 수정하면 큰 클래스도 직접적으로 영향을 받게된다. 이런 영향을 줄이기 위해 의존성 역전을 통해 인터페이스로 작은 클래스의 입,출력 값의 형태를 보장할 수 있고 이는 각 클래스의 역할 분리에 도움되며 유지보수에 이점이 있다.

정리

SOLID를 사용하면 클래스를 사용할 때 인터페이스로 감싸서 사용하고 조금 큰 클래스는 쪼개서 작은 클래스 여러개로 분리하며 한 클래스를 상속하면 자손 클래스는 조상 클래스를 대체할 수 있지만, 수정할 수 없게된다.