객체지향 설계 원칙

1 minute to read

Single Responsibility Principle

모든 클래스는 하나의 책임만을 가지며, 클래스는 그 책임을 완전히 캡슐화해야 함을 말함. 클래스가 제공하는 모든 기능은 이 책임과 깊게 부합해야 한다.

Open-close Principle

확장에 대해 열려 있음

모듈을 확장할 수 있어야 한다.

수정에 대해 닫혀 있음

모듈의 확장이 그 모듈의 소스코드나 바이너리 코드의 변경을 초대하지 않는다.

구현 방법

추상화 기반의 클래스를 만들면, 이 개체는 수정에 닫혀있지만, 필요에 의해 파생 클래스를 구현하는 방식으로 확장에는 열려 있을 수 있다.

하지만 모든 상황에서 완벽한 코드를 작성하기는 불가능하기 때문에 경험을 통해 최적의 설계를 해야 한다.

Liskov Substitution Principle

서브타입은 언제나 자신의 기반타입으로 교체할 수 있어야 한다.

즉, 자식 클래스는 최소한 자신의 부모 크래스에서 가능한 행위는 모두 수행할 수 있어야 한다.

대표적인 예시로 정사각형과 직사각형의 구현이 있다.

Interface Sergregation Principle

클라이언트 자신이 이용하지 않는 인터페이스에 의존하면 안된다.

큰 덩어리의 인터페이스를 구체적이고 작은 단위로 분리시켜 필요한 기능들만 이요할 수 있게 한다.

내부 의존성이 약화되어 리팩토링, 수정, 재배포를 쉽게 할 수 있다.

Dependency Inversion Property

나쁜 디자인

  1. 모든 변경마다 많은 다른 부분에 영향을 미쳐 변경 자체가 어렵다.
  2. 변경 작업을 할 때 예상치 못한 다른 부분이 망가진다.
  3. 현재의 어플리케이션에서 분리할 수 없기 때문에 다른 어플리케이션에서 재사용 하기가 매우 어렵다.

위의 예시들의 공통점은 모두 의존성이 강하다는 것이다.

의존 관계 역전의 원칙

하이 레벨 모듈은 로우레벨 모듈에 의존해서는 안된다. 둘 다 추상에 의존해야 한다.

추상은 상세를 의존해서는 안된다. 상세는 추상을 의존해야 한다.

간단하게 버튼과 램프를 통해 예시를 들어보면, 버튼이 직접적으로 램프에 불을 켜라, 불을 꺼라 라는 명령을 내리도록 설계를 하면 의존 관계 역전의 원칙을 위반합니다.(추상이 상세를 자동적으로 의존)

추상 버튼과 추상 버튼 클라이언트를 작성하고, 버튼 구현체는 추상 버튼을 상속받아 구현하는 형태, 램프는 추상 버튼 클라이언트를 상속받아 구현하는 형태를 가지게 하면 구현된 버튼은 램프에 대해서 몰라도 됩니다.

결론은 구조적 디자인에서 발생하던 로워 레벨 모듈의 변경이 하이 레벨 모듈의 변경을 요구하는 관계를 끊고, 추상을 매개체로 관계를 최대한 느슨하게 만들자는 것입니다.

참조