객체지향에서 꼭 지켜야 할 5개의 원칙을 통틀어 객체지향 5원칙이라 칭한다. 5개의 원칙의 앞글자를 따서 SOLID라고도 부른다.
한 클래스는 하나의 책임만 가져야 한다.
작성된 클래스는 하나의 기능만 가지며 클래스가 제공하는 모든 서비스는 그 하나의 책임(변화의 축: axis of change)을 수행하는 데 집중되어 있어야 한다는 원칙이다.
어떤 변화에 의해 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 함을 의미한다.
따라서 SPR에서 책임은 '소프트웨어를 구성하는 설계 부품인 클래스나 함수 등은 단 하나의 기능만을 가져야한다'는 의미이다.
SPR 원리를 적용하면 무엇보다도 책임 영역이 확실해지기 때문에 한 책임의 변경에서 다른 책임의 변경으로의 연쇄작용에서 자유로울 수 있을 뿐만 아니라 책임을 적절히 분배함으로써 코드의 가독성 향상, 유지보수 용이라는 이점까지 누를 수 있으며 객체지향 원리의 대전제 격인 OCP원리뿐 아니라 다른 원리들을 적용하는 기초가 된다.

SPR 적용전엔 특성정보들로 변경이 발생할 수 있는 price,Maker,Type,model 등이 변화할때 해당 Guitar클래스를 수정해야하는 부담이 발생하게 된다

따라서 이렇게 SPR을 적용하면 특성 정보들을 분리해 가독성이 좋아지고 변화에 의한 변경되는 부분들을 한곳에서 관리할 수 있게된다.
소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
즉, 객체 기능의 확장을 허용하고 스스로의 변경은 피해야한다는 것이다.
버틀란트 메이어(Bertrand Meyer) 박사가 1998년 객체지향 소프트웨어 설계라는 책에서 정의한 내용으로 소프트웨어의 구성요소(컴포넌트,클래스,모듈,함수)는 확장에는 열려있고, 변경에는 닫혀있어야 한다는 원리이다. 이것은 변경을 위한 비용은 가능한 줄이고 확장을 위한 비용은 가능한 극대화 해야한다는 의미로, 요구사항의 변경이나 추가사항이 발생하더라도, 기존 구성 요소는 수정이 일어나지 말아야하며, 기존 구성요소를 쉽게 확장해서 재사용할 수 있어야 한다는 뜻이다.
개방 폐쇄 원칙의 핵심은 변화하는 부분을 추상화하는 것이다.

위에서 봤던 예제로 만약 Guitar가 아닌 첼로, 바이올린, 비올라같은 다른 악기들도 다뤄야한다면 매번 새로운 악기들과 요소들을 만들어간다면 복잡할 것이다

그렇기에 Guitar와 추가 될 다른 악기들을 추상화하는 작업이 필요하다.
여기서 추가될 악기들의 공통 속성을 모두 담을 수 있는 인터페이스를 생성하게되면 새로운 악기가 추가 되면서 변경이 발생하는 부분을 추상화하여 분리할 수 있다.
이렇게 코드의 수정을 최소화화여 결합도는 줄이고 응집도는 높일수 있는 효과를 본다.
+)


JDBC 매니저를 상속받는 PostgreSQL, Oracle, Sybase는 모두 변경에는 확장적이지만, 자바 어플리케이션은 수정에 폐쇄적인 것을 알 수 있다. 더 쉽게 이야기하자면, Oracle DB의 변화가 발생하여도 자바 어플리케이션에서 수정할 코드는 없다는 것이다. 즉, 개방 폐쇄 원칙은 하나의 변화가 다른 곳에도 연쇄적으로 변화를 일으키는 것을 방지하기 위해 만들어졌다.
프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
이 원칙은 MIT 컴퓨터 사이언스 교수인 리스코프가 제안한 설계 원칙으로, 부모 클래스와 자식 클래스 사이에는 일관된 행위가 있어야 한다는 원칙이다.
즉, 자식 클래스는 부모 클래스에서 가능한 행위를 수행해야 하며, 객체 지향 프로그래밍에서는 부모 클래스의 인스턴스 대신 자식 클래스의 인스턴스를 사용해도 문제가 없다는 것을 의미한다.
쉽게 말해 자식 클래스는 언제나 자신의 부모 클래스를 대체할 수 있다는 원칙이고 즉 부모 클래스가 들어갈 자리에 자식 클래스를 넣어도 계획대로 잘 작동해야 한다.
LSP 원칙을 잘 적용한 예제가 자바의 컬렉션 프레임워크이다.

만일 변수에 LinkedList 자료형을 담아 사용하다, 중간에 전혀 다른 HashSet 자료형으로 바꿔도 add() 메소드 동작을 보장받기 위해서는 Collection 이라는 인터페이스 타입으로 변수를 선언하여 할당하면 된다.
왜냐하면 인터페이스 Collection의 추상 메서드를 각기 하위 자료형 클래스에서 implements하여 인터페이스 구현 규약을 잘 지키도록 미리 잘 설계되어 있기 때문이다.
void myData() {
// Collection 인터페이스 타입으로 변수 선언
Collection data = new LinkedList();
data = new HashSet(); // 중간에 전혀 다른 자료형 클래스를 할당해도 호환됨
modify(data); // 메소드 실행
}
void modify(Collection data){
list.add(1); // 인터페이스 구현 구조가 잘 잡혀있기 때문에 add 메소드 동작이 각기 자료형에 맞게 보장됨
// ...
}
리스코프 치환 원칙은 한마디로 다형성을 지원하기 위한 원칙이라고 할 수 있다.
+)

결국 리스코프 치환 원칙은 객체 지향의 상속이라는 특성을 올바르게 활용하면 자연스럽게 얻게 되는 것이다.
특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 말아야 한다는 원칙이다. 즉, 어떤 클래스가 다른 클래스에 종속될 때에는 가능한 최소한의 인터페이스만을 사용해야 한다. 이것을 하나의 일반적인 인터페이스보다는, 여러 개의 구체적인 인터페이스가 낫다 라고 정의할 수도 있다. 이 원칙을 적용하여 설계하면, 시스템의 내부 의존성을 약화시켜 리팩토링, 수정, 재배포를 쉽게 할 수 있는 이점이 생긴다.
SPR이 클래스의 단일 책임을 강조한다면 ISP는 인터페이스의 단일 책임을 강조한다.

프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안된다." 라는 것이다.
의존 관계의 역전이란 구조적 디자인에서 발생하던 하위 모듈의 변경이 상위 레벨 모듈의 변경을 요구하는 위계관계를 끊는 의미의 역전이다. 실제 사용 관계는 바뀌지 않으며, 추상을 매개로 메시지를 주고 받음으로써 관계를 최대한 느슨하게 만드는 원칙이다.
즉 의존 관계를 맺을 때 변화하기 쉬운 것 또는 자주 변화하는 것보다는 변화하기 어려운 것, 거의 변화가 없는 것에 의존하라는 것이다. 한마디로 구체적인 클래스보다 인터페이스나 추상 클래스와 관계를 맺으라는 것이다.
이 원칙을 적용하면 복잡한 컴포넌트간의 커뮤니케이션 관계를 단순화하고 컴포넌트 간의 커뮤니케이션을 효율적이게 한다.
+) 저수준 모듈이 고수준 모듈에 의존하게 되는 것
== 자신보다 변하기 쉬운 것에 의존하지 마라
자동차가 스노우타이어에 의존한다.

자동차는 한 번 사면 몇 년은 타야 하는데 스노우타이어는 계절이 바뀌면 일반 타이어로 교체해야 한다. 이런 경우 스노우타이어를 일반타이어로 교체할 때 자동차는 그 영향에 노출돼 있음을 알 수 있다.

위와 같이 자동차가 구체적인 타이어들(스노우타이어, 일반타이어, 광폭타이어)이 아닌 추상화된 타이어 인터페이스에만 의존하게 함으로써 스노우타이어에서 일반타이어로, 또는 다른 구체적인 타이어로 변경돼도 자동차는 이제 그 영향을 받지 않는 형태로 구성된다.
자동차는 자신보다 변하기 쉬운 스노우타이어에 의존하던 관계를 중간에 추상화된 타이어 인터페이스를 추가해 두고 의존 관계를 역전시키고 있다.
이처럼 자신보다 변하기 쉬운 것에 의존하던 것을 추상화된 인터페이스나 상위 클래스를 두어 변하기 쉬운 것의 변화에 영향받지 않게 하는 것이 의존 역전 원칙이다.
참조 문헌 : https://www.nextree.co.kr/p6960/
https://velog.io/@juhwan9408/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%EC%84%A4%EA%B3%84-5%EC%9B%90%EC%B9%99-SOLID#span-stylecolorredsspanrp---%EB%8B%A8%EC%9D%BC-%EC%B1%85%EC%9E%84-%EC%9B%90%EC%B9%99brsingle-responsibility-priniciple4
https://velog.io/@juhwan9408/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%EC%84%A4%EA%B3%84-5%EC%9B%90%EC%B9%99-SOLID#span-stylecolorredsspanrp---%EB%8B%A8%EC%9D%BC-%EC%B1%85%EC%9E%84-%EC%9B%90%EC%B9%99brsingle-responsibility-priniciple4
https://server-engineer.tistory.com/228
https://inpa.tistory.com/entry/OOP-%F0%9F%92%A0-%EC%95%84%EC%A3%BC-%EC%89%BD%EA%B2%8C-%EC%9D%B4%ED%95%B4%ED%95%98%EB%8A%94-LSP-%EB%A6%AC%EC%8A%A4%EC%BD%94%ED%94%84-%EC%B9%98%ED%99%98-%EC%9B%90%EC%B9%99