드디어 solid에 대한 개념을 정리 하게 되었다.

객체 지향의설계의 5원칙 집대성

로버트 C. 마틴이 2000년대 초반 객체 지향 프로그래밍 및 설계의 다섯가지 기본원칙으로 제시함 .

응집도(high Cohesion)는 높이고, 결합도 (Loose Coupling)는 낮추라는 고전 원칙을 객체 지향의 관점에서 재정립한 것.

결합도와 응집도
결합도는 모듈간의 상호 의존 정도로서 결합도가 낮으면 모듈간의 상호 의존성이 줄어들어 객체의 재사용이나 수정, 유지 보수가 용이하다.
응집도는 하나의 모듈내부에 존재하는 구성요소들으 ㅣ기능적 관련성으로 응집도가 높은 모듈은 하나의 책임에 집중하고 독립성이 높아져 재사용이나 기능의 수정, 유지보수가 용이하다.

객체지향 SW 설계의 원칙 ① 개방-폐쇄 원칙

객체지향 SW 설계의 원칙 ② 사례연구, 단일 책임 원칙

객체지향 SW 설계의 원칙 ③ 인터페이스 분리의 원칙

객체지향 SW 설계의 원칙 ④ 리스코프 치환 원칙

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

어떤 클래스를 변경해야하는 이유는 오직 하나 뿐이어야 한다. - 로버트 C 마틴

책에서는 여자친구, 어머니, 직장상사, 소대장 등 다양한 사람들이 의존하는 남자친구로 설명을한다.

여러 사람들이 의존하는 남자친구는 피곤할수 밖에 없다.

여자친구- 남자친구, 어머니 - 아들, 직장상사 - 사원, 소대장 - 소대원

이렇게 역할을 분리하라는 것이 단일 책임 원칙이다.

장점 :

  • 이전에는 남자친구라는 이름으로 의존되고있는 것을 관리 하였는데, 역할을 분할하니 클래스 이름도 이해하기가 좋다.
  • 여자친구와 이별을 하더라도 어머니-아들, 직장상사- 사원, 소대장 - 소대원 에게는 영향을 받지 않는다.
  • 단일 책임 원칙은 속성, 메서드, 패키지, 모듈, 컴포넌트, 프레임워크 등에도 적요할 수 있는 개념이다.

잘못된 예

예시1) 남자와 여자를 사람으로 나타내는 클래스가 있다. 남자는 군대를 가야해서 사람이라는 클래스에 군번이라는 필드를 넣게 된다면? 여자는 군대를 가지 않지만 군번이라는 필드 에 값은 할당되지 않아도 계속 가지고 있어야하는 찜찜함이 있다.

이럴때는 남자, 여자가 공통적인 부분들을 사람이라는 클래스에 두고 남자, 여자 클래스에서 상속을 받아, 차이점을 구현하면 해결할수 있다.

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

소프트 웨어 인티티(클래스, 모듈, 함수) 등 확장에 대해서는 열려 있어야 하지만 변경에 대해서는 닫혀 있어야한다 - 로버트 c 마틴

자신의 확장에는 열려있고, 주변의 변화에 대해서는 닫혀 있어야한다

예제

한 운전자가 수동의 마티즈를 운전할때 창문 수동 개방, 기어 수동 조작에 대한 메서드를 사용 했는데, 나중에 쏘나타로 차를 변경하게 되면서 창문 수동 개방, 기어 자동 조작 에 대한 메서드를 사용하게 된다면 ?

운전자가 운전에 영향을 받아야하는가?를 물어보면서 상위 클래스 또는 인터페이스를 중간에 둠으로써, 다양한 자동차가 생긴다고 해도 객체 지향 세계의 운전습관에는 영향을 받지 않게 된다.

자동차가 생긴다고 하는것은 자동차 입장에서는 자신의 확장에 개방이 되어있고, 운전자입장에서는 주변의 변화에 폐쇄 되어있는 것이다.

또 다른 예를 들면, JDBC를 사용하는 클라이언트는 데이터베이스가 오라클에서 MySQL 로 바뀌더라도 Connection을 설정 하는 부분외에는 따로 수정하는 부분이 없다. 데이터베이스는 교체가 가능하므로 확장에 개방이 되어있고, 자바 애플리케이션은 데이터베이스라고 하는 주변의 변화에 닫혀 있다는 말이다.

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

서브 타입은 언제나 자신의 기반 타입(base type) 으로 교체 할 수 있어야한다. - 로버트 c 마틴

상속은 조직도나 계층도가 아닌 분류도가 되어야한다!

  • 하위 클래스 is a kind of 상위 클래스 - 하위 분류는 상위 분류의 한 종류이다.

  • 구현 클래스 is able to 인터페이스 - 구현분류는 인터페이스 할 수 있어야 한다.

    인터페이스 할수 있어야한다라는 표현은 각 인터페이스 명에 따라 쉽게 이해할 수 있다.
    AutoCloseable - 자동으로 닫힐 수 있어야한다.
    Appendable - 덧붙일 수 있어야한다.
    Cloneable - 복제할 수 있어야한다.
    Runnable - 실행 할 수 있어야한다.

상위 클래스의 객체 참조 변수에는 하위 클래스의 인스턴스를 할당할 수 있다.

부모 자식관계의 잘못된 예를 보면

아버지 춘향이 = new 딸();

춘향이는 아버지형의 객체 참조변수 이기에 아버지객체가 가진 행위를 할 수 있어야하는데, 딸인 춘향이는 아버지의 역할을 할수가 없다.

아래와 같은 경우에는 동물 - 펭귄 구조(분류도)는 리스코프 치환 원칙을 만족 한다라고 할 수 있다.

동물 뽀로로 = new 펭귄();

정리하면 하위 클래스의 인스턴스는 상위형 객체 참조 변수에 대입해 상위 클래스의 인스턴스 역할을 하는데 문제가 없어야한다.

계층도/조직도 경우가 아니라, 분류도인 경우 하위에 존재하는 것들은 상위에 있는 것들의 역할을 하는데 전혀문제가 없다.

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

클라이언트는 자신이 사용하지 않는 메서드에 의존 관계를 맺으면 안 된다. - 로버트 C. 마틴

이전의 SRP를 설명할때 남자친구는 여자친구, 어머니, 직장상사, 소대장이 의존하고있는 남자친구에 대해 역할을 분리하는것이 좋다고 이야기를 했는데, 다른 방법으로는 ISP를 사용하여 나타낼 수 있다.

여자친구, 어머니, 직장상사, 소대장이 의존하고있는 남자친구의 역할의 메서드를 포함하는 인터페이스를 생성하고, 남자친구를 implements 해서 각 역할에 맞는 클래스를 생성하는것이 인터페이스 분할 원칙의 핵심이다.

인터페이스에 메서드를 정의하고,정의된 메서드들을 각 개별의 객체의 클래스에스 구현하는 것 이 핵심이라고 생각함

결론적으로 SRP, ISP는 같은 문제에 대한 두가지 다른 해결책이라고 볼수 있다.

프로젝트의 요구사항과 설계자의 취향에 따라 단일 책임 원칙이나 인터페이스분할 원칙중 하나를 선택해서 설계할 수 있다.

상위 클래스는 풍성할 수록 좋고, 인터페이스는 작을 수록 좋다.

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

"고차원 모듈은 저차원 모듈에 의존하면 안된다. 이 두 모듈 모두 다른 추상화 된 것에 의존해야 한다.","추상화된 것은 구체적인 것에 의존하면 안된다. 구체적인 것이 추상화된 것에 의존해야한다."," 자주 변경되는 구체(Concrete) 클래스에 의존하지 마라" - 로버트 마틴

자동차 타이어에는 여러 종류가 있다. 스노우 타이어, 일반 타이어, 광폭타이어

자동차 타이어가 교체 될때마다 타이어클래스들을 변경 해야하지만, 상위에 인터페이스로 타이어라는 추상 객체를 만들어 상속하여 사용한다면, 타이어가 변경되도

자신보다 변하기 쉬운 것에 의존하던 것을 추상화된 인터페이스나 상위 클래스를 두어번 하기쉬운 것의 변화에 영향 받지 않게 하는것이 의존 역전의 원칙

상위 클래스일 수록 인터페이스일수록, 추상클래스일수록 변하지 않는 가능성이 높기에 하위 클래스나 구체 클래스가 아닌 상위 클래스, 인터페이스, 추상클래스를 통해 의존하라는것이 바로 의존 역전의 원칙

'ProgramLanguage > Java' 카테고리의 다른 글

JVM 튜닝  (0) 2020.02.10
Lambda_Expression(2)  (0) 2020.01.25
Java 와 객체 지향  (0) 2019.12.03
Java jar파일 만들기  (0) 2019.08.04
인터페이스와 추상클래스  (0) 2019.06.10

+ Recent posts