응집도, 결합도
추상화
- 인터페이스를 통해 메서드를 외부에 제공할 때는 최소한의 메서드만 제공하라
-상위클래스는 풍성할수록 좋고, 인터페이스는 작을수록 좋다고 했다.
SOLID: 로버트 C. 마틴이 2000년대 초반 객체 지향 프로그래밍 및 설계의 다섯 가지 기본 원칙으로 제시한 것을 마이클 페더스가 두문자어로 소개한 것.
- 응집도는 높이고(high cohesion), 결합도는 낮추는(loose coupling) 고전 원칙을 객체지향의 관점에서 재정립함
- 응집도: 하나의 모듈 내부에 존재하는 구성 요소들의 기능적 관련성, 응집도가 높은 모듈은 하나의 책임에 집중하고, 독립성이 높아져 재사용이나 기능의 수정, 유지보수가 용이하다.
- 결합도: 모듈(클래스) 간의 상호 의존 정도로서 결합도가 낮으면 모듈 간의 상호 의존성이 줄어들어 객체의 재사용이나 수정, 유지보수가 용이하다.
- 어떤 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 한다.
- 역할과 책임에 따라 분리해서 각각 하나의 역할과 책임만 갖도록 한다.

여기서는 클래스 분할만 이야기 했으나, 단일 책임 원칙은 속성, 메서드, 패키지, 모듈, 컴포넌트, 프레임워크 등에도 적용할 수 있는 개념이다.
ex) 불필요한 속성이 들어가있을 때-> 하나의 속성이 여러 의미를 갖는 경우
- 소프트웨어 엔티티(클래스, 모듈 함수 등)는 확장에 대해서는 열려 있어야 하지만 변경에 대해서는 닫혀 있어야 한다.
- 자신의 확장에는 열려있고, 주변의 변화에 대해서는 닫혀 있어야 한다.

인터페이스를 중간에 둠으로써 다양한 자동차가 생긴다고 해도 운전자는 운전 습관에 영향을 받지 않게 된다.
다양한 자동차가 생긴다고 하는 것은 자동차 입장에서는 자신의 확장에는 개방돼 있는 것이고, 운전자 입장에서는 주변의 변화에 폐쇄돼 있는 것이다.

데이터베이스가 오라클에서 mysql로 바뀌더라도 Connection을 설정하는 부분 외에는 따로 수정할 필요가 없다.
설정 부분을 별도 설정 파일로 분리해두면 클라이언트 코드는 단 한줄도 변경할 필요가 없다.
개방 폐쇄 원칙을 무시하고 프로그램을 작성하면?
- 객체 지향 프로그래밍의 가장 큰 장점인 유연성, 재사용성, 유지보수성 등을 얻을 수 없다.
객체지향의 상속 특성- 서브 타입은 언제나 자신의 기반 타입(base type)으로 교체할 수 있어야 한다.
- 하위 클래스의 인스턴스는 상위형 객체 참조 변수에 대입해 상위 클래스의 인스턴스 역할을 하는 데 문제가 없어야 한다.
상속은 조직도나 계층도가 아닌 분류도가 되어야 한다.

아버지 춘향이 = new 딸() -> X
동물 뽀로로 = new 펭귄()-> O아빠의 역할을 맡기고 있다. 아버지 객체가 가진 행위(메서드)를 할 수 있어야 한다.

하위에 존재하는 것들은 상위에 있는 것들의 역할을 하는 데 전혀 문제가 없다.
- 클라이언트는 자신이 사용하지 않는 메서드에 의존 관계를 맺으면 안 된다.
- 인터페이스는 그 역할에 충실한 최소한의 기능만 공개하라


- 고차원 모듈은 저차원 모듈에 의존하면 안 된다. 이 두 모듈 모두 다른 추상화된 것에 의존해야 한다.
- 추상화된 것은 구체적인 것에 의존하면 안 된다. 구체적인 것이 추상화된 것에 의존해야 한다.
- 자주 변경되는 구체(Concrete) 클래스에 의존하지 마라.


- 자신보다 변하기 쉬운 것에 의존하던 것을 추상화된 인터페이스나 상위 클래스를 두어 변하기 쉬운 것의 변화에 영향받지 않게 하는 것이 의존 역전 원칙이다.
자신보다 변하기 쉬운 것에 의존하지 마라
- 관심사의 분리 (Separation Of Concerns)
- 관심이 같은 것끼리는 하나의 객체 안으로 또는 친한 객체로 모으고, 관심이 다른 것은 가능한 한 따로 떨어져 서로 영향을 주지 않도록 분리하는 것이다.
- SRP(
단일 책임 원칙, Single Responsibility Principle): 어떤 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 한다.- OCP(
개방 폐쇄의 원칙, Open Closed Principle): 자신의 확장에는 열려있고, 주변의 변화에 대해서는 닫혀 있어야 한다.- LSP(
리스코프 치환 원칙, Listov Substitution Principle): 서브 타입은 언제나 자신의 기반 타입으로 교체할 수 있어야 한다.- ISP(
인터페이스 분리 원칙, Interface Segregation Principle): 클라이언트는 자신이 사용하지 않는 메서드에 의존관계를 맺으면 안 된다.- DIP(
의존 역전 원칙, Dependency Inversion Principle): 자신보다 변하기 쉬운 것에 의존하지 마라.