iOS/Swift 상식

POP(Protocol Oriented Programming) vs OOP(Object Oriented Programming)

HJ39 2023. 2. 21. 19:15

POP와 OOP의 가장 큰 차이점은 클래스들이 수직적인 구성이나 수평적인 구성으로 이루어져 있다는 것이다.

 

POP(Protocol Oriented Programming)

POP는 필요한 부분만 프로토콜로 분리해서 만들 수 있고 다중 프로토콜을 구현할 수 있다.

프로토콜 규칙을 class, struct, enum에 적용할 수 있기 때문에 확장 부분에서도 OOP보다 유연하다.

 

POP는 HAS-A 관계로 구성되어 있어 수평적인 구조로서 묘사할 수 있다.

예를 들어

강아지의 특성을 구현한다면

protocol Eatable{
    func eat()
}

extension Eatable{
    func eat(){
        print("I can Eat")
    }
}

protocol EatAlot{
    func eatAlot()
}

extension EatAlot{
    func eatAlot(){
        print("I can eat a lot")
    }
}

class Dog: Eatable, EatAlot{ }

let dog = Dog()
dog.eat()	// I can Eat 출력
dog.eatAlot()	// I can eat a lot 출력

위에서 말한 HAS-A관계로 생각해 보자

Dog HAS A EatAlot = 강아지는 많이 먹을 수 있다.

Dog HAS A Eatable = 강아지는 먹을 수 있다.

 

위와 같이 프로토콜을 이용해서 필요한 속성들을 가져와 사용할 수 있다.

 

OOP(Object Oriented Programming)

OOP는 사물을 객체로 형성하여 공통점을 갖는 모든 곳에서 상속을 받아 객체 내부에 모든 로직을 캡슐화한다.

필요하지 않은 부분을 상속을 받았다는 이유로 속성들을 공유해야 한다.

복잡한 상속 구조를 지닌 클래스를 상속한 경우 원하는 클래스를 참조할 때 다운캐스팅을 해야 한다.

 

가장 큰 단점으로 하나의 클래스만 상속을 받을 수 있다는 것이다.

 

POP에서 예제를 OOP로 변경해서 생각해 보자

 

class Eatable{
    func eat(){
        print("I can eat")
    }
}

class EatAlot: Eatable{
    
    override func eat() {
        print("I can eat2")
    }

    func eatAlot(){
        print("I can eat a lot")
    }
}

class Dog: EatAlot{ }

let dog = Dog()
dog.eat()    // I can Eat 출력
dog.eatAlot()    // I can eat a lot 출력

위 예시에서 POP와 OOP의 차이점이 눈에 보일 것이다.

 

POP의 경우는 protocol을 이용해 수평적으로 이루어져 있지만

OOP의 경우에는 수직적으로 클래스들이 이루어져 있다.

만약 Dog클래스에 접근했다가 Eatable 타입이 필요한 경우 Eatable타입으로 타입 캐스팅을 한 후에 접근하는 경우가 생긴다.

하지만 POP의 경우 protocol 타입을 가져다 사용하면 되므로 손쉽게 문제 해결이 된다.

 

 

 

# 참고한 사이트

  1. https://jinnify.tistory.com/40
  2. https://blog.burt.pe.kr/posts/protocol-oriented-programming/