goal
객체지향 설계 원칙 (객체지향 설계 5원칙)의 SOLID원칙을 이해한다.
1 ] 객체지향 설계의 5원칙, SOLID원칙
명칭 | 번역 |
SRP (The Single Responsibility Principle) |
단일 책임 원칙 |
OCP (The Open Closed Principle) |
개방 폐쇄 원칙 |
LSP (The Liskov Substitution Principle) |
리스코프 치환 원칙 |
ISP (The Interface Segregation Principle) |
인터페이스 분리 원칙 |
DIP (The Dependency Inversion Principle) | 의존관계 역전 원칙 |
1. SRP (단일 책임 원칙)
[1] 개념
- 모든 클래스는
하나의 책임
만 가지며, 그책임
을 완전히 캡슐화해야 함을 말함 - 클래스가 제공하는 모든 기능은 이
책임
과 주의깊게 부합해야 한다.- 예로, 보고서 출력/편집의 모듈을 만든다고 가정한다.
- 보고서 편집의 사유는 두 가지로 변경될 수 있다.
- 첫 번째 : 보고서의
형식이 바뀐 경우
- 두 번째 : 보고서의
내용이 바뀐 경우
- 첫 번째 : 보고서의
- 분류된 각각의 것이 편집 목적의
책임
을 져야하기 때문에 클래스나 모듈로 나누어야 한다. - 다른 시기에 다른 이유로 변경되어야하는 두 가지를 묶는 것은 나쁜 설계일 수 있다.
[2] 한 클래스를 한 관심사에 집중하도록 유지하는 것이 중요한 이유
- 클래스가 더욱 단단해지기 때문이다.
- [1]개념의 예를 가져와 더 살펴본다면, 편집 과정에 변경이 일어나면, 같은 클래스의 일부로 있는 출력 코드가 망가질 위험이 대단히 높아진다.
2. OCP (개방 폐쇄 원칙)
[1] 개념
- 모든 클래스가 열려있음과 닫혀있음이 확실해야한다.
- 열린 경우 : 클래스의 확장이 자유로워야 한다.
- 닫힌 경우 : 프로그램의 변경이 일어나더라도 핵심 기능을 구현한 코드(핵심 기능을 담은 클래스)는 변화가 일어나면 안 된다.
3. LSP (리스코프 치환 원칙) - 가장 애매하고 오해하기 쉬움
참고자료 : [SOLID] 리스코프 치환 원칙(LSP)란?, https://steady-coding.tistory.com/383, 제이온(J.ON)
[1] 개념
상위 타입의 객체
를하위 타입의 객체
로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.- 다른말로, 'B가 A의 자식 타입이면 부모 타입인 A객체는 자식 타입인 B로 치환해도, 작동에 문제가 없다.'
- 개발자의 관점으로,
- 부모 클래스 타입인 A를 사용하는 기존의 프로그램 코드가 자식 클래스 B로 대입 시켰을 때도,
- 문제 없이 작동하도록 하기 위해서, 자식 클래스는 부모 클래스가 따르던 계약 사항을 자식도 따라야 한다.
예시코드 "정사각형은 직사각형이 될 수 있지만 직사각형은 정사각형이 될 수 없습니다."
- Rectangle.java <직각사각형>
public class Rectangle {
private int width;
private int height;
public void setWidth(final int width){
this.width = width;
}
public void setHeight(final int height) {
this.height = height;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}
- Square.java <직각사각형을 상속받아 만든 정사각형>
public class Square extends Rectangle {
@Override
public void setWidth(final int width) {
super.setWidth(width);
super.setHeight(width);
}
@Override
public void setHeight(final int height) {
super.setWidth(height);
super.setHeight(height);
}
}
※ 의미 :: 정사각형은 세변의 길이가 같아야 하므로, Rectangle클래스의 width와 height를 재정의함
- 다른 클래스에서 Retangle클래스를 이용
# 메소드의 의미 : "직사각형의 세로 길이는 가로보다 길어야한다."
public void increaseHeight (final Rectangle rectangle) {
if (rectangle.getHeight() <= rectangle.getWidth()) {
rectangle.setHeight(rectangle.getWidth() + 1);
}
}
※ 의미 : rectangle객체의 세로 <= 가로
인 경우, 객체의 세로에 기존 가로의 길이 + 1
을 하는 코드
- 정사각형이 아닌 직사각형에 대해서는 위 메소드가 올바르게 작동한다.
- new Rectangle이 객체로 들어간 경우
- 정사각형의 길이는
가로 == 세로
이므로 위 메소드를 실행하면 가로와 세로의 길이가 모두 1씩 증가한다.- new Square이 객체로 들어간 경우
- 즉,
''메소드 실행 후, 직사각형의 길이는 가로보다 세로가 길어야 한다''
라는 가정이 깨지게 되는 것 - 이를 해결하기 위해서
instanceof
를 통해 타입 비교를 실시한다.
- increaseHeight메소드의 수정
public void increaseHeight (final Rectangle rectangle) {
if (rectangle instanceof Square) {
throw new IllegalStateException();
}
if (rectangle.getHeight() <= rectangle.getWidth()) {
rectangle.setHeight(rectangle.getWidth() + 1);
}
}
하지만, 이 코드는 OCP
에 어긋나는 코드이다. 왜냐하면 increaseHeight()가 확장에는 열려 있지 않기 때문이다.
따라서, Square 클래스는 Rectangle클래스를 상속받으면 안 된다.
LSP 정리
상위 타입의 객체
를하위 타입의 객체
로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.를 구현 클래스에 대입하여 이야기해보면- 상위 타입의 클래스 : Rectangle클래스의 setHeight()메소드의 명세는 아래와 같다.
- 매개변수로 값이 들어오면 세로의 길이가 변한다
- 가로의 길이는 변하지 않는다
- 하위 타입의 클래스 : Square클래스는 setHeight()메소드의 명세는 아래와 같다.
- 매개변수로 값이 들어오면 세로의 길이가 변한다
- 매개변수로 값이 들어오면 가로의 길이도 변한다
- 상위 타입의 클래스 : Rectangle클래스의 setHeight()메소드의 명세는 아래와 같다.
- 즉, 상위 타입에서 정한
명세
를 하위 타입에서도 그대로지킬 수 있을 때
상속을 진행해야한다. - 혹은, 상속을 하게 된다면 해당 메소드를 정의하지 않아야 한다.
4. ISP (인터페이스 분리 원칙)
- 클라이언트가 자신이 이용하지 않는 메소드에 의존하지 않아야 한다는 원칙이다.
- 큰 덩어리의 인터페이스들을 구체적이고 작은 단위들로 분리시켜 클라이언트들이 꼭 필요한 메소드들만 이용할 수 있게 하는 것
- 작은 단위로 나뉜 인터페이스는
역할 인터페이스
라고도 한다.
5. DIP (의존관계 역전 원칙)
참고자료 : Spring + java 이론 :) 의존성 주입의 의미와 개선 코드, https://kimeuncheol.tistory.com/42, 내자료
'Spring > Spring 이론' 카테고리의 다른 글
Spring 이론 + SIA 그룹스터디(2장) :) Spring에서 사용하는 Template의 종류와 WAR, JAR에 따른 Template 채택 (0) | 2022.05.14 |
---|---|
spring 이론 :) Jar(java Archive)와 War(Web Application Archive) (0) | 2022.05.03 |
Spring 이론 :) Spring Web Layer, DAO, DTO (0) | 2022.04.25 |
Spring 이론 :) Spring Container, Spring 핵심 프로그래밍 모델 3가지, Spring API가 제공하는 것과 특징 (0) | 2022.04.25 |
Spring + java 이론 :) 의존성 주입의 의미와 개선 코드 (0) | 2022.04.04 |