ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • POP에 대해서
    IOS 2024. 7. 23. 00:40

     

    안녕하세요, 이번 글은 POP에 대한 정리와 "OOP와 차이점은?"에서부터 시작된 궁금증을 해소함과 더불어 Swift 입문자 분들에게 조금이나마 도움이 되는 마음으로 OOP와 POP에 대해 글을 쓰려합니다.

     

    POP를 시작하기 앞서, 오랫동안 프로그래밍 기법으로 자리 잡은 Object Oriented Programing이 존재했습니다.

    객체지향 패러다임으로 C++, C#, Java 등 많은 언어들이 존재했고 해당 언어를 OOP SOLID원칙에 따른 프로그래밍 장점과 차이점이 존재했던 거 같습니다.

    OOP패러다임 다음 POP는 OOP에서의 단점들을 보안한 프로그래밍 기법이라 생각되는데요, 그 이유에 대한 내용으로 내용을 작성하려 합니다.

     

    [Swift Protocol]

    '기능적으로 비슷한 성격을 띠는 동작이나 속성들을 추상화한 그룹으로 Base class 상관없이 캡슐화'가 가능한 집합이라 말씀드릴 거 같습니다. 코드로 말씀드리면 다음과 같습니다.

    protocol Bird {
      var name: String { get }
      var canFly: Bool { get }
    }
    
    protocol Flyable {
      var airspeedVelocity: Double { get }
    }

     

    이처럼 Bird는 이름과 CanFly란 Boolean 타입을 가지는 Protocol입니다. 이는 Bird를 따르는(구현)하는 실제 클래스, 구조체, 열거형에서 실체를 정의하게 됩니다. 마찬가지로 Flyable의 경우 해당 프로토콜을 준수하려면, airSpeedVelocity를 구현해줘야 합니다.

    이러한 설명만 들었을 때, Java를 학습하신 분들이라면 Interface와 비슷하다고 느낄 것 같습니다. 

    하지만 위의 예시는 너무 단편적인 부분이고 Swift에선 좀 더 강력한 기능들이 제공됩니다.(자세한 내용은 다음 블로깅 때 포스팅 하겠습니다.)

    즉, Protocl으로 POP, OOP를 Swift에서 쉽게 실현할 수 있습니다.

    참고로 (swift는 상속의 경우 하나의 상위 클래스만 상속 가능합니다, 반면 프로토콜은 다중으로 상속이 가능합니다.)

    [Protocol의 유연성]

    OOP의 경우 하위 클래스가 상위 클래스의 정의된 속성과 메서드를 그대로 상속받는 메커니즘입니다. 이런 메커니즘을 생각했을 때, 하위 클래스에서 오버라이드를 통해 재정의 가능하지만, 기본적으로 상위 존재로 인해 하위 존재의 성격이 정의된다는 것입니다. 

    POP는 Protocol의 '조합'을 통해 성격이 정의됩니다. 즉, 특성을 지닌 집합인 프로토콜들을 작은 단위로 나누고 이를 하나의 클래스, 구조체, 열거형에 조합하는 방식으로 구현 가능합니다. 

     

    다음은 Kodeco의 Gina De La Rosa 님이 작성하는 Protocol을 활용한 유연성의 대한 예시 코드입니다.

      
    import Foundation
    
    protocol Vehicle {
        var make: String { get }
        var model: String { get }
        func drive()
    }
    
    class Car: Vehicle {
        let make: String
        let model: String
        
        init(make: String, model: String) {
            self.make = make
            self.model = model
        }
        
        func drive() {
            print("Driving the \(make) \(model).")
        }
    }
    
    class ElectricCar: Car, Chargeable {
        func charge() {
            print("Charging the \(make) \(model).")
        }
    }
    
    protocol Chargeable {
        func charge()
    }

     

    ElectricCar 클래스의 상위 클래스로 Car 클래스를 상속받습니다. 추가로 전기차 특성에 해당하는 Chargeable을 통해 하위 클래스인 ElectricCar 클래스만 해단 프로토콜을 '준수'하고 있습니다.

     

    [Extension을 활용한 재사용성]

    protocol을 extension 해서 공통적으로 동작하는 메서드를 정의할 수 있습니다. 코드로 예시를 들겠습니다.

    protocol Animalable {
        var name: String { get }
        //그외 동물이 가질 수 있는 속성 등
    }
    
    extension Animalable {
        func speak() { print("\(name)") }
    }
    
    struct Bird: Animalable {
        let name: String
    }
    
    let swiftBird = Bird(name: "Swift")
    swiftBird.speak()

    위 예시처럼, 동물일 때 어떤 속성과 동작을 준수해야 한다는 걸 정의한 Protocol이 있다고 가정하겠습니다.

    정말 아주 먼 미래에 동물이 말할 수 있게된다면, 위 예시처럼 Animalable extension을 통해 speak 메서드를 구현한 것처럼 Animalable을 준수하는 클래스, 구조체, 열거형을 수정할 필요가 없습니다. 또한  공통적으로 동작이 구체화된 것을 구현할 수도 있을 것입니다.

    [마무리]

    이렇게 강력한 Swift Protocol 중심으로 설계하는 것이 POP입니다.

    정확히 말해 OOP는 클래스의 상속으로 객체들을 설계한다면, POP는 프로토콜 위주로 객체를 설계하는 것을 뜻합니다.

    OOP에도 프로토콜을 사용할 수 있지만, 이는 추상화 목적에 가깝다고 생각됩니다.

    즉, POP란 프로토콜 위주로 객체를 설계하고 OOP와 차이점은 유연하고 확장성 있는 설계가 가능하다는 점입니다.

     

    개인적으로 swift에서 Protocol을 Java Interface처럼 OOP의 DIP원칙으로 사용되는 코드를 보며 Swift Protocol을 활용해 OOP와 POP두 가지 기법을 이용하는 게 매력적으로 와닿았습니다. Swift는 깊게 이해하려 할수록 매력적인 거 같습니다.

    [References]

     

    Protocol-Oriented Programming Tutorial in Swift 5.1: Getting Started

    In this protocol-oriented programming tutorial, you’ll learn about extensions, default implementations and other techniques to add abstraction to your code.

    www.kodeco.com

     

    Protocols in iOS Object-Oriented Programming

    Object-Oriented Programming (OOP) and protocols are two complementary paradigms in Swift. Learn how to combine them to build apps that are robust, flexible and easy to maintain.

    www.kodeco.com

     

Designed by Tistory.