객체 지향 프로그래밍 (OOP)

SEUNGJUN·2024년 1월 19일

객체 지향 프로그래밍 이란?

소프트웨어 개발 패러다임 중 하나로, 현실 세계의 객체들을 모델링하여 프로그램을 구성하고 코드를 재사용하고 유지보수하기 쉽게 만들어주며, 프로그램의 구조를 더 명확하게 만들어 주는 방법

OOP 주요 개념

1. 클래스(Class)

클래스는 객체를 만들기 위한 설계도나 틀, 비슷한 특징을 가지고 있는 공통 속성의 행위를 정의 한다. 클래스에는 속성과 메서드로 구성이 된다.

클래스는 쉽게 말해 레시피 책과 같다. 예를들어 자동차 만들기 레시피가 클래스 이고 그 안에 바퀴, 창문, 엔진 등 속성이 있고, 시동 켜기, 후진하기, 전진하기 메서드가 정의가 되어 있다고 생각 하면 된다.

2. 객체(Object)

객체는 클래스의 인스턴스로, 실제 메모리에 할당되는 것을 의미함. 클래스에서 정의 한 속성과 메서드를 가지며, 프로그램에서 상호 작용할 수 있는 독립적인 단위이다.

객체는 레시피를 가지고 만든 완성품 하나 라고 생각 하면 되는데, 위 예시처럼 자동차 레시피를 가지고 자동차를 만들면 이 차가 하나의 객체라고 할수 있다. 그리고 이 객체는 여러가지 속성을 가지고, 레시피에 나와있는 메서드들을 행위할수 있다.

3. 상속(Inheritance)

상속은 기존의 클래스에서 기능을 물려받아 새로운 클래스를 만드는 것을 의미하며, 부모 클래스의 특징을 자식 클래스가 상속을 받아 사용할수가 있고, 코드의 재사용을 함으로써 계층적인 구조를 만들수 있게 해준다.

상속은 대체적으로 부모와 자식관계라고 할수가 있는데 자동차를 예로 들면 부모는 자동차를 만드는 레시피, 자식은 승용차 또는 SUV 자동차를 만드는 레시피 이런식으로 기본적인 자동차를 만드는 레시피에 각각의 다른 특성을 추가해서 만들수 있는 방법을 상속이라고 한다.

4. 다형성(Polymorphism)

동일한 인터페이스나 메서드를 통해서 여러 객체 유형을 다룰 수 있는 능력을 나타낸다. 메서드 오버로딩과 메서드 오버라이딩을 통해서 구현된다.

  • 오버로딩 : 여러 형태의 메서드를 가질수 있음.
  • 오버라이딩 : 부모 클래스의 메서드를 자식 클래스에서 재정의함.

다형성은 여러 도구들이 동일한 작동을 하는것, 예를들어 주행을 한다는 메서드가 있다고 하면 이를 행할수 있는 객체들은 자동차, 자전거, 킥보드 등의 각자 자신들의 방식대로 주행을 한다고 할수가 있다.

객체 지향 프로그래밍의 원칙 (SOLID)

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

클래스는 하나의 기능만을 가져야한다라는 원칙으로 클래스가 단일 원칙을 가지게 되면 코드를 이해하기가 쉬워지고, 변경시에 해당 기능의 클래스만 수정하므로 유지보수성이 향상된다.

자동차라는 클래스가 있을때, 이 클래스는 운전 기능만을 담당하고 있어야 하며, 이 클래스에서 수리까지 같이 해버리면 안된다. 수리라는 클래스가 따로 만들어 져야 한다.

2. 개방-폐쇄 원칙(Open/Closed Principle, OCP)

확장에 있어서는 열려있지만, 수정에는 닫혀 있어야 한다는 원칙으로 기존의 코드를 변경하지 않고 새로운 기능을 추가할수 있도록 해야 한다. 이렇게 되면 기존 코드의 안정성이 유지가 되고 새로운 기능을 추가하는데 있어 재사용성이 증가할수가 있다.

자동차 레시피 클래스가 있을때, 새로운 형태의 자동차가 필요하면 자동차 레시피를 수정하는 것이 아니라 새로운 형태의 자동차 클래스를 추가하는 방식이다.

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

자식 클래스는 언제가 부모 클래스로 대체가 될수 있어야 한다는 원칙으로 다형성을 지원하고 코드의 일관성을 유지하며 사용자가 서브 타입을 대체해도 기능이 문제 없이 동작한다.

자동차 클래스가 있을때, 서브클래스인 승용차 클래스는 자동차 클래스를 대체할 수 있어야 한다. 자동차 클래스의 메서드를 사용하는 코드에서 승용차 클래스로 대체 하더라도 문제가 없어야 한다.

4. 인터페이스 분리 원칙(Interfae Segregation Principle, ISP)

클라이언트는 자신이 사용하지 않는 메서드에 의존해서는 안되며, 인터페이스는 클라이언에게 플요한 메서드만 제공해야 한다는 원칙으로 사용하지 않는 기능에 의존하지 않기 때문에 불필요한 복잡성을 줄일수가 있고, 인터페이스의 이해와 사용이 간편해 진다.

관리자와 작업자가 있다고 할때 작업자 인터페이스에는 일하기와 휴식하기가 존재하지만 관리자 인터페이스에는 일하기 메서드만 존재하면 된다. 인터페이스를 작게 분리하면 각 클래스에 필요한 메서드에만 의존할수가 있게 된다.

5. 의존 역전 원칙(Dependency Inversion Principle, DIP)

고수준 모듈은 저수준 모듈에 의존해서는 안되며, 양쪽 모두 추상화에 의존해야 한다는 원칙으로 코드의 유연성이 증가되고, 변경에 대한 영향이 최소화가 된다.

전구를 켜고 끄는 컨트롤러가 존재할때, 고수준 모듈인 전구 켜기 기능 사용 클래스는 저수준 모듈인 전구 컨트롤러에 의존하면 안된다. 대신해 추상화된 인터페이스나 추상 클래스를 통해 두 모듈이 상호작용하게 해야한다. 이렇게 되면 전구 컨트롤러를 변경해도 전체 시스템에 영향이 미치지 않는다.

profile
RECORD DEVELOPER

0개의 댓글