클린 아키텍처: 세 가지 프로그래밍 패러다임을 읽고
클린 아키텍처를 읽으면서 특히 인상 깊었던 부분은 구조적 프로그래밍, 객체지향 프로그래밍, 함수형 프로그래밍이라는 세 가지 패러다임에 대한 설명이었습니다. 이 패러다임들은 우리가 소프트웨어를 설계하고 개발하는 방식에 깊은 영향을 미쳐왔습니다. 책에서 이를 어떻게 설명했는지, 그리고 제가 이해한 바를 정리해 보았습니다.
1. 구조적 프로그래밍 (Structured Programming)
가장 먼저 적용된 패러다임이자 현대 소프트웨어 개발의 기초를 다진 구조적 프로그래밍은 1968년 에츠허르 비버 데이크스트라에 의해 제안되었습니다.
당시에는 프로그램 내에서 무분별한 goto 문장이 사용되었는데, 이는 프로그램의 흐름을 지나치게 복잡하고 예측하기 어렵게 만들었습니다. 데이크스트라는 이를 문제로 지적하며, if/then/else와 do/while/until 같은 명확한 구조를 도입해 제어 흐름의 규칙을 정립했습니다.
이로 인해 코드의 가독성과 유지보수성이 크게 향상되었고, 구조적 프로그래밍은 프로그래밍 세계의 핵심적인 전환점이 되었습니다.
구조적 프로개밍은 제어흐름의 직접적인 전환에 대해 규칙을 부과 한다.
// 구조적 프로그래밍 (Structured Programming)
// 구조적 프로그래밍의 핵심은 명확한 제어 흐름입니다. if, for, while과 같은 구조를 활용해 프로그램의 흐름을 제어합니다. Java는 구조적 프로그래밍의 기본 원칙을 따릅니다.
public class StructuredExample {
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
int sum = 0;
// 명확한 흐름: 반복문을 사용해 배열의 모든 값을 더함
for (int number : numbers) {
sum += number;
}
// 조건문을 사용해 결과 출력
if (sum > 10) {
System.out.println("합계는 10보다 큽니다: " + sum);
} else {
System.out.println("합계는 10 이하입니다: " + sum);
}
}
}
// 이 코드에서는 for와 if를 사용하여 명확한 제어 흐름을 보여줍니다.
2. 객체지향 프로그래밍 (Object-Oriented Programming)
다음으로 도입된 패러다임은 객체지향 프로그래밍입니다. 흥미롭게도 이 패러다임은 구조적 프로그래밍보다 2년 앞선 1966년, **올레 요한 달(Ole-Johan Dahl)**과 **크리스텐 니가드(Kristen Nygaard)**에 의해 탄생했습니다.
이 두 프로그래머는 알골 언어의 함수 호출 스택을 힙으로 옮기면서 새로운 가능성을 발견했습니다. 함수 호출이 끝난 뒤에도 함수 내 지역 변수가 유지될 수 있도록 하자, 이는 클래스와 인스턴스 변수, 메서드라는 개념으로 발전했습니다.
객체지향 프로그래밍은 제어 흐름의 간접적인 전환에 규칙을 부과합니다. 다형성을 통해 코드는 더 유연하고 재사용 가능하게 되었고, 현대 개발에서는 필수적인 개념으로 자리 잡았습니다.
객체 지향 프로그래밍은 제어흐름의 간접적인 전환에 대해 규칙을 부과 한다.
// 객체지향 프로그래밍 (Object-Oriented Programming)
// 객체지향 프로그래밍의 특징은 캡슐화, 상속, 다형성을 활용해 프로그램을 객체 기반으로 구성하는 것입니다.
// 예시: 은행 계좌 관리 프로그램
// 부모 클래스: Account
class Account {
protected String accountHolder;
protected double balance;
public Account(String accountHolder, double balance) {
this.accountHolder = accountHolder;
this.balance = balance;
}
public void deposit(double amount) {
balance += amount;
System.out.println(amount + "원이 입금되었습니다. 잔액: " + balance);
}
public void withdraw(double amount) {
if (balance >= amount) {
balance -= amount;
System.out.println(amount + "원이 출금되었습니다. 잔액: " + balance);
} else {
System.out.println("잔액이 부족합니다.");
}
}
}
// 자식 클래스: SavingsAccount
class SavingsAccount extends Account {
private double interestRate; // 이자율
public SavingsAccount(String accountHolder, double balance, double interestRate) {
super(accountHolder, balance);
this.interestRate = interestRate;
}
public void addInterest() {
double interest = balance * interestRate / 100;
deposit(interest);
System.out.println("이자가 추가되었습니다. 잔액: " + balance);
}
}
public class OOPExample {
public static void main(String[] args) {
// 부모 클래스 객체 생성
Account account = new Account("홍길동", 10000);
account.deposit(5000);
account.withdraw(3000);
// 자식 클래스 객체 생성
SavingsAccount savings = new SavingsAccount("김철수", 20000, 2.5);
savings.deposit(5000);
savings.addInterest();
}
}
// 위 코드는 객체지향 프로그래밍의 상속과 다형성을 보여줍니다. SavingsAccount는 Account를 확장하며, 추가적인 기능(이자 계산)을 제공합니다.
3. 함수형 프로그래밍 (Functional Programming)
마지막으로 함수형 프로그래밍입니다. 최근에야 주목받기 시작했지만, 사실 이 패러다임은 세 가지 중 가장 먼저 등장한 개념입니다.
1930년대 **알론조 처치(Alonzo Church)**가 수학적 문제를 해결하기 위해 만든 람다 계산법이 그 기초이며, 1958년 **존 매카시(John McCarthy)**가 개발한 LISP 언어에 직접적인 영향을 미쳤습니다.
함수형 프로그래밍의 가장 큰 특징은 불변성입니다. 즉, 변수의 값이 변경되지 않으며, 할당문 자체가 존재하지 않는다는 점입니다. 물론 현대 함수형 언어들은 특정 조건하에 변수 값을 변경할 수 있도록 하지만, 매우 까다로운 제약을 두고 있습니다.
결과적으로 함수형 프로그래밍은 할당문에 대한 규칙을 부과하며, 순수 함수와 상태 변화를 최소화한 코드로 높은 안정성과 예측 가능성을 제공합니다.
함수형 프로그래밍은 할당문에 대해 규칙을 부과 한다.
// 3. 함수형 프로그래밍 (Functional Programming)
// Java 8부터 함수형 프로그래밍의 일부 개념이 도입되었습니다. 특히 람다 표현식과 Stream API를 통해 데이터 처리를 간결하게 작성할 수 있습니다.
// 예시: 숫자 목록에서 짝수만 필터링하고 합계 계산
import java.util.Arrays;
public class FunctionalExample {
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// Stream과 람다를 사용한 함수형 프로그래밍
int sumOfEvens = Arrays.stream(numbers)
.filter(number -> number % 2 == 0) // 짝수만 필터링
.sum(); // 합계 계산
System.out.println("짝수의 합계: " + sumOfEvens);
}
}
// 이 코드에서 filter와 같은 고차 함수는 상태를 변경하지 않고 데이터를 처리하는 함수형 프로그래밍의 특징을 보여줍니다.
마무리
이 세 가지 패러다임은 각각의 시점에서 프로그래밍을 한 단계 발전시켰으며, 지금도 소프트웨어 개발의 근본적인 원칙으로 자리 잡고 있습니다.
구조적 프로그래밍은 흐름의 명확성, 객체지향 프로그래밍은 재사용성과 유연성, 그리고 함수형 프로그래밍은 안정성과 불변성을 통해 각자의 방식으로 소프트웨어의 질을 높이는 데 기여했습니다.
책에서 이러한 개념들을 상세히 설명하며 개발자들에게 주는 메시지는 하나였습니다.
“소프트웨어는 끊임없이 변화할 수 있어야 한다.”
그렇기에 우리는 항상 세 가지 패러다임의 원칙을 숙지하고, 더 나은 소프트웨어를 만들기 위해 노력해야 할 것입니다.
블로그 글로서 적합하도록 문단을 구성하고 간결하게 다듬었습니다. 추가적으로 강조하고 싶은 부분이나 독자의 관심을 끌만한 예시를 넣고 싶다면 알려주세요! 😊
'ETC > 책' 카테고리의 다른 글
[Clean Architecture] 서문 및 개요 (0) | 2025.01.07 |
---|