etc.
[Programming Paradigm] 선언형, 함수형, 객체지향, 절차형 프로그래밍
mooni_
2025. 4. 9. 11:26
개발 방법론 정리
프로그래밍에는 다양한 패러다임(Paradigm)이 존재하며, 각각의 철학과 구현 방식이 다릅니다. 이번 글에서는 대표적인 개발 방법론들을 간단한 코드 예제와 함께 정리해보았습니다.
1. 선언형 프로그래밍 (Declarative Programming)
- 정의: “프로그램은 함수로 이루어진 것이다” 라는 철학이 담긴 프로그래밍 패러다임입니다.
- 특징: 무엇을 할 것인지를 설명합니다. 어떻게 할지는 중요하지 않습니다.
2. 함수형 프로그래밍 (Functional Programming)
- 선언형 프로그래밍의 일종입니다.
- 순수 함수를 조합하여 로직을 구성하고, 고차 함수를 통해 재사용성과 추상화를 극대화합니다.
- JavaScript에서는 함수가 일급 객체이기 때문에 함수형 스타일을 유연하게 적용할 수 있습니다.
const list = [1, 2, 3, 4, 5, 11, 12]
const ret = list.reduce((max, num) => num > max ? num : max, 0)
console.log(ret)
reduce()는 배열의 값을 누적해 하나의 값으로 줄이는 순수 함수입니다.
💡 주요 개념
순수 함수(Pure Function)? 출력이 오직 입력값에만 의존하고, 부작용이 없는 함수
const pure = (a, b) => {
return a + b
}
고차 함수(Higher-Order Function)? 함수를 인자로 받거나, 함수를 반환하는 함수
일급 객체(First-Class Citizen)? 함수를 변수에 할당하거나, 인자로 넘기거나, 반환할 수 있습니다.
- 변수나 메서드에 함수를 할당할 수 있음
- 함수 안에 함수를 매개변수로 담을 수 있음
- 함수가 함수를 반환할 수 있음
3. 객체지향 프로그래밍 (Object-Oriented Programming)
- 프로그램을 객체의 집합으로 표현하며, 객체 간의 상호작용을 통해 로직을 구성합니다.
- 객체 내부의 데이터와 메서드를 하나로 묶어 처리합니다.
const ret = [1, 2, 3, 4, 5, 11, 12]
class List {
constructor(list) {
this.list = list
this.mx = list.reduce((max, num) => num > max ? num : max, 0)
}
getMax() {
return this.mx
}
}
const a = new List(ret)
console.log(a.getMax())
💡 객체지향의 4대 특징
- 추상화 (Abstraction) : 복잡한 시스템으로부터 핵심 개념만 간추립니다.
- 캡슐화 (Encapsulation) : 데이터와 메서드를 하나로 묶고, 내부 구현을 숨깁니다.
- 상속성 (Inheritance) : 상위 클래스의 기능을 하위 클래스가 물려받아 사용하거나 확장합니다.
- 다형성 (Polymorphism) : 동일한 메서드가 다른 방식으로 동작할 수 있습니다.
- 정적 다형성: 오버로딩
- 동적 다형성: 오버라이딩
오버로딩(Overloading)?
class Person {
public void eat(String a) {
System.out.println("I eat " + a);
}
public void eat(String a, String b) {
System.out.println("I eat " + a + " and " + b);
}
}
public class CalculateArea {
public static void main(String[] args) {
Person a = new Person();
a.eat("apple");
a.eat("tomato", "phodo");
}
}
메서드 이름은 같지만, 매개변수의 개수나 타입이 다릅니다. 컴파일 시점에 결정됩니다.
오버라이딩(Overriding)?
class Animal {
public void bark() {
System.out.println("mumu! mumu!");
}
}
class Dog extends Animal {
@Override
public void bark() {
System.out.println("wal!!! wal!!!");
}
}
public class Main {
public static void main(String[] args) {
Dog d = new Dog();
d.bark();
}
}
상속받은 메서드를 재정의하여 동작을 바꿉니다. 런타임 시점에 결정됩니다.
객체지향 설계 원칙 (SOLID)
- SRP(단일 책임 원칙) : 클래스는 하나의 책임만 가져야 합니다.
- OCP(개방-폐쇄 원칙) : 확장에는 열려 있고, 변경에는 닫혀 있어야 합니다.
- LSP(리스코프 치환 원칙) : 하위 클래스는 상위 클래스의 기능을 대체할 수 있어야 합니다.
- ISP(인터페이스 분리 원칙) : 하나의 일반적인 인터페이스보다는 여러 개의 구체적인 인터페이스로 분리해야 합니다.
- DIP(의존 역전 원칙) : 고수준 모듈이 저수준 모듈에 의존하지 않도록 합니다.
4. 절차형 프로그래밍 (Procedural Programming)
- 프로그램을 순차적인 명령어의 흐름으로 작성하는 방식입니다.
- 모듈화가 어렵고, 유지보수가 힘든 단점이 있습니다.
const ret = [1, 2, 3, 4, 5, 11, 12]
let a = 0
for(let i = 0; i < ret.length; i++) {
a = Math.max(ret[i], a)
}
console.log(a)
마무리
프로그래밍 패러다임은 단순한 문법을 넘어서 문제 해결 방식에 대한 철학입니다.
실무에서는 하나의 패러다임만 사용하는 경우보다, 상황에 따라 적절히 조합하여 사용하는 경우가 많습니다.