SRP 단일 책임 원칙
Single Responsibility Principle
•
한 클래스는 하나의 책임만 가져야 한다.
•
하나의 책임이라는 것은 모호하다.
◦
책임은 클 수 있고, 작을 수도 있다.
◦
문맥과 상황에 따라 다르다.
•
중요한 기준은 변경이다. 변경이 있을 때 파급 효과가 적을수록 단일 책임 원칙을 잘 따른 것이다.
EX: UI 변경, 객체의 생성과 사용을 분리.
OCP 개방-폐쇄 원칙
Open/Closed Principle
•
소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
코드를 변경하지 않으면서 확장을 어떻게 해야하는가? 정답은 다형성이다.
//Car car = new K3("K3 자동차");
Car car = new Sonata("쏘나타");
Java
복사
뭔가 이상하다. 분명 변경에는 닫혀있어야한다고 했는데, K3에서 Sonata로 변경한데 있어 주석을 통해 코드를 변경했다. 다형성을 사용했는데도 코드를 변경함으로써 OCP 원칙을 위반하고 말았다.
그럼 어떻게 해야할까? 이를 해결하기위해 객체 생성, 관계수립을 해주는 설정자가 필요하다.
LSP 리스코프 치환 원칙
Liskov substitution principle
•
프로그램의 객체는 프로그램의 정확성을 깨트리지 않으면서 하위 타입의 인스턴스로 바꿀수 있어야 한다.
⇒ 특정 인터페이스(Car)에서 전진기능(go)이 있다고 할때 구현체에서는 전진이라는 책임을 다해야지 특정 구현체가 전진기능을 수행할 때 전진이 아닌 후진이나 우회전등을 한다면 LSP 원칙에 위배된다.
•
컴파일단계에서 생기는 문제는 아니지만 클라이언트는 특정 역할을 사용할 때 해당 기능에 대해 기대하는 책임이 있기에 해당 책임을 수행할것을 믿고 동작하는것이기에 이 원칙이 필요하다.
ISP 인터페이스 분리 원칙
Interface segregation principle
클라이언트가 자신이 이용하지 않는 메서드에 의존하지 않아야 한다는 원칙으로
범용 인터페이스 하나보다는 특정 목적을 위한 인터페이스 여러개가 있는것이 좋다. 그럼으로써 클라이언트에서는 꼭 필요한 메서드들만 이용할 수 있게 된다. 이런 작은 단위들을 역할 인터페이스라고도 부른다.
public interface Car {
void driving(DirectionType direction);
void fix(FixType type);
}
Java
복사
위처럼 자동차 인터페이스가 있다고 할 때 운전을 통합하는 driving과 fix처럼 범용적인 인터페이스 두개보다는
public interface Car {
void go();
void left();
void stop();
void right();
void fixHandle();
void fixEngine();
}
Java
복사
이렇게 특정 기능을 수행하는 작은 단위로 분리하는게 내부 의존성을 약화시켜 리팩토링, 수정, 재배포를 쉽게 한다.
DIP 의존관계 역전 원칙
Dependency inversion principle
프로그래머는 추상화에 의존해야지, 구체화에 의존하면 안된다.
운전자는 운전을 하기 위해서는 자동차 역할에 대해 알아야지 K3에 대해서 알아야 하는게 아니다.
즉, 구현 클래스가 아닌 인터페이스에 의존하라는 의미이다.