TIL(Today I Learned)

SimpleCalculator

첫번째 개인 프로젝트는 간단한 계산기 기능을 레벨에 따라 개발해 보는 것 입니다.
아직 xcode로 앱개발을 하는 강의는 진행하지 않은 상황이기 때문에 UI를 제외하고 기능만 구현 하면 됩니다.
playground를 사용해 보지 않은 상황에서 겸사겸사 좋은 경험이 될 것 같아서 playground로 진행하기로 했습니다.
먼저 기능적인 로직을 구현하는건 전혀 어렵지 않겠지만 Lv.4에 해당하는 추상화 라는 개념을 좀 더 확실히 공부하고 넘어가야 할 것 같습니다.
주어진 조건은 다음과 같습니다.

필수 구현 기능

  • Lv1 : 더하기, 빼기, 나누기, 곱하기 연산을 수행할 수 있는 Calculator 클래스를 만들고, 클래스를 이용하여 연산을 진행하고 출력하기

  • Lv2 : Lv1에서 만든 Calculator 클래스에 나머지 연산을 가능하도록 코드를 추가하고, 연산 진행 후 출력하기

  • Lv3 : AddOperation(더하기), SubstractOperation(빼기), MultiplyOperation(곱하기), DivideOperation(나누기) 연산 클래스를을 만든 후 클래스간의 관계를 고려하여 Calculator 클래스와 관계를 맺기

    • 관계를 맺은 후 필요하다면 Calculator 클래스의 내부코드를 변경하기
      • 나머지 연산자(%) 기능은 제외합니다.
    • Lv2 와 비교하여 어떠한 점이 개선 되었는지 스스로 생각해 봅니다.
      • hint. 클래스의 책임(단일책임원칙)

선택 구현 기능

  • Lv4 : AddOperation(더하기), SubtractOperation(빼기), MultiplyOperation(곱하기), DivideOperation(나누기) 연산 클래스들을 AbstractOperation라는 클래스명으로 만들어 사용하여 추상화하고 Calculator 클래스의 내부 코드를 변경합니다.
  • Lv3 와 비교해서 어떠한 점이 개선 되었는지 스스로 생각해 봅니다.
    • hint. 클래스간의 결합도, 의존성(의존성역전원칙)
Lv1

더하기 / 뺴기 / 나누기 / 곱하기 연산은 모두 간단하게 구현이 가능하기에 클래스만 만들어서 완성할 수 있었습니다.

Lv2

나머지 연산 역시 %로 쉽게 구할 수 있는 연산이기에 간단하게 구현이 가능했습니다.

Lv3

각각의 연산을 클래스로 분리하고 Calculator 클래스에서 연산을 진행하는 것은 문제가 되지 않았으나 Calculator 클래스와의 관계를 맺는다는 부분이 좀 와 닿지 않았습니다. 문제의 의도가 무엇일지 고민해보았으나 클래스로 분리하는 것 자체가 Lv3에서 원하는 결과물일 것 이라는 생각이 들어서 방향을 그쪽으로 잡았습니다.

class AddOperation {
    func operate(first: Double, second: Double) -> Double {
        return first + second
    }
}
class SubtractOperation {
    func operate(first: Double, second: Double) -> Double {
        return first - second
    }
}
class MultiplyOperation {
    func operate(first: Double, second: Double) -> Double {
        return first * second
    }
}
class DivideOperation {
    func operate(first: Double, second: Double) -> Double {
        return first / second
    }
}
Lv4

Lv3에서 클래스를 분리하고 나니 왜 추상화를 진행하라고 하는지 알 것 같았습니다.
각각의 클래스 안에 operate라는 함수가 parameter와 return이 모두 동일한 타입이었고 그 클래스들 모두 부모 클래스가 있으면 구현이 더 간편해 질 것 같다는 생각이 들었습니다.
그러나 최근 강의에서 protocol에 대한 학습을 진행 하였고 상속과 프로토콜을 고민하다가 프로토콜로 진행해 보기로 했습니다.

protocol AbstractOperation {
    func operate(first: Double, second: Double) -> Double
}
프로토콜 vs 상속
  • 프로토콜은 추상적인 object의 행위를 정의하고 상속은 구현체의 object 자체를 정의
  • 프로토콜을 이용했을 때, 해당 클래스를 변경하려고 하는 경우 다른 클래스를 고려하지않고 해당 클래스만 고려하여 수정하면 되므로 변경이 더욱 쉬움(SRP원칙 - 단일 책임 원칙)
  • 상속을 선택하는 경우
    1. 명확히 is-a 관계인 경우
    2. 상속을 위한 클래스로 구현된 경우
    3. 자신이 잘 알고 관리할 수 있는 클래스인 경우

댓글남기기