객체지향 설계의 5원칙 S.O.L.I.D
잘못된 코딩이란?
-
높은 결합도
정보(데이타)가 외부에 노출되면 될수록, 여러 객체에서 그 정보를 이용하게 되고, 정보를 변경하려 할 때, 그 정보에 의존하는 모든 객체를 같이 수정해야 하기에, 수정이 어려워집니다.(추상화 위반)
-
낮은 응집도
하나의 객체 정보변경이 다른 객체에 의해 이루어지면, 소스를 수정하려 할때 어떤 객체에 의해 정보변경이 이루어지는지 찾아야 하고, 찾은 소스를 같이 수정해야 합니다.(캡슐화 위반)
-
쓸데 없이 복잡함
지나치게 복잡하게 디자인한 코드도 소스의 가독성을 해칩니다.
The Single Responsibility Principle – SRP
어떤 클래스를 변경해야 하는 이유는 오직 하나뿐 이어야 한다.
쇼핑몰 상품 객체가 있다고 할때, 상품페이지에 쓰이는 상품객체와 이미 주문을 끝낸 이후에 표시되는 상품객체는 각각 생성해야 합니다.
하나의 객체가 여러곳에 쓰이면 쓰일수록, 변경이 잦아지고 또 버그의 위험성은 증가합니다.
The Open-Closed Principle – OCP
소프트웨어 엔터티(클래스, 모듈, 함수 등등)는 Interface에 대해서는 개방되어야 하지만, 변경에 대해서는 폐쇄되어야 한다.
구현과 인터페이스의 분리라고도 합니다. 객체를 이용할 때 인터페이스를 이용해 호출하지만, 객체내부의 실제 구현은 외부에 노출되어서는 안됩니다. 구현이 외부에 노출되면 그 객체는 변경이 제한되거나 불가능해집니다.
Liskov Substitution Principle – LSP
서브타입(Sub Type)은 언제나 자신의 기반 타입(Base Type)으로 교체할 수 있어야 한다.
부모객체를 상속한 자식객체는 언제나 부모객체가 쓰이는 곳에 교체되어 쓰일 수 있어야 합니다.
자식객체가 부모객체의 원래의 기능을 비활성화시키거나 대체 불가능할 정도로 변경해서는 안됩니다.
Dependency Inversion Principle – DIP
고차원의 모듈은 저차원의 모듈에 의존하면 안된다. 이 두 모듈 모두 다른 추상화된 것에 의존한다. 추상화 된 것은 구체적인 것에 의존하면 안 된다. 구체적인 것이 추상화된 것에 의존해야 한다.
Dependency 는 A 객체가 B 객체를 사용하는 관계입니다. 속성으로 포함하는 것이 아니라, 메소드에서 사용합니다.
스노우타이어는 바뀌기 쉽기 때문에 막바로 의존하지 말고, 추상화된 객체에 의존해야 안전합니다.
변하기 쉬운 객체에 의존하지 말고, 변하기 어려운 추상클래스나 인터페이스를 이용하도록 해야 변화에 덜 민감해집니다.
// without DIP
public class Car {
public void change(SnowTire tire) {
// ....
}
}
// with DIP
public class Car {
public void change(Tire tire) {
// ....
}
}
Interface Segregation Principle – ISP
클라이언트는 자신이 사용하지 않는 메소드에 의존 관계를 맺으면 안된다.
거대한 객체는 실제로 사용되는 인터페이스는 몇개 되지도 않으면서 여러 곳에서 사용됨으로 인해 뜻하지 않는 영향을 받기 쉬워집니다.
가능하면 객체를 쪼개어 여러개로 만들고 객체의 사이즈를 줄여 의도하지 않은 영향을 최소화해야 합니다.