항해99 심화주차 - 객체 지향

youngsung·2023년 3월 12일
0

Node.js

목록 보기
4/7

객체 지향 (Object-Oriented)

1) 객체 지향이란?

객체 지향은 소프트웨어의 핵심을 기능이 아닌 객체로 삼으며 "노가 어떠한 일을 할 것인가?"에 초점을 맞춥니다.
즉, 객체를 도출하고 각각의 역할을 정의하는 것에 초점을 맞춥니다.

  • 책임과 권한을 가진 객체들이 서로 메시지를 주고받으며 협력해서 필요한 기능을 수행하도록 시스템을 개발하는 것을 객체 지향이라고 합니다.

  • 크고 복잡한 시스템을 효과적으로 분해하고 구성할 수 있고, 손쉽게 이해하고 효율적으로 다룰 수 있게 도와주는 방법으로 인정받아 많은 프로그래밍 언어에 적용되어 왔고 지금은 가장 인기 있는 프로그래밍 패러다임으로 자리 잡습니다.

2) 캡슐화 (Encapsulation)

개념적이나 물리적으로 객체 내부의 세부적인 사항을 감추는 것을 캡슐화라고 부릅니다.
즉, 캡슐화를 사용하는 가장 큰 이유는 정보은닉을 목적으로 합니다.

  • 정보은닉은 객체에 대한 중요한 정보를 외부로 노출시키지 않도록 하기 위한 기법입니다.

캡슐화의 목적은 변경하기 쉬운 객체를 만드는 것입니다. 캡슐화를 통해 객체 내부의 접근을 제한하면 객체와 객체 사이의 결합도를 낮출 수 있기 떄문에 설계를 좀 더 쉽게 변경할 수 있게 됩니다.

3) 상속 (Inheritance)

상속이란 이미 정의된 상위 클래스의 특징을 하위 클래스에서 물려받아 코드의 중복을 제거하고 코드 재사용성을 증대시킵니다.
즉, 하나의 클래스가 가진 특징(함수, 변수 및 데이터)을 다른 클래스가 그대로 물려 받는 것을 말합니다.

  • 개별 클래스를 상속 관계로 묶음으로써 클래스 간의 체계화된 구조를 파악하기 쉬워집니다.

  • 데이터와 메소드를 변경할 때 상위에 있는 것만 수정하여 전체적으로 일관성을 유지할 수 있습니다.

기존에 작성된 클래스를 물려 받아 재활용하여 사용하므로 객체지향 프로그래밍의 중요한 기능 중 하나입니다.

4) 추상화 (Abstraction)

객체에서 공통된 부분을 모아 상위 개념으로 새롭게 선언하는 것을 추상화라고 합니다.
즉, 불필요한 부분을 생략하고 객체 속성 중 공통적이고 중요한 것에만 중점을 두어 모델화 하는 것입니다.

  • 추상화는 객체들의 공통적인 특성을 파악하여 필요 없는 특성을 제거하는 과정입니다.

  • 시스템을 구축하기 전에 시스템 구조 및 구성을 가시적으로 볼 수 있고, 해당 시스템과 유사한 모델을 만들어 여러가지 테스트를 할 수 있습니다.

  • 복잡한 내부 구현에 신경쓰지 않고, 외부에 노출되어 있는 인터페이스만을 이용하여 코드를 작성할 수 있습니다.

클래스를 설계할 때 공통적으로 묶일 수 있는 기능을 추상화 -> 추상클래스 -> 인터페이스로 모델링해서 향후 다양성(Polymorphism)으로 확장할 수 있도록 설계합니다.

여기서 인터페이스(Interface)란 클래스 정의할 때 메소드와 속성만 정의하여 인터페이스에 선언된 프로퍼티 또는 메소드의 구현을 강제하여 코드의 일관성을 유지할 수 있도록 만듭니다.

5) 다형성 (Polymorphism)

다형성이란 객체(클래스)가 연산을 수행하게 될 때 하나의 행위에 대해 각 객체가 가지고 있는 고유한 특성으로 다른 여러 형태로 재구성 되는 것을 말합니다.
즉, 동일한 메소드의 이름을 사용하지만 메소드에 대해 클래스마다 다르게 구현되는 개념이 다형성 입니다.

다형성을 통해 역할(인터페이스)과 구현을 분리해서 오버라이딩(Overrideing)을 통해 서비스의 구현기능을 유연하게 변경, 확장이 가능합니다.

Java의 오버로딩(Overloading), 오버라이딩(Overriding)이 대표적인 다형성의 예시입니다.

6) 의존성 (Dependency)

의존성이란 객체(모듈 및 클래스)들이 협력하는 과정 속에서 해당 객체들이 다른 객체를 의존하게 되는 정도를 나타냅니다.

  • 의존성이라는 말속에는 어떤 객체가 변경될 때 그 객체에 의존하는 다른 객체도 함께 변경될 수 있다는 사실이 내포되어 있습니다.

  • 만약 하나의 객체가 변경될 경우 의존하고 있는 다른 객체 또한 변경이 이루어지게 됩니다.

7) 결합도 (Coupling)

결합도는 의존성의 정도를 나타내며 다른 모듈에 대해 얼마나 많은 의존성을 가지고 있는지를 나타냅니다.

  • 객체 사이의 의존성이 과한 경우를 가리켜 결합도가 높다고 말합니다.

  • 객체들이 합리적인 수준으로 의존할 경우에는 결합도가 낮다고 말합니다.

  • 두 객체 사이의 결합도가 높으면 높을수록 함께 변경될 확률도 높아지기 때문에 변경하기 어려워집니다.

  • 따라서 설계의 목표는 객체 사이의 결합도를 낮춰 변경이 용이한 설계를 만드는 것이어야 합니다.

8) 응집도 (Cohesion)

응집도는 모듈에 포함된 내부 요소들이 각각 연관되어 있는 관계의 정도를 나타냅니다.

  • 밀접하게 연관된 작업만을 수행하고 연관성 없는 작업은 다른 객체에 위임하는 객체를 가리켜 응집도가 높다고 말합니다.

  • 1개의 메소드가 내부에서 변수를 많이 사용할 수록 해당 메소드와 클래스는 응집도가 높아지게됩니다.

  • 자신의 데이터를 스스로 처리하는 자율적인 객체를 만들면 결합도를 낮출 수 있을뿐더러 응집도를 높일 수 있다.

  • 객체의 응집도를 높이기 위해서는 객체는 스스로 자신의 데이터를 책임져야 합니다.

객체 지향 프로그래밍(Object-Oriented Programming, OOP)

1) 프로그래밍 패러다임

프로그래밍 패러다임은 무엇을 해야 할지를 말하기보다는 무엇을 해서는 안 되는지를 말해줍니다.

프로그래밍 패러다임에는 대표적으로 3가지가 존재합니다.
1. 구조적 프로그래밍 (Structured Programming)
2. 객체 지향 프로그래밍 (Object-Oriented Programming, OOP)
3. 함수형 프로그래밍 (Functional Programming)

2) 객체 지향 프로그래밍 (Object-Oriented Programming, OOP)

데이터와 프로세스가 동일한 모듈 내부에 위치하도록 프로그래밍하는 방식을 객체지향 프로그래밍이라고 부릅니다.

  • 객체 지향 프로그래밍은 코드를 추상화해 직관적으로 사고할 수 있기 때문에, 대표적인 프로그래밍 방법론으로 적용되고 있습니다.

  • 객체 지향 프로그래밍에서는 자동차, 동물, 사람 등과 같은 현실 세계의 객체를 유연하게 표현할 수 있습니다.

  • 객체는 어떠한 특성을 가지고 있으며 특정 기능을 수행할 수 있습니다.

3) 객체 지향 프로그래밍의 장점

  • 객체지향 프로그래밍은 의존성을 효율적으로 통제할 수 있는 다양한 방법을 제공함으로써 요구사항 변경에 좀 더 수월하게 대응할 수 있는 가능성을 높여줍니다.

  • 동작을 기준으로 프로그래밍을 진행하는 것보다 데이터를 중심으로 프로그래밍을 하게되면 코드의 덩치가 커지더라도 일관성을 유지하기 좋습니다.

  • 객체지향 코드는 자신의 문제를 스스로 처리해야 한다는 우리의 예상을 만족시켜주기 때문에 이해하기 쉽고, 객체 내부의 변경이 객체 외부에 파급되지 않도록 제어할 수 있기 때문에 변경하기 수월합니다.

  • 흔히 데이터와 프로세스를 하나의 단위로 통합해 놓는 방식으로 표현하기도 합니다.

  • 데이터와 데이터를 사용하는 프로세스가 동일한 객체 안에 위치한다면 객체지향 프로그래밍 방식을 따르고 있을 확률이 높습니다.

객체 지향 설계 5원칙 (SOLID)

1) 객체 지향 설계 5원칙

객체 지향 프로그래밍 및 설계의 다섯가지 기본원칙을 SOLID라는 것으로 불리고 있습니다.

  • SOLID는 객체 지향 프로그래밍 및 설계의 다섯 가지 기본 원칙의 맨 앞단어를 하나씩 가져와 만든 것 입니다.

  • SOLID는 프로그래머가 시간이 지나도 유지 보수와 확장이 쉬운 시스템을 만들고자 할 때 사용합니다.

SOLID의 종류

  • 단일 책임의 원칙 (Single Responsibility Principle, SRP)
  • 개방-패쇄 원칙 (Open-Closed Principle, OCP)
  • 리스코프 치환 원칙 (Liskov substitution principle, LSP)
  • 인터페이스 분리 원칙 (Interface segregation principle, ISP)
  • 의존성 역전 원칙 (Dependency Inversion Principle, DIP)

2) 단일 책임의 원칙 (SRP)
하나의 객체는 단 하나의 책임을 가져야 한다.
즉, 클래스나 모듈을 변경할 이유가 단 하나 뿐이어야 한다는 원칙입니다.
SRP는 책임이라는 개념을 정의하며 적절한 클래스의 크기를 제시합니다.

3) 개방-패쇄 원칙(OCP)
소프트웨어 엔티티 또는 개체(클래스, 모듈, 함수 등)는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.

  • 즉, 소프트웨어 개체의 행위는 확장될 수 있어야 하지만, 개체를 변경해서는 안됩니다.

  • 기존 코드에 영향을 주지않고 소프트웨어에 새로운 기능이나 구성 요소를 추가할 수 있어야 한다는 것입니다.

만약 요구사항을 조금 확장하는데 소프트웨어를 엄청나게 수정해야 한다면, 소모되는 개발 코스트또한 엄청나게 증가할 것입니다.

4) 리스코프 치환 원칙 (LSP)
프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.

하위 타입 이란 S타입의 객체 O1 각각에 대응하는 T타입 객체 O2가 있고, T타입을 이용해서 정의한 모든 프로그램 P에서 O2자리에 O1을 치환하더라도 P의 행위가 변하지 않는다면, ST의 하위 타입입니다.
즉, ST의 하위 유형이면 해당 프로그램의 속성을 변경하지 않고 T객체를S객체로 대체할 수 있습니다.

만약 부모 클래스와 자식 클래스가 있는 경우 서로를 바꾸더라도 해당 프로그램에서 잘못된 결과를 도출하지 않는 것입니다.

5) 인터페이스 분리 원칙 (ISP)
특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
즉, 클라이언트가 필요하지 않는 기능을 가진 인터페이스에 의존해서는 안되고, 최대한 인터페이스를 작게 유지해야합니다.

6) 의존성 역전 원칙 (DIP)
프로그래머는 추상화에 의존해야지, 구체화에 의존하면 안된다.

높은 계층의 모듈(도메인)이 저수준의 모듈(하부구조)에 의존해서는 안된다.

  • 고수준 계층의 모듈(도메인)은 저수준 계층의 모듈(하부구조)에 의존해서는 안된다. 둘 다 추상화에 의존해야 한다.
  • 추상화는 세부 사항에 의존해서는 안된다. 세부 사항은 추상화에 의존해야 한다.
profile
To Infinity and Beyond

0개의 댓글