[내일배움캠프 8일차] 2주차 계산기 만들기 Lv4

NH·2025년 3월 12일

내일배움캠프

목록 보기
8/62
post-thumbnail

🧮 2주차 과제: Swift를 사용하여 계산기 만들기


📌 TIL: Swift Calculator - DIP 적용 (Lv4)

📝 오늘 배운 내용

오늘은 Swift의 객체지향 프로그래밍(OOP) 개념과 의존성 역전 원칙(DIP) 을 적용하여 계산기 클래스를 개선하는 과정을 학습했다.


🟠 도전 구현 기능

🏆 Lv4

  • AbstractOperation라는 추상화된 프로토콜 만들기
  • 기존에 구현한 AddOperation(더하기), SubtractOperation(빼기), MultiplyOperation(곱하기), DivideOperation(나누기) 클래스들과 관계를 맺고 Calculator 클래스의 내부 코드를 변경
  • Swift 내의 어떤 문법을 이용하여 추상화할 수 있을지 생각해 봅시다.

🔥 1. 기존 코드의 문제점 (Lv3)

이전 단계에서는 Calculator 클래스가 특정 연산 클래스(AddOperation, SubtractOperation 등)에 직접 의존하고 있었다.
이렇게 되면 새로운 연산을 추가할 때마다 Calculator 코드를 수정해야 하는 문제가 발생한다.

class Calculator {
    let addOperation = AddOperation()
    
    func calculate(_ num1: Double, _ num2: Double) -> Double {
        return addOperation.calculation(num1, num2)  // 특정 클래스에 강하게 의존!
    }
}

문제점 정리

  • Calculator가 특정 연산 클래스에 강한 결합(High Coupling) 을 가지고 있음
  • 새로운 연산이 추가될 때마다 Calculator를 수정해야 함 (OCP 위반)

🎯 2. DIP(의존성 역전 원칙) 적용

의존성을 낮추기 위해 프로토콜을 활용하여 추상화된 AbstractOperation을 만들었다.
Calculator는 구체적인 연산 클래스가 아닌, 추상적인 AbstractOperation에 의존하도록 변경했다.

// ✅ 1. 추상화된 프로토콜 정의
protocol AbstractOperation {
    func calculation(_ num1: Double, _ num2: Double) -> Double?
}

// ✅ 2. 연산 클래스들이 프로토콜을 채택
class AddOperation: AbstractOperation {
    func calculation(_ num1: Double, _ num2: Double) -> Double? {
        return num1 + num2
    }
}

class SubtractOperation: AbstractOperation {
    func calculation(_ num1: Double, _ num2: Double) -> Double? {
        return num1 - num2
    }
}

class MultiplyOperation: AbstractOperation {
    func calculation(_ num1: Double, _ num2: Double) -> Double? {
        return num1 * num2
    }
}

class DivideOperation: AbstractOperation {
    func calculation(_ num1: Double, _ num2: Double) -> Double? {
        guard num2 != 0 else {
            print("Error: 0으로 나눌 수 없습니다.")
            return nil
        }
        return num1 / num2
    }
}

// ✅ 3. Calculator가 "추상화(프로토콜)"에 의존하도록 변경
class Calculator {
    func calculation(_ operation: AbstractOperation, _ num1: Double, _ num2: Double) -> Double? {
        return operation.calculation(num1, num2)
}

// ✅ 4. 실행 예시
let calc = Calculator()

// 옵셔널 언래핑
if let addRetult = calc.calculation(AddOperation(), 10, 20) {
    print(addRetult)
}

if let subRetult = calc.calculation(SubstractOperation(), 10, 20) {
    print(subRetult)
}

if let mutiRetult = calc.calculation(MultiplyOperation(), 10, 20) {
    print(mutiRetult)
}

if let divRetult = calc.calculation(DivideOperation(), 10, 20) {
    print(divRetult)
}

💡 3. DIP 적용 후 개선된 점

❌ 기존 문제 (Lv3)✅ 개선된 코드 (Lv4)
Calculator가 특정 연산 클래스에 의존Calculator추상화된 AbstractOperation에 의존
새로운 연산을 추가하려면 Calculator 수정 필요새로운 연산 클래스를 만들어도 Calculator 수정 불필요
OCP(개방-폐쇄 원칙) 위반OCP 준수 → 유지보수 용이
클래스 간 결합도 높음 (High Coupling)결합도 낮아짐 (Low Coupling)

🏆 도전: 디렉토리 및 파일 구분

개인 과제에서 파일과 디렉토리를 정리

  • 도전과제 중 하나인 과제 파일 정리를 해보았다.
  • 구상은 아래와 같이 했다.
📂 Calculator/        				# 프로젝트 루트 디렉토리
 ├── 📂 Lv3-OperationClass/			# Lv3 연산 기능 클래스 저장
 │    ├── AddOperation.swift
 │    ├── DivideOperation.swift
 │    ├── MultiplyOperation.swift
 │    ├── SubstractOperation.swift
 ├── 📂 Lv4-AbstractOperation/		# Lv4 추상화 프로토콜 저장
 │    ├── AbstractOperation.swift
 ├── 📄 Calculator.swift			# Calculator 클래스 코드 저장
 ├── 📄 main.swift					# 메인 코드
 ├── 📄 README.md    				# 프로젝트 소개 및 실행 방법 설명
  • 결과

🚨 트러블 슈팅

파일 및 디렉토리 정리 중 발생한 오류에 대해 정리

  • 오류 내용 : 갑자기 코드에 Expressions are not allowed at the top level 오류가 발생
  • 원인 : 처음 파일 정리 중에, main.swift 파일 이름을 Calculator.swift 로 변경하니, 오류가 발생
  • 원인 분석 :
    • main.swift 파일 이름을 바꾸면 안되는 이유
      • Swift 프로젝트에서 main.swift 파일은 진입점(entry point) 역할
      • main.swift 내부의 코드들은 최상위 레벨에서 실행이 가능
      • 하지만 파일 이름을 변경하면 Swift 컴파일러가 이를 일반 Swift 파일로 인식하여 최상위 레벨의 표현식을 허용하지 않음
    • 최상위 코드(Top-Level Code)란?
      • "최상위 코드(Top-Level Code)"란 함수, 클래스, 구조체 등의 내부가 아닌, 파일의 가장 바깥쪽에서 직접 실행되는 코드를 의미

과제 결과물 : github 페이지로 👉 이동하기


✍️ 배운점과 느낀점

1️⃣ DIP(의존성 역전 원칙)는 "구체적인 클래스"가 아닌 "추상화(프로토콜)"에 의존하라는 원칙을 배웠다.
2️⃣ 클래스 간의 결합도를 낮추면 유지보수성과 확장성이 좋아진다.
3️⃣ Swift에서 프로토콜을 활용하면 OOP 원칙을 잘 적용할 수 있다.

👉 앞으로도 객체지향 원칙과 디자인 패턴을 고려하면서 코드 설계하는 습관을 길러야겠다. 🚀

profile
iOS 개발 블로그

0개의 댓글