단일 책임 원칙(Single Responsibility Principle)
개념
Single Responsibility Principle(단일 책임 원칙)
은 객체는 하나의 책임만을 지녀야 한다는 법칙이다.- 여러 책임을 동시에 가지는 객체는 처음에 코드를 짤 때는 편하다.
- 하지만 코드가 복잡해질수록 에러가 날 확률도 높아지며 직관적으로 코드를 이해하기 어려워진다.
- 따라서 객체를 설계하기 전 책임을 확실하게 부여하는 것이 중요하다.
AS-IS
1 |
|
TO-BE
1 |
|
개방 폐쇄 원칙(Open Closed Principle)
개념
Open Closed Principle(개방 폐쇄 원칙)
은 객체의 확장에는 열려있고, 수정에는 닫혀있게 해야 한다는 법칙이다.- 기존의 코드를 변경하지 않으면서 기능을 추가할 수 있도록 설계되어야 한다.
- OCP에서 중요한 부분은 요구사항이 변경되었을 때 코드의 변경되어야 할 부분과 그렇지 않아야 할 부분이 명확하게 구분되어 있어야 한다는 점이다.
- 보통 이를 지키기 위해선 인터페이스나 추상 클래스를 통해 추상화시키고 이를 상속, 구현하게 된다.
- 새로운 기능을 추가한다고 할 때, 다형성을 사용해 기존 코드를 변경하지 않으면서 (변경에 닫혀있음), 추상 클래스를 상속받아 쉽게 코드를 추가할 수 있다.(확장에 열려있음)
AS-IS
1 |
|
TO-BE
1 |
|
리스코브 치환 원칙(Liskov Substitution Principle)
개념
Liskov Substitution Principle(리스코브 치환 원칙)
은 부모 객체의 역할은 자식 객체도 할 수 있어야 된다는 원칙이다.- B 객체가 A 객체의 자식이라면 B 객체의 타입을 A로 바꾸더라도 작동에 문제가 없어야 한다.
- 상위 타입에서 정한 명세를 하위 타입에서도 그대로 지킬 수 있을 때 상속을 해야 한다.
- 일반적으로
Liskov Substitution Principle
이 지켜지지 않으면Open Closed Principle
을 위반하게 된다.
위반한 사례 1
1 |
|
위반한 사례2
1 |
|
인터페이스 분리 원칙(Interface Segregation Principle)
개념
Interface Segregation Principle(인터페이스 분리 원칙)
은 클라이언트가 자신이 이용하지 않는 메서드는 의존하지 않아야 한다는 원칙이다.- SOLID의 1 원칙인
Single Responsibility Principle
은 객체가 하나의 책임만을 가져야 한다고 했는데, 여기서는 인터페이스(혹은 추상 클래스)가 하나의 책임만을 가져야 한다고 보면 된다. - 인터페이스를 책임에 맞게 잘 쪼개둔다면, 클라이언트 입장에서는 필요한 역할만 구현(혹은 상속)하여 사용할 수 있다.
AS-IS
1 |
|
TO-BE
1 |
|
의존성 역전 원칙(Dependency Inversion Principle)
개념
Dependency Inversion Principle(의존성 역전 원칙)
은 의존성을 항상 고수준으로 향하게 하여 예측할 수 없는 의존성의 변화를 줄이자는 원칙이다.- 일반적으로 의존성을 가지는 대상이 변경되면 의존하는 주체도 함께 변경된다.
- 만약 자주 바뀌는 구현체(저수준)를 의존하게 된다면 코드의 변경이 잦을 것이며, 버그와 사이드 이펙트가 날 확률이 높아진다.
- 이때 코드가 덜 바뀌는 인터페이스나 추상 클래스(고수준)를 의존한다면 상대적으로 안정적인 코드를 작성할 수 있다.
- 고수준은 상위 수준 + 추상화되어 있는 개념이다.
- 일반적으로 잘 변하지 않는 특성을 가진다.
- 코드 개념에서 고수준은 인터페이스, 추상클래스 등을 예로 들 수 있다.
- 저수준은 추상화된 개념을 구체적으로 구현하는 개념이다.
- 인터페이스, 추상클래스를 구현하는 구현체(클래스)나 함수 등 실제 동작에 관여하는 코드라고 보면 된다.
기본 코드
1 |
|
AS-IS
1 |
|
- 만약 App에서 다른 데이터베이스를 사용하고 싶다면, 코드를 직접 변경해야 한다.
- 또한 App을 테스트하는 코드를 작성할 때도 의존성이 강하게 결합되어 테스트가 쉽지 않다.
TO-BE
1. 의존성 역전
1 |
|
2. 의존성 주입과 함께
- 일반적으로 의존성 역전을 하면서 의존성 주입을 함께 사용한다.
- 의존성 주입을 사용하게 되면 객체의 생성을 외부에 맡기게 된다.
- 그러면 해당 클래스는 외부 의존성에 조금 더 자유롭게 되며 테스트를 작성할 때도 용이하다.
1 |
|
- 의존성 주입(DI)을 해주기 위해선 결국 이를 사용하는 클라이언트에서 의존성들을 일일이 넣어줘야 한다.
- 만약 잘못 코드를 작성하면 의존성 관계가 복잡해질 수 있다.
- 그래서 보통 의존성 주입을 별도로 관리해주는 라이브러리나 프레임워크를 사용한다.