OOP (Object-Oriented Programming)
OOP (Object-Oriented Programming)
객체지향 프로그래밍 (OOP) : 소프트웨어 설계 및 구현 방식으로, 프로그램을 "객체"라는 독립적인 단위로 분리하여 문제를 해결
OOP에서 지향하는 바는 코드를 더 구조적이고 재사용 가능하며 유지보수가 용이하게 만드는 것
1. 캡슐화 (Encapsulation)
- 데이터와 메서드를 하나의 단위로 묶고, 객체 외부에서는 내부 구현을 숨기려는 원칙
- 데이터의 무결성을 보호하고, 외부에서 직접 데이터에 접근하지 못하게 하여 코드의 안정성을 높임
- ex. 클래스 내부에서 데이터를 관리하고, 그 데이터에 접근하는 방법을 메서드로 제공하여 데이터를 안전하게 수정하도록 제한
2. 상속 (Inheritance)
- 기존의 클래스에서 새로운 클래스를 만들어 그 기능을 재사용하는 원칙
- 코드 중복을 줄이고, 기존 코드의 기능을 확장하거나 수정할 수 있어 유지보수에 용이
- ex. Animal 클래스에서 Dog, Cat 클래스를 상속받아 공통적인 행동을 Animal에서 정의하고, 각각의 세부적인 행동은 자식 클래스에서 구현
Abstract Class : 인스턴스를 만들 수 없는 클래스
- 객체를 직접 생성할 수 없고, 상속을 통해 자식 클래스에서 구현을 완료해야 하는 클래스
- 공통된 특성이나 구현의 일부를 제공하고, 상속받은 클래스가 구체적인 구현을 추가하도록 요구
- 공통된 속성이나 메서드를 공유하고 싶을 때 사용합니다.
- 일부 메서드는 자식 클래스에서 구현하도록 강제할 때 사용합니다. (추상 메서드를 통해)
- 상속받는 클래스들에 대해 기본적인 틀을 제공할 때 유용합니다.
3. 다형성 (Polymorphism)
- 동일한 메서드나 연산자가 다양한 방식으로 동작하도록 하는 원칙
- 같은 인터페이스를 통해 다양한 객체가 동작할 수 있어 유연성과 확장성을 높임
- ex. Animal 클래스의 makeSound() 메서드가 Dog에서는 "멍멍", Cat에서는 "야옹"을 출력하도록 다르게 동작
- 메서드 오버로딩 (Method Overloading) – 동일한 이름의 메서드를 매개변수의 개수나 타입에 따라 다르게 정의하는 것.
- 메서드 오버라이딩 (Method Overriding) – 상속 관계에서 부모 클래스의 메서드를 자식 클래스에서 재정의하는 것.
4. 추상화 (Abstraction)
- 불필요한 세부 사항을 숨기고 중요한 기능만을 사용자에게 제공하는 원칙
- 복잡한 시스템을 단순화하여 더 쉽게 다룰 수 있게 하고, 외부와의 인터페이스를 명확히함
- ex. Vehicle 클래스에서 startEngine() 메서드가 차량에 따라 다르게 동작하지만, 사용자에게는 동작 방식의 세부 사항을 숨기고 startEngine()만 제공
5. 객체의 자율성
- 객체가 자신의 상태와 동작을 관리하게 하여, 외부의 변화에 자기 자신만의 방식으로 반응하도록 함
- 객체는 독립적으로 작동하며, 다른 객체와의 상호작용을 통해 시스템을 구성 (모듈화와 응집도를 높임)
- ex. 객체는 자신이 가진 데이터를 직접 수정하거나 변경할 수 있으며, 외부에서 객체의 상태를 직접 변경하는 것을 제한
6. 유연성과 확장성
- 객체지향 설계를 통해 시스템을 유연하고 확장 가능하게 만들어, 변경이 필요할 때 최소한의 수정으로 기능을 확장하거나 수정하도록 함
- 새로운 요구 사항이나 변경에 적응하기 쉬운 구조를 만들어, 유지보수 비용을 줄임
- ex. 새 기능이 필요할 때 기존 클래스를 수정하지 않고 새로운 클래스를 추가하거나, 기존 인터페이스를 확장하여 기능을 추가할 수 있음
SOLID
- 객체 지향 설계의 5가지 주요 원칙을 정의
- 소프트웨어의 유지보수성, 확장성, 가독성을 높이기 위해 설계됨
1. Single Responsibility Principle (SRP)
하나의 클래스는 오직 하나의 책임을 가져야한다.
2. Open/Colsed Principle (OCP)
Software Entity (Class, Module, Function 등) 확장에는 열려 있어야 하지만, 수정에는 닫혀 있어야 한다.
(즉, 새로운 기능 추가시 기존코드를 수정하지 않고 확장하는 형태로 설계
3. Liskov Substitution Principle (LSP)
서브클래스는 부모 클래스의 기능을 대체할 수 있어야 한다.
(즉, 자식 클래스가 부모 클래스를 대신해도 프로그램이 정상적으로 작동해야함)
4. Interface Segregation Principle (ISP)
클라이언트가 사용하지 않는 인터페이스에 의존하지 않도록 작은 단위의 인터페이스를 여러개 만들어야 한다.
(하나의 큰 인터페이스를 여러 역할로 나누면, 필요 없는 메서드를 구현하지 않아도 되므로 유지보수가 쉬워진다.)
5.Dependency Inversion Principle (DIP)
상위 모듈은 하위 모듈에 의존해서는 안되며, 둘다 추상화에 의존해야한다.
(구체적인 클래스에 의존하면 유연성이 떨어지기 때문에, 추상 인터페이스를 사용하여 모듈 간 결합을 줄여야 한다)