1. 프로그래밍 패러다임 (Programming Paradigm)
1.1 패러다임 (Paradigm)
우리가 일상에서 '패러다임이 전환되었다 (paradigm shift)'라는 표현을 많이 사용하고 있는데, programming paradigm을 살펴보기 전에 패러다임이 무엇인지 알아보자.
위키피디아에 따르면, 패러다임(paradigm)은 '어떤 한 시대 사람들의 견해나 사고를 근본적으로 규정하고 있는 테두리로서의 인식의 체계, 또는 사물에 대한 이론적인 틀이나 체계를 의미하는 개념'이다. (어떤 사물을 바라보는 사고의 틀이나 체계)
대표적인 패러다임의 예로, '천동설'과 '지동설'이 있다. 우리가 천문학을 이해하고, 바라보는 관점을 천동설은 '지구가 중심이다'라는 관점을 제시한 것이고, 지동설은 '태양이 중심이다'라는 관점을 제시해준 것이다.
1. 2 프로그래밍 패러다임 (Programming Paradigm)
프로그래밍 분야에서도, paradigm은 우리가 프로그래밍 방식을 이해하는 관점을 갖게 해 준다. 우리가 어떻게 프로그래밍할 것인지에 대한 인식의 체계를 제공해주는 것이다.
programming paradigm은 프로그램, 프로그래밍 언어를 구성하는 방식을 이해할 수 있는 관점을 갖게 해 준다. programming paradigm을 잘 이해하고 있다면, 좋은 프로그램을 만드는 데에 도움이 된다.
프로그래밍 분야에서, 여러 서로 다른 paradigm이 공존하고 있다.
C++ 같은 경우, 절차 지향 언어인 C에 객체 지향 기능을 추가한 멀티 패러다임 언어 (Multi-Paradigm Language)이다. Scalar는 처음 만들어졌을 때부터, 객체 지향 기능과 함수형 기능을 결합한 멀티 패러다임 언어이다. 이외에도 절차 지향, 객체 지향, 함수형 패러다임을 모두 지원하는 Python도 멀티 패러다임 언어이다.
이처럼 특정한 paradigm만을 고집하는 것이 아니라 여러 paradigm의 장점들을 조합해 사용하고 있다.
- 명령형 (Imperative) 프로그래밍 (Pascal, C) : '어떻게 (HOW)'에 집중
- 절차적 (Procedural) 프로그래밍 (C, ALGOL)
- 객체 지향 (Object-Oriented) 프로그래밍 (Java, C++, Python)
- 선언형 (Declarative) 프로그래밍 (HTML, SQL) : '무엇을 (WHAT)'에 집중
- 함수형 (Functional) 프로그래밍 (Scala, Rust)
- 구조적 (Structured) 프로그래밍 (Pascal, C)
- 객체 기반 (Object-Based) 프로그래밍 (JavaScript, C#)
- 이벤트 기반 (Event-driven) 프로그래밍
해당 글에서는, 프로그래밍 패러다임(programming paradigm) 중 절차적, 객체 지향 프로그래밍에 관하여 알아보고자 한다.
1.3 폴리글랏 프로그래밍 (Polyglot Programming)
폴리글랏(polyglot)은 다국어를 구사하는 것을 의미한다. Polyglot Programming은 '여러 프로그래밍 언어를 자유롭게 사용하는 것'이다. 여러 프로그래밍 언어를 배움으로써 다양한 프로그래밍 패러다임을 이해하고, 우리가 해결해야 하는 다양한 문제를 해결하는 데에 도움이 된다.
polyglot programming은 선택이 아니라 필수라고 생각한다. 글로벌 시대에 모국어 외에 외국어를 배우는 것과 같이, 개발자도 다양한 프로그래밍 언어들을 배우는 것이 중요하다고 본다.
2. 절차적 프로그래밍 (Procedural Programming; PP)
객체 지향 프로그래밍 (OOP)를 살펴보기 전에, OOP 프로그래밍 패러다임이 등장하기 전의 프로그래밍 패러다임인 절차적 프로그래밍에 관하여 알아보자.
2.1 절차적 프로그래밍 (Procedural Programming; PP) 특징
절차적 프로그래밍 (procedural programming)은 프로시저 (procedure; also known as routine, subroutine, function,...) 호출을 기반으로 하고 있는 프로그래밍 패러다임 (프로시저 호출, 각 프로시저에 대한 코드 세트로 구성)이다.
프로시저 (procedure)는 일반적으로 의미 없는 결과를 돌려주는 함수, 즉 return값이 없는 함수다. (Python에서, procedure은 None값을 반환한다. https://docs.python.org/ko/3/reference/simple_stmts.html)
1. 하향식 접근 (Top-Down Approach)
2. 사전 정의된 함수 (Pre-defined Function)
3. 지역 변수 (local variable) : 정의된 함수 내부 (local scope)에서만 사용될 수 있는 변수
4. 전역 변수 (global variable) : 정의된 함수 외부에 선언되는 변수, 전역 변수는 지역 변수와 달리 모든 함수에서 사용될 수 있다.
5. 프로그래밍 라이브러리 (programming library) : 코드 모음인 사용자 정의 라이브러리를 만들 수 있다.
6. 모듈화 (modularity) : 두 개의 상이한 시스템이 상이한 작업을 수행하지만, 더 큰 작업을 먼저 끝내기 위해 함께 그룹화
2.2 구조적 프로그래밍 (Structured Programming)
1966년 Corrado Böhm과 Giuseppe Jacopini이 ACM에 발표한 논문에 소개된 Structured Program Theorem에서, 하위 프로그램을 3가지 제어 구조 (control structure)인 sequence, selection, iteratioin만을 활용해 다시 실행할 수 있다고 증명했다. (프로그램 실행 단순화)
1968년, Dijkstra가 발표한 논문 Go To Statement Considered Harmful 에서 GOTO문을 많이 사용하면 일명 '스파게티 코드'가 발생하고, GOTO문으로 인한 갑작스러운 순차 진행으로의 변경 등 문제점을 해결하기 위해 구조적 프로그래밍이 만들어졌다.
+) DRY (Don't repeat yourself) 원리 : 중복 코드 피해라
1. 시퀀스 (Sequence) : 순서대로 명령문 수행
# Python
x = 3
y = 4
z = x + y
print(z)
하위 프로그램을 실행한 후, 그 다음 하위 프로그램을 실행한다.
2. 선택 (Selection) : If-else 조건문
x = 1
if (x % 2 == 0):
print('짝수입니다')
boolean에 따라 두 개의 하위 프로그램 중 하나를 선택해 실행한다.
3. 반복 (Iteration) : 조건이 True이면 반복
x = 10
while (x < 100):
print(x)
x += 1
boolean이 True면, 프로그램을 반복적으로 실행한다.
3. 객체 지향 프로그래밍 (Object-Oriented Programming; OOP)
3.1 객체 지향 프로그래밍 (OOP) 구조
객체 지향 프로그래밍(OOP)는 data, object를 중심으로 설계하는 프로그래밍 패러다임이다. object는 고유한 속성이 있는 data field로 정의할 수 있다. Top-down이 아니라 Bottom-up 방식이다.
1. 클래스 (Class)
각각의 object, attribute, method에 대한 blueprint 역할을 하는 사용자 정의 데이터 타입이다.
2. 객체 (Object)
특정 데이터로 생성된 class의 instance.
실제 object이거나 추상화된 object일 수 있다.
3. 메서드 (Method)
class 안에 정의되는 함수로, object의 동작을 나타낸다. 각각의 메서드는 instance obeject에 관한 참조로 시작된다.
4. 속성 (Attribute)
object의 state를 나타낸다. object는 attribute field에 저장된다.
- 프로퍼티 (Property) vs 속성 (Attribute)
https://blog.finxter.com/python-property-vs-attribute/
https://stackoverflow.com/questions/47296982/what-is-the-difference-between-a-class-attribute-and-property
3.2 OOP 특징
1. 추상화(Abstraction)
예로 들어, '교촌', 'BBQ', '굽네'가 있다면, '치킨'이라는 공통점을 찾아 한 집합으로 만드는 것이다.
각 object의 구체적인 개념에 집중하는 것이 아니라 추상적인 개념에 집중함으로써 유연한 설계를 지원해준다.
2. 캡슐화(Encapsulation)
- 응집도 (Cohesion) : class 또는 module 안의 object들이 얼마나 밀접한지 정도.
- 결합도 (Coupling) : 어떤 기능을 수행하는 데 다른 class 또는 module에 얼마나 의존적인지 정도
응집도가 높고, 결합도가 낮도록 설계하는 것이 좋은 설계인데, 캡슐화가 이를 지원한다.
캡슐화는 결합도를 낮게, 즉 의존성을 낮추는 데에 도움을 준다. 한 곳에 변화가 일어나더라도, 다른 곳에 미치는 영향을 최소화한다. 타임캡슐을 생각하면, 추억이 담긴 물건을 캡슐에 넣어 숨기는 것처럼, 캡슐화는 object가 내부적으로 기능을 어떻게 구현하는지를 숨기는 것이다.
- 정보 은닉 (Information Hiding) : 필요 없는 정보는 외부에 접근하지 못하도록 제한하는 것
결합도가 높으면, 즉 다른 class나 module에 대해 의존도가 높으면, 객체 지향 방식으로 설계하는 의미가 없으므로, 의존도를 최대한 낮게 만드는 것이 중요하다.
3. 상속(Inheritance, 일반화 관계; Generalization)
상속을 통한 재사용 문제점
1. 상위 클래스 변경이 어려움
2. 불필요한 클래스 증가
3. 상속이 잘못될 수 있다 (상속 받는 클래스가 부모 클래스와 IS-A 관계 아닐 때)
-> 객체 조립 (Composition)
필드에서 다른 객체 참조
다른 종류의 클래스 상속할 때는 객체 조립 사용 추천
- IS-A 관계일 때
- 재사용이 아니라 expand하고 싶을 때
4. 다형성(Polymorphism)
서로 다른 class의 object가 같은 message를 받았을 때, 각자의 방식으로 동작하는 능력이다.
부모 클래스의 method를 자식 클래스가 Overriding (재정의)해서 자신에게 맞게 활용하는 것이다.
- 오버라이딩 (Overring) vs 오버로딩 (Overloading)
3.3 OOP의 5대 원칙 (SOLID)
S : SRP (Single Responsibility; 단일 책임 원칙)
object는 단 하나의 책임을 져야 하며, class를 변경하는 이유는 단 하나여야 한다.
만일 SPR를 지키지 못한다면, 한 책임의 변경에 의해 다른 책임과 관련된 코드에 영향을 미칠 수 있다.
O : OCP (Open-Closed; 개방-폐쇄 원칙)
기존 코드를 변경하지 않으면서 (Closed), 기능을 추가할 수 있도록 (Open) 설계해야 한다.
L : LSP (Liskov Substitution; 리스코프 치환 원칙)
상속 (Inheritance, 일반화 관계; Generalization)에 관한 원칙으로, 자식 클래스는 최소한 자신의 부모 클래스에서 가능한 행위를 수행할 수 있어야 한다.
I : ISP (Interface Segregation; 인터페이스 분리 원칙)
Interface를 Client에 특화되도록 분리시키라는 원칙이다.
D : DIP (Dependecy Inversion; 의존 역전 원칙)
쉽게 변화하지 않는 것, 거의 변화가 없는 것에 의존하라는 원칙이다.
3.4 절차적 프로그래밍 vs 객체 지향 프로그래밍
Reference
https://loosie.tistory.com/834
https://www.oreilly.com/radar/multi-paradigm-languages/
https://www.techtarget.com/searchapparchitecture/definition/object-oriented-programming-OOP
https://gyoogle.dev/blog/computer-science/software-engineering/Object-Oriented%20Programming.html
https://www.geeksforgeeks.org/differences-between-procedural-and-object-oriented-programming/
https://condor.depaul.edu/sjost/it236/documents/structured.htm
https://www.sciencedirect.com/topics/computer-science/structured-programming
댓글