객체지향의 5가지 원칙 (SOLID)
SOLID 원칙을 지키며 설계를 한다면 좋은 객체 지향 설계를 할 수 있다.
그렇다면 SOLID 원칙이 무엇인지 아래와 같이 예시와 함께 정리 해보았다.
SOLID
• SRP: 단일 책임 원칙(single responsibility principle)
• OCP: 개방-폐쇄 원칙 (Open/closed principle)
• LSP: 리스코프 치환 원칙 (Liskov substitution principle)
• ISP: 인터페이스 분리 원칙 (Interface segregation principle)
• DIP: 의존관계 역전 원칙 (Dependency inversion principle)
• SRP: 단일 책임 원칙(single responsibility principle)
- 한 클래스는 하나의 책임만 가져야 한다. 이는 클래스를 변경하는데 있어 그 이유가 한가지여야 함을 의미한다.
- SRP 원칙을 잘 지키려면 책임의 영역을 확실히 구분하여 서로 다른 클래스로 분배해야한다.
- SRP 원칙으로 설계한다면 변경에서의 연쇄작용이 줄어 변경에 자유도가 올라간다.
class Car {
private String manufacturerName; // 제조사
private String barnd; //브랜드
private Long serialNum; //시리얼넘버
private String color; //색상
private String type; //차 타입(전기, 하이브리드, 일반)
private List options; //추가 옵션
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//아래와 같이 책임을 나누어 설계
class Car {
private String serialNum;
private Manufactuerer manufacturer;
private CarOption carOption;
}
class Manufactuerer{
private String manufacturerName;
private String barnd;
}
class CarOption{
private color;
private type;
private option;
}
• OCP: 개방-폐쇄 원칙 (Open/closed principle)
- 요소가 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
- 이를 지키려면 다형성과 추상화를 적극 활용하여야 한다.
- 확장과 변경의 진짜 의미는 구현체를 직접 변경하는것이 아니라 추상화된 기능을 여러 구현체로 구현하여 기능을 확장하는데 있다.
- 이 또한 변경(아래 예시와 같이 다른 구현체로 변)을 용이하게 하기 위한 원칙
// 예시)
MemberRepository m = new MemoryMemberRepository();
MemberRepository m = new JdbcMemberRepository();
• LSP: 리스코프 치환 원칙 (Liskov substitution principle)
- 프로그램의 객체는 정확성을 깨뜨리지 않으면서 하위 타입으로 바꿀 수 있어야 한다
- 이는 컴파일시 부모타입에 자식 타입의 객체가 들어가는 것을 의미하는 것이 아님
- 자식타입은 추상화된 메서드 or 객체의 규약을 지키며 상속받아야함을 의미한다.
• ISP: 인터페이스 분리 원칙 (Interface segregation principle)
- 특정 클라이언트를 위한 하나의 구체적인 인터페이스보다 여러 범용적인 인터페이스를 사용해야 한다.
- 이를 통해 인터페이스 명확해지고 대체 가능성이 높아진다.
아래 예시는 너무 구체적인 잘못된 인터페이스. 전기차는 주유가 불가능하고 옵션을 추가하지 않은 차량은 좌석을 히팅할 수 없다.
// 예시)
public interface CarFunc {
void go(int meter);
void back(int meter);
void addOil(int oil);
void heatingSeat (int heatingGrade);
}
• DIP: 의존관계 역전 원칙 (Dependency inversion principle)
- 구체화에 의존하지 않고 추상화에 의존해야 한다.
- 추상화된 매개체를 통하여 결합의 관계를 느슨하게 설정할 수 있다.
// 예시)
public class MemberService{
private MemberRepository m;
}