Post

객체 지향 5대 원칙 - SOLID

wikipedia - SOLID (객체 지향 설계)

단일 책임의 원칙 (SRP, Single Responsibility Principle)

한 클래스는 하나의 책임만 가져야 한다.

  • 어떤 코드를 어디에 두어야 하는가?를 결정할 때 많이 도움이 되는 원칙.
  • 그 클래스를 변경해야 하는 상황,원인,이유가 딱 한가지 인지’ 를 보면, 단일 책임으로 제대로 분리되었는지를 확인할 수 있다.
  • 클래스는 그 책임을 완전히 캡슐화해서 제공해야 한다.
    • 어떤 클래스에 변경이 발생했을 때, 변경이 발생했다는 그 이유만으로 다른 클래스에도 변경이 발생해야하는 상황이 있어서는 안된다는 것이다. (어떤 사유로 내부 로직을 변경했다면, 거기서 끝나야 한다는 의미)
    • 지키지 않는 경우 3.8 산탄총 수술 문제가 발생한다.
  • 아무튼 가장 기본이 되는 원칙은 ‘함께 변경할 대상을 한데 모으는 것 ‘ 이다.

인터페이스 분리 원칙 (ISP, Interface Segregation Principle)

클라이언트 코드는 자신이 사용하지 않는 메서드에 의존하지 않아야 한다.

  • 이를 위해서는 프로그램을 작은 단위의 인터페이스들로 구성해야 한다.
    • 그래야 클라이언트가 자신이 필요한 인터페이스로 객체를 참조하여 사용할 수 있으니까. (= 필요 없는 메서드 의존 X)
  • 그래서,특정 클라이언트를 위한 (작은) 인터페이스 여러 개가 범용 인터페이스 하나 보다 낫다.

의존성 역전 원칙 (DIP, Dependency Inversion Principle)

일반적인 의존성 설정 방향과 반대로, 역방향 의존성을 가지도록 해서 상위 모듈이 하위 모듈에서 완전히 독립 할 수 있도록 한다.

  • 상위 모듈이 하위 모듈을 use 하는 일반적인 구조에서, 상위 모듈은 하위 모듈을 참조 (의존) 한다.
  • 이 때 상위 모듈이 인터페이스 없이 하위 모듈을 직접 참조하면, 상위 모듈은 하위 모듈의 구현에 의존하게 된다.

  • 반면 DIP를 따라 하위모듈이 상위모듈에서 필요로 하는 기능을 참조(의존) 하게끔 설계하게 된다면, 상위 모듈은 하위 모듈의 구현이 어떻게 되어 있든 그로부터 완전히 자유롭다.

  • 이처럼 상위 계층이 하위 계층에 의존하는 전통적인 의존 관계를 반전 시킴으로써, 상위 계층이 하위 계층의 구현으로부터 독립하기 위한 원칙이기 때문에, 의존성 역전 원칙 이라는 이름을 가지고 있다.
  • 꼭 클래스 단위에 국한된 얘기는 아니고, 모듈이나 계층, 설계 전반적으로도 적용할 수 있는 원칙이다.

개방 폐쇄의 원칙 (OCP, Open/Closed Principle)

소프트웨어 구성요소(모듈, 클래스, …)는
확장에는 열려 있어야 하고(쉬운 확장),
변경에는 닫혀 있어야 한다.(내부 구조를 변경할 필요 X)

  • 예를 들어, 어떤 라이브러리가 인터페이스를 참조하고 있다면, 그 인터페이스를 구현한 클래스를 내가 직접 만들 수 있다.
  • 이런 설계가 확장에는 열려 있고, 내부 구조는 변경할 필요 없는 닫혀있는 구조다.

리스코프 치환의 원칙 (LSP, Liskov Substitution Principle)

  • 넓게는 다형성, 즉 “상위 타입 변수를 사용하는 곳에 하위 타입을 넘겨도 문제 없이 동작 할 수 있어야 한다 .” 의미라고 보면 된다.
  • 단순히 타입 치환 뿐만 아니라, 프로그램의 정확성을 깨뜨리지 않기 위한 몇 가지 제약조건 이 있다.
    • 예시 : 직사각형을 상속한 정사각형
    • 정사각형은 직사각형이다. (true) 그러나 정사각형이 직사각형을 상속하는 상황을 생각해보면…
      • 정사각형의 width, height setter는 어떻게 될 것 같은가?
      • setter를 고려했을 때, 정사각형 인스턴스가 직사각형 변수에 담기면 어떻게 되는가?
      • 직사각형을 파라미터로 받아 높이를 늘려주는 메서드에 정사각형을 넘기면 어떻게 되는가?
    • 정사각형은 개념적으로는 직사각형이지만, 직사각형을 상속하면 LSP 위반 한다는 것을 알 수 있다.
      • 단, 정사각형, 직사각형이 불변 객체라면 이런 문제가 발생하지 않으므로 LSP 위반이 아니다.
  • 자식클래스에서 부모클래스의 메서드를 override 할 때, 더 느슨한 가시성 접근자로 open하는 것은 가능하지만, 더 엄격한 가시성 접근자를 사용하여 close하는 것은 불가능한 것은 이 때문이다.
    • https://stackoverflow.com/questions/17510152/why-cant-we-assign-weaker-privilege-in-subclass
    • 만약 자식클래스에서 더 엄격한 가시성 접근자를 써서 닫을 수 있다고 가정하면…
      • SuperClass obj = new SubClass()처럼 담아, java obj.부모는_public_자식은_private() 호출하게 되면?
      • 실제 인스턴스는 자식클래스이기 때문에 private인 자식 클래스의 메서드가 호출되어야 한다. => private이지만 외부 호출이 가능하게 되므로 모순.
This post is licensed under CC BY 4.0 by the author.