언어를 처음 배우기 시작하면, "객체지향 프로그래밍이다"는 말을 자주 볼 수 있다.
내가 아는 객체라면 { } 객체 타입 이것밖에 안떠오르는데 객체지향 프로그래밍이 도대체 무엇일까?
객체지향와 절차지향를 비교해서 이해해볼 수 있다.
두 개념을 알기 위해서는 '프로시저'와 '의존'을 알아야 한다.
'프로시저 '와 '의존성 '을 먼저 짚고 넘어가보자.
프로시저
프로시저는 데이터를 활용해서 로직을 처리하는 함수를 말한다.
특정 프로세스를 절차적으로 기술해놓은 것으로 절차적으로 처리하고자 하는 명령어들의 집합을 의미한다.
추가적으로, 프로시저와 함수의 차이는 무엇일까?
함수도 '명령어 집합'이라는 의미에서 일종의 프로시저로 볼 수 있다.
둘을 비교하는 것이 애매하기는 하나 강력한 차이라면 'side effect'가 있다.
side effect 란?
side effect는 '부작용'으로 꼭 부정적인 의미를 내포하지는 않는다.
실행 중에 어떤 객체를 접근해서 변화가 일어나는 행위(라이브러리 I/O, 객체 변경 등)를 말한다.
이는 의도하지 않은 결과를 내어 잠정적인 버그의 원인이 되기도 한다.
ex.
1) x = 3 + 4
-> 1개의 side effect 존재. x의 값이 변경되었기 때문
2) y = x++
-> 총 2개의 side effect 존재. x++에서 x가 한 번 변하고, x 값 대입으로 y가 한 번 변함.
3) 3 + 4
-> side effect가 없음.
출처: https://lemeraldl.tistory.com/entry/SIDE-EFFECT
함수형 프로그래밍에서 'side effect'가 중요한 개념으로 'side effect'가 없도록 구현을 해야한다.
즉, 프로그래밍 관점에서 프로시저의 경우에는 'side effect'를 가질 수 있지만 순수 함수는 'side effect'가 없도록 만들어야 한다.
※ 데이터베이스 관점에서는 프로시저와 함수를 구분해서 사용한다.
프로시저는 특정 작업을 수행하기 위한 절차이며 return 값이 있을 수도, 없을 수도 있으며 심지어는 여러개를 가질 수도 있다. 또한 DB 단에서 기술을 하는 개념이며 단독으로 문장 구성이 가능하고 수식내에서는 사용이 불가능하다.
CREATE OR REPLACE PROCEDURE 프로시저 이름 (
매개변수명1 [ IN || OUT || INOUT ] 데이터타입
, 매개변수명2 [ IN || OUT || INOUT ] 데이터타입 ... )
IS||AS
변수, 상수 등 선언 ( 선언부 )
BEGIN
실행 문장 ( 실행부 )
EXCEPTION 문장 //필수아님
END ;
그에 비해 함수는 프로시저의 각 프로세스를 수행하기 위해 필요한 기능들을 의미한다. 특정 계산을 수행하기 때문에 반드시 return 값이 있어야 하며 오직 하나의 값만 가질 수 있다. 또한 Client 단에서 기술을 하고 단독으로 문장 구성이 불가능하며 수식 내에서만 사용이 가능하다.
CREATE OR REPLACE FUNCTION 함수 이름
( 매개변수명1 매개변수1타입,
매개변수명2 매개변수2타입 ... )
RETURN 데이터타입
IS||AS
변수, 상수 등 선언 ( 선언부 )
BEGIN
실행 문장 ( 실행부 )
RETURN 반환값 //필수
EXCEPTION 문장 //필수아님
END ;
의존성
의존성은 값으로 다른 객체를 참조하는 것을 의미한다.
의존 관계를 외부에서 결정하고 주입하는 것을 '의존성 주입(DI)'이라고 한다.
의존성 주입이 등장하면 '의존 역전 원칙(DIP)'도 같이 등장하는데 이는 다른 게시글에서 다루는 것으로 하겠다.
다시 본론으로 돌아와서,
'절차지향'이라고 하면 순차적으로 처리될 것 같고, 보통 절차지향과 객체지향을 비교하니까
객체지향은 그 반대인 순차적으로 처리하지 않는 방식으로 느껴진다. 그러나 객체지향도 마찬가지로 순차적으로 처리하는 방식이라고 한다. 또한 절차지향과 객체지향이 완전히 반대되는 개념이 아니다.
본격적으로 두 프로그래밍 방식을 비교해보기 위해
< 데이터 A, B, C, D > 와 < 프로시저 A, B, C, D >가 있다고 가정해본다.
* "⇒": 의존
프로시저 A ⇒ A, C 데이터 (프로시저 A는 A, C 데이터에 의존)
프로시저 B ⇒ A, B 데이터
프로시저 C ⇒ B, C 데이터
그럼 절차지향부터 알아보자.
절차지향 프로그래밍(POP)
프로시저 B가 A, B 데이터에 의존하다가 모르고 A를 지웠다고 생각해보자.
그럼 프로시저 A는 동작하지 않는다. 프로시저 A는 A를 A'로 변경을 해서 사용을 해야할 것이다.
하나의 프로시저의 동작이 다른 프로시저에도 영향을 준다.
이것이 절차지향 프로그래밍의 핵심이다.
프로시저가 데이터에 직접 의존하도록 코드가 구성되기 때문에 데이터가 변경되면 프로시저도 변경 될 수 있다.
예시 언어: C, Pascal
객체지향 프로그래밍(OOP)
객체지향 프로그래밍에는 '객체'가 등장한다.
(가)객체는 A, B 데이터
(나)객체 C, D 데이터
프로시저 A가 데이터 A, C를 사용하기 위해 (가), (나) 객체에게 데이터를 넘겨달라고 요청했다고 하자.
(가)객체는 A, (나)객체는 C를 넘겨줄 것이다. 근데 프로시저 A가 (가)에게서 받은 A를 지운다면?
그래도 데이터 A는 남아있고 (가) 객체에도 영향이 없다. 이것이 절차지향과의 차이점이다.
A 데이터를 필요로 하는 프로시저 B가 (가)객체에 A 데이터를 요청해도 잘 동작된다. 여기서의 (가)객체는 다른 메모리에 있는 객체라서 가능한 것이다.
객체지향 프로그래밍은 다른 프로시저에 영향이 가는 절차지향 프로그래밍의 단점을 보완하기 위해서 등장한 방식이다.
예시 언어: C++, Java, Python
정리하면,
절차지향은 프로시저가 데이터에 직접 의존을 해서 데이터에 변경이 있으면 프로시저에도 영향이 간다.
객체지향은 프로시저가 데이터에 직접 의존하지 않는다. 데이터에 의존하지 않고 객체를 통해서 프로그래밍이 가능하다.
객체 안에 데이터와 프로시저가 있어서 객체끼리 의사소통을 하는 형태이다.
※ 클래스 vs 인스턴스
클래스는 인스턴스를 생성하기 위한 틀로 '붕어빵틀'에 비유할 수 있다.
인스턴스는 메모리 혹은 객체라고 하는데 '붕어빵'에 비유할 수 있다.
즉 객체지향에서 객체(붕어빵)는 붕어빵 틀만 같은 것이지 사실은 다른 붕어빵인 셈이다.
참고자료
https://thenicesj.tistory.com/445
'IT Study > CS' 카테고리의 다른 글
[Backend] UUID vs ULID vs snowflake ID (0) | 2023.12.16 |
---|---|
[Frontend] nginx를 사용해서 VM에서 배포하기 (+ CodeSpliting) (0) | 2023.11.29 |
[Front] 디바운싱과 쓰로틀링 (1) | 2023.11.22 |
[CS] Stateful vs Stateless 차이 (0) | 2023.11.15 |
[Back] 계속 헷갈리는 토큰 vs 쿠키 vs 세션 (1) | 2023.11.14 |