새소식

반응형
Back-end/Spring

[Spring] Part 1-3-2. 나만의 MVC 프레임워크 만들기 | 객체지향 개념 다지기 + 실습

  • -
반응형

2. 객체 지향 개념 다지기

객체 지향이란?

사실, 이 질문에 대한 정답은 존재하지 않는 것 같습니다. 그말인 즉슨, 각자 자신만의 객체 지향을 생각하는 신념(?)과 같은 것이 있을 뿐이고 프로그래밍에 정답이 없는 것과 마찬가지입니다.

 

하지만 중요한 점은 여러분들이 자신있는 언어에 대해서 자신만의 견해를 가지고 대답을 할 수 있는지가 중요한 것입니다.

 

객체지향에 한 견해에 대해 말씀드리기 전에 먼저 객체지향이 갖고 있는 4가지의 특징에 대해서 말씀드리려 합니다.

1. 추상화 (Abstraction)

2. 다형성 (Polymorphism)

3. 캡슐화 (Encapsulation)

4. 상속 (Inheritance) 

 

이 4가지는 객체지향을 다른 패러다임과 구분짓는 중요한 특징입니다. 각각에 대해 간단한 설명을 해 보겠습니다.

 

 

추상화

  • 불필요한 부분을 제거함으로써 필요한 핵심만 나타낸 것
  • 일반화 혹은 단순화라고도 함.
  • 목적은 복잡성을 낮추는 용도

 

다형성

  • 다양한 형태를 가지는 것
  • 하나의 타입으로 여러 종류의 객체를 참조하는 것

 

캡슐화

  • 객체 내부의 세부사항을 외부로부터 감추는 것
  • 목적은 인터페이스만 공개해서 변경하기 쉬운 코드를 만들기 위함.

 

상속

  • 부모로부터 물려받는 것

 


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

다음은 훌륭한 객체지향 코드를 작성할 수 있는 원칙입니다.

 

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

  • 하나의 책임을 가진다.

2. OCP: Open/Closed Principle (개방 폐쇄의 원칙)

  • 확장에는 열려있고 변경에는 닫혀있다.
  • 즉, 기존코드를 변경하지 않고 기능을 추가할 수 있어야 한다.

3. LSP: Liskov's Substitution Principle (리스코프 치환의 원칙)

  • 상위 타입의 객체를 하위 타입의 객체로 치환해도 동작에 전혀 문제가 없어야 한다.

4. ISP: Interface Segregation Principle (인터페이스 분리의 원칙)

  • 많은 기능을 가진 인터페이스를 작은 단위로 분리시킴으로써 클라이언트에게 필요한 인터페이스들만 구현하도록 한다.
  • 이를 통해, 클라이언트가 사용하지 않는 기능에 의존하게 되면, 예상하지 못한 문제가 발생하는 것을 예방할 수 있다.


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

  • 의존관계를 맺을 때 자주 변경되는 쪽이 아니라, 변경이 거의 일어나지 않는 쪽에 의존한다.
  • 자기보다 변하기 쉬운 것에 의존하게 되면 변화의 영향을 많이 받기 때문에 추상화 된 인터페이스나 상위 클래스를 두어서 변화의 영향을 많이 받지 않게 하기 위한 것이다.

 

하지만, 많은 사람들이 앞서 살펴본 객체지향의 4가지 특징이나 5가지 설계 원칙에 대해서는 각자 나름대로의 견해를 가지고 있지만 객체지향에 대한 질문에 대해서는 대답을 명확하게 못하는 경우가 많습니다.

 

강의에서 제시되는 객체지향의 설명은 다음과 같습니다.

 

객체 지향 패러다임

객체지향이란 "적절한 객체에게 적절한 책임을 할당하여 서로 메시지를 주고 받으며 협력하도록 하는 것" 자체를 말하는 것입니다.

 

그리고 객체지향이 등장하게된 배경은 점점 증가하는 SW(Software) 복잡도를 낮추기 위해 객체지향 패러다임이 대두되었습니다.

 

개인적으로 생각하는 두 가지 중요 포인트는 다음과 같습니다.

  • 이름 자체가 객체 지향인 만큼 클래스가 아닌 객체에 초점을 맞추는 것
  • 객체들에게 얼마나 적절한 역할 책임을 할당하는지

이 부분은 개념적으로 설명은 드렸지만 이와 관련된 코드는 다시한번 아래에서 살펴보도록 할 것입니다.

 

 

절차지향  프로그래밍 vs. 객체지향 프로그래밍

두 패러다임을 구분 짓는 요소는 다음과 같은 두 가지가 있습니다.

  • 책임이 한 곳에 집중 돼 있는 방식 (getter)
  • 책인이 여러 객체로 적절히 분산되어 있는 방식

 

책임이 한 곳에 집중 되어 있다면 절차지향,
책임이 여러 객체로 적절히 분산되어 있다면 객체지향으로 생각할 수 있는 것입니다.

 

즉, 하나의 메소드에서 getter를 통해 값을 가져 온 다음에 이곳에서 어떤 모든 처리가 집중되어 있다면 절차지향이지만,

getter로 무언가를 가져와서 처리하는 것이 아닌 해당 책임을 가진 객체에게 메세지를 통해 협력하도록 구현하는 방식을 객체지향 방식으로 보는 것입니다.

 

high cohesion, loose coupling

객체지향 설계에 있어서, 가장 좋은 표현은 high cohesion, loose coupling 이라고 합니다. 한국어 뜻은 높은 응집도, 낮은 결집도 인데요.

이 부분을 객체지향 설계를 할 때 가장 염두에 두면 좋습니다.

 

이는 서랍 정리라는 개념으로 비유할 수 있습니다.

 

응집도가 높은, 즉 서로 비슷한 것끼리는 하나로 모아놓습니다.

그리고 다른 성격의 것들은 분리시킴으로써 비슷한 것들끼리는 응집도를 높이고 서로 다른 것들끼리는 분리를 시키는 것을 말하고 싶었습니다.

 

그렇다면 이렇게 하면 무엇이 좋은 것일까요?

 

응집도가 높은 것들끼리 모아놓으면 무언가 변경이 되었을 때, 변경의 포인트가 하나로 집중될 수 있다는 것입니다. 즉, 파악해야 할 영향 범위가 굉장히 한 곳에 집중되어 있다는 것입니다.

 

우리는 프로그래밍을 하다보면 수정에 대한 요구사항을 받을 때가 있는데, "영향 범위를 모르겠어요", "어디까지 영향을 주는지 모르겠어요" 등의 표현을 가끔 쓰는 데요. 이러한 표현을 쓰게 된 것 자체에는 객체지향을 온전히 사용하지 못했다는 것을 반증해 주는 표현이라고 생각합니다.

 

객체지향에 있어서는 요구사항이 들어왔을 때 특정 한 부분만 수정을 하면 된다는 것은 응집도가 높다는 부분이고, 

어떤 변경이 생겼을 때, 다른 곳에 영향을 끼치지 않는다면 낮은 결합도라고 생각합니다.

 

즉, 어떤 변화가 생겼을 때 다른 곳에 미치지 않는다면 high cohsion, loose coupling 인 것입니다.

 

생각해보면 이 표현은 유지보수와 굉장히 밀접한 관련이 있습니다. 즉, 객체지향 설계를 하는 이유는 어떠한 변경이 생겼을 때 아주 빠르게 그리고 높은 응집도와 낮은 결집도를 가지고 유연하게 대응할 수 있기 때문이라고 생각합니다.

 

설계 순서

1. 도메인을 구성하는 객체에는 어떤 것들이 있는지 고민

 

2. 객체들 간의 관계를 고민

 

3. 동적인 객체를 정적인 타입으로 추상화해서 도메인 모델링 하기

  • 클래스는 공통적인 상태와 행동을 가진 객체들은 추상화 한 것, 이를 통해 복잡성을 낮춤

 

4. 협력을 설계

 

5. 객체들을 포괄하는 타입(즉, 클래스)에 적절한 책임을 할당

  • 즉, 클라이언트와 협력할 수 있는 public interface를 정의한다.

 

6. 구현하기

  • 이런 public interface를 구현

 

참고

  • 객체지향 세계에서는 모든 객체가 능동적인 존재

 

3. 객체지향 프로그래밍 실습

사칙 연산 계산기

 

학점 계산기

  • 요구 사항
    • 평균학점 계산 방법 = (학점수 x 교과목 평점)의 합계/수강신청 총학점 수
    • MVC 패턴(Model-View-Controller) 기반으로 구현한다.
    • 일급 컬렉션 사용

 

인사관리 시스템 구현

음식점에서 음식 주문하는 과정

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.