[Spring] 2. OOP in Spring
1. 객체지향이란?
Java, Python 과 같은 프로그래밍 언어를 공부하다보면, 많이 등장하는 용어이기도 하다. 그렇다면 객체 지향은 무엇일까? 우선, 객체 지향의 등장을 알기에 앞서 절차지향이라는 용어 먼저 설명하고자 한다. 절차지향이란, C언어와 같이 실행하고자 하는 순서대로 코드를 입력하여 실행하는 방식을 의미하며, 이에 해당하는 언어는 절차지향 언어라고 부른다. 물론, 당시에는 프로그램 단위가 크지 않았고, 대체적으로 간단한 로직을 순차적으로 처리해 결과를 얻는 수준이였기에 문제가 되지 않았다.
하지만, 시간이 지남에 따라 컴퓨터가 발전하게 되고, 이로 인한 프로그램의 복잡도 역시 높아지게 되면서, 유지 보수 비용이나 개발 시간 등 다양한 부분에서 비효율적이였다. 이를 해결하기 위해 보다 효과적인 개발방식을 채택하게 되었고, 그것이 객체지향방식으로 개발하는 것이다.
그렇다면 객체지향 방식에 대해 알아보자. 이는 현실에 존재하는 사물을 있는 그대로 모델링하여, 행위와 속성을 정의하고, 정의한 객체가 중심이 되어 실제 사물이 동작하는 방식으로 설계하는 것을 의미한다. 이 때, 사물을 객체(Object) 라고 부르며, 객체가 갖는 속성이나 특징을 변수(Variable) 로, 객체가 하는 행위를 메소드(Method) 라고 부른다.
1) 객체의 3요소
그렇다면 객체라고 부르는 대상은 어떤 특징을 갖고 있을까? 크게 3가지 요소를 갖고 있으면, 객체로 정의할 수 있다. 그 3가지 요소는 아래의 내용과 같다.
(1) 상태 유지 (객체의 상태)
객체는 상태 정보를 저장하고, 유지되어야하며, 앞서 언급한 것처럼 속성은 변수로 정의된다. 따라서 속성값이 바뀌게 되면, 객체의 상태가 변경되기 때문에, 이러한 변경이 이루어지도록 해야한다.
(2) 기능 제공 (객체의 책임)
객체는 자신을 가지고 할 수 있는 일인 기능을 제공해야한다. 이는 앞서 언급한 것처럼 메소드라는 것으로 만들어진다. 또한 행위는 외부로부터 직접 속성에 접근하여 변경하는 것이 아니라 객체에서 제공하는 메소드로 기능이 제공되어야한다.
(3) 고유 식별자 제공 (객체의 유일성)
우리가 구현하는 객체는 생성될 때마다, 객체가 식별 가능하도록 고유한 식별자를 갖고 있어야한다. 일반적으로 카드번호, 계좌번호와 같이 속성을 이용해서 각각의 고유한 값을 줄 수 있는데, 최근에는 데이터베이스를 이용해서 기본키 등을 활용해 식별자를 주는 것도 가능하다.
2) 객체의 종류
객체는 실존 여부에 따라 물리 객체와 개념 객체로 나눌 수 있다. 아래에서 이 둘의 차이점을 알아보도록 하자.
- 물리적 객체
물리적 객체는 실제로 사물이 존재하는 것으로, 클래스로 정의한 객체를 의미한다.
- 개념적 객체
비즈니스 로직으로 처리하는 부분을 의미하며, 여러 객체를 서로 상호작용하도록 하며, 객체가 제공하는 연산 메소드를 통해 객체의 속성을 변경시키는 객체를 의미한다.
객체지향에서 대부분의 코딩은 각 객체에 긴으을 정의하고, 이를 비즈니스 로직으로 처리하는 서비스에서 객체의 메소드를 활용해, 여러 가지 조건을 확인 및 객체의 속성을 변경하는 작업을 수행한다. 이를 위해 각 객체의 속성에 대한 정의와 속성이나 상태를 변경할 수 있는 메소드들을 잘 정의하는 것이 중요하다.
2. 객체 지향의 특성
1) 갭슐화 (Capsulation)
객체의 속성을 보호하기 위해 사용되는 특성을 의미한다. 이는 메소드 설계에서 중요하다. 메소드 설계 시, 캡슐화가 적용되는 내용은 다음과 같다.
① 먼저, 속성이 선언되었으나, 이의 상태를 변경하는 메소드가 없다면 잘못된 속성이다.
② 실물 객체가 가진 기능을 모두 제공해야한다.
③ 각 메소드는 서로 관련성이 있어야 한다.
④ 객체 안의 메소드는 객체 안의 속성을 처리해야하며, 다른 객체를 전달받아 해당 다른 객체에 정의된 속성을 직접 처리된 속성을 직접 처리해선 안된다.
⑤ Getter / Setter
메소드 외부에서 내부 속성에 접근해 값을 변경하고자 할 경우, 직접 접근하는 것이 아니라, 사전에 만들어둔 Getter/Setter 메소드를 이용해서 접근 및 처리해야한다.
⑥ CRUD 메소드
데이터 처리를 위한 기본적인 CRUD 메소드를 제공해야한다.
⑦ 비즈니스 로직 메소드 비즈니스 로직 처리를 위한 메소드를 제공해야한다.
⑧ 객체 생명 주기 처리 메소드 destroy(), disconnect() 등 종료 및 소멸에 대한 메소드를 제공해야한다.
⑨ 객체의 영구성 관리 메소드 영구성(유효성) 속성에 대한 변경이 필요한 경우, 외부에서는 접근이 불가능하도록 private로 선언하며, 내부의 다른 메소드를 통해서 사용되도록 한다.
위와 같이 캡슐화를 통해 메소드를 구현할 경우 갖게 되는 장점은 아래 3가지가 있다.
① 객체지향의 패러다음 중 하나인 추상화를 제공한다. 이 때, 외부에서는 어떻게 동작하는 지 이해할 필요가 없으며, 단순 호출만으로 해당 기능을 실행할 수 있고, 이를 통해 객체 단위로 프로그램 설계가 가능하다.
② 한 객체에 관련된 속성 및 메소드는 모두 캡슐화의 형태로 제공되기 때문에, 객체의 모듈성과 응집도가 높아진다. 객체의 경우 단일 객체에만 영향을 주기에 재사용성이 높아진다.
③ 위의 2가지 이유에 따라, 유지보수의 효울성이 향상된다.
2) 상속
객체 지향에서의 상속은, 자식 클래스(하위 클래스)가 부모 클래스(상위 클래스)의 필드나 메소드를 그대로 받아서 사용할 수 있게 함으로써 객체들 간의 관계를 구축하는 방법으로, 속성의 상속이 아니라 하위로 내려갈 수록 구체화되는 것을 의미한다.
상속을 하는 이유는 잘 개발된 클래스를 재사용함으로서, 새로운 클래스를 만들 때 코드의 중복을 줄여준다. 때문에 확장성의 측면에서 유용한 기능이라고 할 수 있다. 또한 중복을 줄여주기 때문에 유지보수에도 용이한 기능이라고 할 수 있겠다.
3) 다형성
다형성이란, 하나의 개체가 여러 개의 형태로 변화는 것을 의미하며, 객체지향에서도 유사하게 사용할 수 있다. 주로, 오버라이딩을 통해서 다형성을 구현할 수 있다.
위의 그림에서처럼 자동차의 종류가 바뀔 수는 있고, 자동차 차량 내부 구조가 바뀔 수는 있지만, 기존 자동자의 역할만 동일하다면, 운전자는 차량에 상관 없이 운전할 수 있는 것과 동일하다.
외부에서는 내부 구현이 어떻게 변경되든 상관없이, 수행하는 역할이 동일하다면, 상관없이 사용할 수 있다.
4) 추상화
객체지향에서의 추상화란, 모델링을 의미한다. 즉, 구체적으로 공통적인 부분 혹은 특정 속성을 분리해서 재조합하는 것을 의미하며, 앞서 설명한 다형성, 상속 모두 추상화에 속한다고 볼 수 있다.
댓글남기기