객체지향에서 지켜야할 5개의 원칙을 통틀어서 객체지향 5원칙이라고 칭한다.

(꼭 반드시 지켜야하는 것은 아니다.)

이 원칙의 앞글자를 따서 SOLID라고도 부른다.

단일 책임 원칙 (Single Responsibility Principle (SRP))

객체는 오직 하나의 책임을 가져야한다.

사칙연산 함수를 가지고 있는 계산기 클래스가 있다고 하면, 이 클래스는 오직 사칙연산 기능만을 책임진다. 만일 프로그램이 대대적으로 수정이 되더라도 계산기 클래스가 수정될 만한 사유는 사칙연산 함수와 관련된 문제이다. 이처럼 단일 책임 원칙은 클래스의 목적을 명확히 함으로써 구조가 난잡해 지거나, 수정사항이 불필요하게 넓게 퍼지는 것을 예방하고 명확히 기능을 분리할 수 있게 한다.

→ 예시) 위의 계산기 클래스로 계산기 프로그램을 개발하고 있는데, UI 관련 코드도 같은 클래스에 포함시켜버렸다. 그러면 계산기 클래스는 계산과, UI갱신등 두 가지의 책임을 지니게 된다. 만약 UI 수정사항이 있어도 계산기 클래스를 고치고 있어야한다, 만약 UI가 더 커진다면 클래스의 목적이 모호해지고, 유지보수하기도 어렵게 된다.

개방-폐쇠 원칙 (Open-Closed Principle (OCP))

객체는 확장에 대해서는 개방적이고, 수정에 대해서는 폐쇄적이어야 한다는 원칙이다.

즉, 객체 기능의 확장을 허용하고 스스로의 변경은 피해야한다.

→ 예시) 스타크래프트에 등장하는 유닛을 만들기 위해 클래스를 만든다고 했을때, 유닛들의 공통사항을 고려하면서 가질수 있는 것들을 메서드와 필드를 가지는 유닛이라는 추상클래스를 만들고, 구현은 그 추상클래스를 상속받는 하위클래스에서 오버라이딩해서 구성하는 것, 그러면 각각 유닛마다 기능의 확장에 대해서는 개방적으로 할 수 있다.

리스코프 치환 원칙 (Liskov Substitution Principle (LSP))

자식 클래스는 언제나 자신의 부모 클래스를 대체 할 수 있다는 원칙이다. 즉 부모클래스 Person가 있다면 그 부모클래스를 상속받는 Solider 클래스가 Person 참조 변수에 넣어도 계획대로 잘작동 할 수 있다는 개념이다.

→ 예시) 위에서 만든 스타크래프트 유닛이라는 추상클래스(여기서 Move, Attack은 모든 공통적으로 구현되어 있음)에 그것을 상속받는 마린을 만들고 Move, Attack 메서드를 오버라이딩해서 재구현했을때 유닛이라는 참조변수에 마린을 넣어도 잘동작 해야한다는 것이다.

인터페이스 분리 원칙 (Interface Segregation Principle (ISP))

반드시 객체가 자신에게 필요한 기능만을 가지도록 제한하는 것이다

불필요한 상속과 구현을 최대한 방지함으로써 객체의 불필요한 책임을 제거하는 것이다. 이렇게 기능을 잘게 나누어 인터페이스로 분리하면 확장성을 향상 시킬 수 있다.

→ 예시) 위에서 만든 스타크래프트 유닛이라는 추상클래스는 상속받는 경우에 자원채취기능을 구현해야한다고 했을때 자원채취기능을 가지는 인터페이스를 따로 만들고 그것을 유닛클래스를 상속받는 자식클래스에 자원채취기능을 선언한 인터페이스를 상속받게 하는 것이다.

의존성 역전 원칙 (Dependency Inversion Principle (DIP))

상위 수준의 모듈은 하위 수준의 모듈에 의존하면 안된다. 둘 모두 추상화에 의존해야 한다는 것.

추상화는 구체적인 사항에 의존해서는 안된다. 구체적인 사항은 추상화에 의존해야 한다.

추상화된 인터페이스나 추상 클래스를 통해 상호작용하도록 설계되어야 된다는 것.