개발/Java&Kotlin

[Java] 객체 지향 설계 5원칙 - SOLID

devhooney 2022. 8. 6. 03:23
728x90

스프링 입문을 위한 자바 객체 지향의 원리와 이해를 읽고 간단한 정리.

SOLID는 아래 5가지 원칙의 앞 글자를 따서 부르는 이름

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

(2) OCP(Open Closed Principle): 개방 폐쇠 원칙

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

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

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

 

1. SRP - 단일 책임 원칙

어떤 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 한다.

- 단일 책임 원칙은 클래스 이외에도 속성, 메소드, 패키지, 모듈, 컴포넌트, 프레임워크 등에도 적용할 수있는 개념이다.

 

- 단일 책임 원칙을 지키지 않은 메소드(예시입니다.)

 

class Dog {
    final static Boolean male = true;
    final static Boolean female = false;
    Boolean sex;
    
    void pee() {
        if (this.sex == male) {
        	// 한쪽 다리를 들고 소변
        } else {
        	// 뒷다리 두 개를 굽혀 앉은 자세로 소변
        }
    }
}

- pee() 메소드가 수컷과 암컷 강아지의 행위를 모두 구현하려고 하기 때문에 단일 책임 원칙을 지키지 않고 있다.

 

- 단일 책임 원칙을 지키도록 리팩토링

 

abstract class Dog {
    abstract void pee();
}

class MaleDog extends Dog {
    void pee() {
    	// 한쪽 다리를 들고 소변
    }
}

class FemaleDog extends Dog {
    void pee() {
    	// 뒷다리 두 개로 앉은 자세로 소변
    }
}

- 이부분을 읽으면서 내가 이 원칙을 잘 지키면서 코딩을 하고 있는지 생각해봤다.(잘 모르겠다..)

 

2. OCP - 개방 폐쇄 원칙

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

 

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

- 가장 좋은 예시는 JDBC

- DB를 MySQL에서 오라클로 수정해도, Connection을 설정하는 부분 외에는 따로 수정할 필요가 없다.

- 스프링 프레임워크도 철저하게 지키고 있다.

- 이 원칙을 지키지 않을 경우, 유연성, 재사용성, 유지보수성의 장점을 잃게 된다.

 

3. LSP - 리스코프 치환 원칙

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

 

- 객체 지향의 상속은 두 가지 조건을 지켜야 한다.

(1) 하위 클래스 is a kind of 상위 클래스 - 하위 분류는 상위 분류의 한 종류다.

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

> 자동으로 닫힐 수 있어야 한다.(AutoCloseable)

> 덧붙일 수 있어야 한다.(Appendable)

> 복제할 수 있어야 한다.(Cloneable)

> 실행할 수 있어야 한다.(Runnable)

 

4. ISP - 인터페이스 분리 원칙

클라이언트는 자신이 사용하지 않는 메소드에 의존 관계를 맺으면 안된다.

 

- SRP와 ISP는 같은 문제에 대한 다른 해결책

- 인터페이스는 메소드를 외부에 제공할 때 최소한의 메소드만 제공해야 한다.

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

 

5. DIP - 의존 역전 원칙

자신보다 변하기 쉬운 것에 의존하지 마라.

 

- 상위 클래스일수록, 인터페이스일수록, 추상 클래스일수록 변하지 않을 가능성이 높다. 하위 클래스나 구체 클래스가 아닌 상위 클래스, 인터페이스, 추상 클래스를 통해 의존해야 한다.

 

6. 정리

- SRP(단일 책임 원칙): 어떤 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 한다.

- OCP(개방 폐쇄 원칙): 자신의 확장에는 열려 있고, 주변의 변화에 대해서는 닫혀 있어야 한다.

- LSP(리스코프 치환 원칙): 서브 타입은 언제나 자신의 기반 타입으로 교체할 수 있어야 한다.

- ISP(인터페이스 분리 원칙): 클라이언트는 자신이 사용하지 않는 메소드에 의존 관계를 맺으면 안된다.

- DIP(의존 역전 원칙): 자신보다 변하기 쉬운 것에 의존하면 안된다.

 

728x90