반응형
SOLID 원칙
SOLID(S.O.L.I.D)
SOLID 원칙이란?
: Rober C. Martin이 2000년에 논문에서 발표한 내용
- 이해하기 쉽고 유연하며, 유지 보수가 쉬운 SW 개발을 위한 다섯가지 SW 설계 원칙
- 단, 다섯가지 원칙을 지키다 보면 서로 상충되는 경우가 발생할 수도 있음
약어 | 원칙 | 한글 명칭 |
---|---|---|
SRP | Single Responsibility Principle | 단일 책임 원칙 |
OCP | Open-Closed Principle | 개방-폐쇄 원칙 |
LSP | Liskov Substitution Principle | 리스코프 치환 원칙 |
ISP | Interface Segregation Principle | 인터페이스 분리 원칙 |
DIP | Dependency Inversion Principle | 의존 역전 원칙 |
01. SRP 원칙
Single Responsibility Principle : 단일 책임 원칙
- 같은 이유로 변경된 것들을 모아 클래스를 만들고, 다른 이유로 변경되는 것은 분리하여 만들어라
- 클래스가 변경되어야 하는 이유는 한가지로만 구성 즉
- 즉 한 클래스에는 역할을 한가지로 구성 : 재사용상, 유지보수를 좋게 하기 위해서
- 사용자와의 관계에 대해서 고민해야 함
- 문제점
: 클래스에 기능이 너무 많으면 유지보수가 어려워짐
SRP의 예
- Book 클래스 메소드 기능 설명
- load() : 파일에서 북 정보를 읽어서 멤버 변수들에 저장
- show() : 콘솔 화면에 해당 객체의 정보를 보임
- 프로그램을 더 이상 고치지 않는다면 이대로 SRP를 지키는 설계가 될 수 있음
- 변경되는 부분들이 생긴다면 SRP를 다시 고려해봐야 함
- 만약 파일이 아니라 데이터베이스에서 책 데이터를 읽어서 저장하는 Load()함수를 만든다면?
- 콘솔 화면이 아니라 GUI화면에 책 내용을 출력하는 show()함수를 만든다면?
- SRP를 지키기 위해 위 기능에서 바꾸어야 하는 점
- Book 클래스에는 북에 대한 정보들만 저장하는 것으로 바꿈
- BookManager 클래스를 따로 만들어 load,show() 함수들을 이 클래스로 편성
- Book, BookManager는 Aggregation(집합)관계
- Aggregation(집합)관계란?
: 여러 개의 독립적인 클래스들이 하나의 클래스를 구성하는 경우로 다이아몬드 형태가 붙어있는 쪽이 전체를 나타내는 클래스이다
: 여기서는 BookManager가 Book을 소유함
02. OCP 원칙
Open-Closed Principle : 개방-폐쇄 원칙
- 기존 코드를 변경하지 않고 확장할 수 있도록 만들어야 함
- 예
- 문을 여는 프로그램을 가정
- 세 가지 종류의 문이 있음
- Sliding door
- Knob door
- Automatic Door
버전1.
1. if문으로 door의 종류에 따라 다르게 열도록 함
: 이렇게 할 경우 새로운 door가 추가되면 해당 코드 수정 불가피
if (door instanceof AutomaticDoor)
client.pressOpen(door);
else if (door instanceof KnobDoor)
client.twistOpen(door);
else if (door instanceof SlidingDoor)
client.slideOpen(door);
버전2.
- 다형성 사용
- door.open();
- 새로운 문이 추가되면 새로운 클래스를 추가하고 open() 함수를 오버라이딩
03. LSP 원칙
Liskov Substitution Principle : 리스코브 치환 원칙
- Subclasses should be substitutable for their base classes
- 자식 클래스는 부모 클래스를 대체 할 수 있어야 함
- 부모 클래스 객체 대신 자식 클래스 혹은 후손 클래스 객체를 사용했을 때 문제 없이 프로그램이 동작해야함
예: 사각형과 정사각형
- 정사각형은 사각형의 특별한 종류
- 상속으로 처리
- Rectangle Class
class Rectangle {
private int width;
private int height;
public Rectangle(int w, int h) {
width = w;
height = h;
}
public int getPerimeter() {
return 2 * (width + height);
}
public void setWidth(int w) { width = w; }
public void setHeight(int h) { height = h; }
}
- Square Class
class Square extends Rectangle {
public Square(int w) {
super(w, w);
}
public void setWidth(int w) {
super.setWidth(w);
super.setHeight(w);
}
public void setHeight(int h) {
super.setWidth(h);
super.setHeight(h);
}
}
- Main Class
class Main {
public static void main(String[] args) {
Rectangle r = new Rectangle(3, 5);
System.out.println(r.getPerimeter());
Square s = new Square(3);
System.out.println(s.getPerimeter());
r = s;
r.setWidth(3);
r.setHeight(5);
System.out.println(r.getPerimeter());
}
}
- 이 경우 Square은 Rentangle을 완벽히 대체하지 못함
- 즉, LSP을 위배하게 됨
4. ISP 원칙
Interface Segregation Principle : 인터페이스 분리 원칙
- Many client specific interfaces are better than one general purpose interface
- 여러 개 클라이언트에 필요한 기능을 가지고 있는 일반화된 인터페이스보다는 각 클라이언트에 특화되어 있는 인터페이스를 사용
- 예: (JAVA에서는 해당되지 않음)
- CDManager, BookManager, MP3Manager라는 클래스가 있을 때, DB를 로드해주는 인터페이스가 IDBloader 하나 일 경우 -> 즉, 일반화된 인터페이스 -> ISP(x)
- ICDDBloader, IMP3DBloader, IBookDBloader 로 인터페이스를 각 클래스에 특화되어있게 분리 ->ISP(o)
- 맨 첫번째 경우처럼 코드를 짤 경우 book에 대한 로드방법만 바꾸고 싶어도 IDBloader를 바꾸게 되므로 전체 클래스가 컴파일을 다시해야함
- 예: (자바에 해당되는 예)
- IDBloader 인터페이스에는 getBookName(), getCDName(), load() 두 개의 함수가 있음
- 만약 해당 인터페이스를 BookManager, CDManager가 구현해야한다면 두 클래스는 각각 getCDName(), getBookName() 서로에게 필요없는 함수까지 구현해야함 -> ISP(x)
- 이 경우, 각 클래스마다 각 클래스에 특화되어있는 인터페이스 IBookDBloader ,ICDDBloader 두 개를 구현해주는 것이 맞음
5. DIP 원칙
Dependency Inversion Principle : 의존 역전 원칙Depend upon Abstactions.
- Depend upon Abstactions. Do not depend upon Concretions
- 기능을 직접 구현한 구체 클래스 또는 함수보다는 추상 클래스나 인터페이스를 사용하는 코드를 작성하라
- 기능을 직접 구현한 클래스나 함수는 변경될 가능성이 높다
반응형
'Computer Science > 디자인패턴' 카테고리의 다른 글
[Head First Design Patterns] 04 팩토리 패턴 (0) | 2020.10.20 |
---|---|
[Head First Design Patterns] 01 디자인 패턴 소개 (0) | 2020.10.18 |
Introduction Advanced OOP (0) | 2020.10.18 |
[Head First Design Patterns] 03 데코레이터 패턴 (0) | 2020.10.07 |
[Head First Design Patterns] 02 옵저버 패턴 (0) | 2020.09.25 |