될때까지

((함수형 프로그래밍)) 프로그래밍 패러다임, 절차형 프로그래밍, 객체지향 프로그래밍, 함수형 프로그래밍 본문

학습/개념정리

((함수형 프로그래밍)) 프로그래밍 패러다임, 절차형 프로그래밍, 객체지향 프로그래밍, 함수형 프로그래밍

랖니 2022. 9. 21. 14:14
728x90

프로그래밍 패러다임(Programming Paradigm)이란?

패러다임이란 '한 시대의 사람들의 견해나 사고를 근본적으로 규정하고 있는 인식의 체계. 또는 사물에 대한 이론적인 틀이나 체계'를 말한다. 위키피디아에 나온 이 뜻이 너무 어려워 다른 기고를 참고했다. 여기서는 '사물을 보는 방법, 문제를 삼는 방법, 문제를 푸는 방법의 총체'를 패러다임이라 일컫는다. 어떤 시대적 상황이나 현실을 바라보는 여러 종류의 인식의 틀 하나 하나를 패러다임이라고 할 수 있다.

💡 그렇다면 프로그래밍 패러다임이란?
프로그래머가 프로그래밍 관점을 갖게 하고 코드를 어떻게 작성할 지 결정하는 역할을 한다.
프로그래밍 하기 위한 방법/전략, 프로그래밍 스타일, 소프트웨어를 "어떻게" 구성해서 코딩할지 생각하는 방법이라 이해할 수 있겠다.

💡 다양한 프로그래밍 패러다임을 배워야 하는 이유는?
이제까지 해왔던 코딩 방식과 다른 스타일을 배운다는 것은, 여러가지 방법으로도 문제를 해결할 수 있는 사고력을 기른다는 뜻이다. 사고의 전환으로 문제를 바라보면 유연한 문제 해결 능력을 기를 수 있다.

프로그래밍 패러다임은 굉장히 많고 다양하지만
대표적이고 범용적인 "명령형 프로그래밍"과 "선언형 프로그래밍"의 2가지 범주로 나눌 수 있다.

 

명령형 프로그래밍(Impretarive Programming)

💡 어떻게(How) 할까에 초점

  • 절차적 프로그래밍 : 수행되어야 할 순차적인 처리 과정을 포함하는 방식 (C, C++)
  • 객체지향 프로그래밍 : 객체들의 집합으로 프로그램의 상호작용을 표현 (C++, Java, C#, Python)

선언형 프로그래밍(Declarative Programming)

💡 무엇(What)을 할까에 초점

  • 함수형 프로그래밍 : 순수 함수를 조합하고 소프트웨어를 만드는 방식 (클로저, 하스켈, 리스프)

=> 처음부터 함수형, 객체지향에 맞게끔 개발된 언어들도 있지만 시간이 지나면서 함수형 프로그래밍 특징이 추가된 언어들도 있다.
객체지향적 프로그래밍 언어에 가까운 파이썬, 자바스크립트도로도 함수형 프로그래밍이 가능한 이유다. 

=> 객체지향은 절차적 프로그래밍의 단점을 극복하기 위해 등장했고, 함수형은 객체지향 프로그래밍의 단점을 극복하기 위해 등장했다.

 

 

🔥 절차적 프로그래밍(Procedure Programming)

일이 순서대로 진행되는 프로그래밍 방식.

과거에는 지금과 같은 큰 규모의 HW, SW가 필요하지 않았다.
데이터에 대한 순서를 파악하고 필요 기능들을 함수로 만들어 순서대로 코드를 실행시켰다.

[장점]

  • 코드의 가독성이 좋다.
  • 컴퓨터의 처리 구조와 비슷해서 실행 속도가 빠르다.

하지만 점점 시대가 발전하면서 SW의 속도가 빨라졌고 이에 따라 코드들도 길어지고 복잡해졌다.

[단점]

  • 순서가 중요한 코드들이다보니 서로 유기적으로 연결이 되어 있어 유지보수 및 분석이 어렵다.
  • 문제해결을 위해 부분 수정이 아닌 전체 수정이 들어가야한다.

 

 

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

모든 데이터를 객체로 취급하여 객체가 처리 요청을 받았을 때, 객체 내부에 있는 기능을 사용해 요청을 처리하는 방식

💡 객체지향 프로그래밍의 특징

  1. 추상화(abstraction)란 공통적인 속성이나 기능을 묶는 것을 의미한다.
  2. 캡슐화(encapsulation)란 객체의 속성과 메소드를 하나로 묶고 일부를 외부에 감추어 은닉하는 것을 의미한다.
  3. 상속성(inheritance)이란 상위 부모 객체의 속성과 특징을 하위 객체가 물려받는 것을 의미한다.
  4. 다형성(polymorphism)은 하나의 메소드나 클래스가 다양한 방법으로 동작하는 것을 말한다.
    대표적으로 오버로딩, 오버라이딩이 있다.
  • 오버로딩 : 오버로딩은 같은 이름을 가진 메서드를 여러개 두는 것을 의미한다.
    메소드의 타입, 매개변수의 유형, 개수 등으로 여러개의 메소드를 둘 수 있다.
  • 오버라이딩 : 오버라이딩은 주로 메소드 오버라이딩을 말하며
    상위 클래스로부터 상속받은 메소드를 하위 클래스가 재정의하는 것을 의미한다.

=> 자바스크립트는 프로토타입이라는 프로퍼티와 메소드를 객체에 상속시켜주는 객체를 가지고 있다.

[장점]

  • 상속과 모듈화를 통해 코드의 재사용성이 높아졌다.
  • 유지보수가 쉽고 확장성이 좋다.
    • 클래스 내부의 변수나 메소드 해당 부분만 수정하면 되기 때문
  • 보안성이 좋고 분석과 설계의 전환이 쉽다.

[단점]

  • 개발속도가 느리다.
    • 생성할 객체를 정확하게 이해하고 큰 그림을 그려야하기 때문에 설계단계부터 많은 시간이 소모된다.
  • 실행속도가 느리다.
    • 모든 것을 객체로 생각하기 때문에 메모리와 연산에 대한 비용이 많이 들어간다.

 

 

 

🔥 함수형 프로그래밍(Functional Programming)

'순수 함수'를 이용해 상태를 제어하는 게 아니라 빠른 처리에 초점을 둔 방식

배우는 데 어려워서 인기를 끌지 못했지만
최근에 빅데이터, 비트코인등의 발전으로 방대한 데이터를 빠르게 계산하는게 필요되는 요즘 사람들의 관심을 갖고 있다.

💡 함수형 프로그래밍의 특징

부수효과가 없는 순수함수를 1급 객체로 간주하여 파라미터로 넘기거나 반환값으로 사용할 수 있으며, 참조 투명성을 지킬 수 있다.

1. 순수 함수(Pure Function)

  • 함수의 인풋이 주어지면 항상 일관된 아웃풋이 나오는 함수(참조 투명성)
  • 함수의 실행이 프로그램의 실행에 영향을 미치지 않아야 하는 함수
  • 함수 내부에서 인자의 값을 변경하거나 프로그램 상태를 변경하는 side effect가 없는 함수
let num = 1;

function add(a) {
	return a + num;
}
function add(a,b) {
	return a + b;
}

 

2. 부수효과(Side Effect)

=> 컴퓨터 과학에서의 부작용은 결과값 이외의 다른 상태를 변경시킬 때 부작용이 있다고 표현한다고 함

  • 변수의 값이 변경됨
  • 자료구조를 제자리에서 수정함
  • 객체의 필드값을 설정함
  • 예외나 오류가 발생하며 실행이 중단된
  • 콘솔 또는 파일 I/O가 발생함

3. 비상태, 불변성(Stateless, Immutablility)

  • 함수에 인자로 전달된 데이터를 변경하면 안된다.
  • 부수효과를 만들지 않기 때문에 불변성을 유지한다.
  • 새로운 오브젝트를 만들어서 전달해야한다.
let person = {name : 'ellie', age : 20};

function increaseAge(person) {
    person.age = person.age + 1;
    return person;
}
let person = {name : 'ellie', age : 20};

function increaseAge(person) {
    return {...person, age : person.age+1};
}

4. expressions only

  • if, switch, for과 같은 구문을 사용하지 않는다.
let numbers = [1,2,3];

function multiply (numbers, multiplier) {
	for (let i = 0; i < numbers.length; i++) {
    	numbers[i] = numbers[i] * multiplier;
    }
}
let numbers = [1,2,3];

function multiply (numbers, multiplier) {
	return number.map(num => num * multipler);
}

 

5. 1급 객체(First-Class Object) & 고차 함수(Higher-order functions)

  • 1급객체 : 변수나 자료구조에 할당할 수 있다 / 다른 함수의 인자로 전달될 수 있다 / 다른 함수의 결과로서 리턴될 수 있다
  • 고차함수 : 함수를 인자로 받을 수 있고, 함수의 형태로 리턴할 수 있는 함수
  • 이 두가지 속성을 가지고 있어야 한다.
// first-class
const addTwo = a => a + 2;
const multiplyTwo = a = > a * 2;
const transform = numbers => numbers.map(addTwo).map(multiplyTwo);
console.log(transform[1,2,3,4]);
// [6, 8, 10, 12]
function double(num) {
  return num * 2;
}

// doubleNum 함수는 고차 함수이다. (다른 함수를 인자로 받음)
function doubleNum(func, num) {
  return func(num);
}

doubleNum(double, 5);

6. 참조 투명성(Referential Transparency)

  • 동일한 인자에 대해 항상 동일한 결과를 반환해야한다.
  • 참조 투명성을 통해 기존의 값은 변경되지 않고 유지된다.

[장점]

  • 외부에 있는 데이터에 의존하지 않고 데이터를 변경하지도 않는다.(부작용이 없다.)
  • 디버깅이 쉽다.
  • 불변성을 지향하기 때문에 프로그램의 동작을 예측하기 쉽다.(테스트 용이)

[단점]

  • 코드의 가독성이 좋지 않을수도 있다.
  • 반복이 재귀를 통해 이뤄지는데 무한루프에 빠질 수 있다.
  • 수학과 연관이 있기 때문에 배우는 데 시간이 오래걸리고 어렵다.
  • 순수함수를 사용하는 건 쉬울 수 있지만 조합하는 것이 어렵다.

 

 

* 참고 자료

https://st-lab.tistory.com/151

https://jongminfire.dev/%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%B4%EB%9E%80

https://velog.io/@majaeh43/%EC%A0%88%EC%B0%A8%EC%A7%80%ED%96%A5-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D

https://mangkyu.tistory.com/111

https://www.youtube.com/watch?v=4ezXhCuT2mw

728x90

'학습 > 개념정리' 카테고리의 다른 글

((OSI)) OSI 7 Layer란?  (1) 2022.10.03
((SoC, Layered Pattern)) 관심사의 분리, 레이어드 패턴  (0) 2022.09.27
((OAuth)) OAuth2.0이란?  (0) 2022.09.19
((Docker)) 도커가 뭐야?  (0) 2022.09.12
((git)) git flow  (0) 2022.09.05