Swift

[Swift] 클래스와 프로토콜에 대한 고찰 및 사용 기준

Dev_Ted 2025. 1. 23. 00:54

클래스와 프로토콜의 차이

Swift에서는 클래스 상속프로토콜 채택을 활용하여 코드의 재사용성을 높일 수 있습니다. 언뜻 보면 비슷해 보이지만, 각각의 역할과 사용 목적이 다릅니다. 어떤 상황에서 클래스를 사용하고, 언제 프로토콜을 사용하는 것이 더 적절한지 고민해보았습니다.

 

 

클래스의 상속

클래스 상속은 객체 지향 프로그래밍(OOP)의 핵심 개념 중 하나로, 부모 클래스의 기능을 자식 클래스가 물려받아 사용할 수 있습니다.

예를 들어, iOS 개발에서 UIViewController를 상속하면 기본적인 화면 관리 기능을 그대로 사용할 수 있습니다.

class CustomViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        print("CustomViewController Loaded")
    }
}

 

클래스 상속의 장점은 다음과 같습니다.

  • 코드 재사용성
    • 공통 기능을 부모 클래스에서 정의하고, 여러 하위 클래스에서 재사용할 수 있습니다.
  • 다형성(Polymorphism)
    • 부모 클래스의 기능을 하위 클래스에서 **오버라이딩(override)**하여 커스터마이징할 수 있습니다.

 

하지만 상속은 다음과 같은 단점을 지니고 있습니다.

  • 상속을 위해 캡슐화가 깨질 수 있습니다.
    • 상속의 장점은 다형성을 구현할 수 있다는 것이 있는데, Swift 언어에선 외부 클래스에서도 접근할 수 있는 단점이 존재합니다. Java는 protected 라는 키워드를 통해 외부 클래스에서의 접근이 불가능하지만, Swift에서는 외부 클래스의 접근을 막을 수 없어 캡슐화가 깨질 수 있습니다.
  • 상위 클래스에 의존적입니다. (강한 결합)
    • 부모 클래스의 변경이 하위 클래스에 영향을 미쳐 예기치 않은 버그를 초래할 수 있습니다.
  • 불필요한 기능 상속
    • SOLID 원칙 중 ISP(인터페이스 분리 원칙) 을 위반할 가능성이 있습니다. (필요하지 않은 기능까지 상속받아야 할 수도 있음)
  • 다중 상속이 불가능합니다.
    • Swift는 다중 상속을 지원하지 않으므로, 한 개의 클래스만 상속받을 수 있습니다.

 

 

프로토콜

프로토콜(Protocol)은 특정 행동(행위)을 정의하는 규약으로, 클래스뿐만 아니라 구조체(struct), 열거형(enum)도 채택할 수 있습니다.

예를 들어, UITableViewDataSource 프로토콜을 채택하여 테이블뷰의 데이터 소스를 설정할 수 있습니다.

protocol Animal {
    func makeSound()
}

class Dog: Animal {
    func makeSound() {
        print("Woof!")
    }
}

class Cat: Animal {
    func makeSound() {
        print("Meow!")
    }
}

 

프로토콜의 장점은 다음과 같습니다.

  • 유연한 설계
    • 특정 기능을 개별적으로 추가할 수 있어, 단일 책임 원칙(SRP)을 지킬 수 있습니다.
  • 다중 채택 가능
    • 여러 개의 프로토콜을 동시에 채택할 수 있어, 다중 상속의 한계를 극복할 수 있습니다.
  • 프로토콜을 통해 불필요한 기능을 줄일 수 있어, ISP(인터페이스 분리 원칙)를 준수할 수 있게 됩니다.
    • 프로토콜을 꼭 필요한 행위에 대해서만 정의하기 때문에 해당 프로토콜을 준수한다는 것은 ‘해당 프로토콜에 정의된 내용은 꼭 사용해야 함’을 의미하는 것입니다. 즉, 불필요한 기능에 대해 추가가 되지 않을 수 있지만, 상속을 하게 되면 모든 기능을 상속받기 때문에 불필요한 기능 또한 상속받을 가능성이 존재합니다.
  • 클래스 외에도 적용 가능
    • 구조체, 열거형도 프로토콜을 채택할 수 있어, 값 타입을 활용한 설계가 가능합니다.
  • 의존성 제거
    • 특정 클래스를 상속받지 않고도, 공통된 기능을 정의할 수 있습니다.

 

하지만 프로토콜 또한 다음과 같은 사항을 주의해야 합니다.

  • 구현 강제
    • 프로토콜을 채택하면 요구된 모든 메서드를 반드시 구현해야 합니다.
  • 복잡성 증가
    • 지나치게 많은 프로토콜을 사용하면 코드가 분산되고, 유지보수가 어려워질 수 있습니다.

 

 

클래스와 프로토콜의 적절한 사용 기준

클래스와 프로토콜의 역할과 특징을 기반으로 클래스는 새로운 객체(컴포넌트)를 만들 때 사용하고, 프로토콜은 특정 행위를 정의할 때 사용하는 것이 적절하다고 생각하였습니다.

예를 들어 UIViewController나 UITableViewCell처럼 특정 기능을 가진 컴포넌트를 만들 때 클래스 상속을 활용하면 기본 기능을 재사용할 수 있어 코드의 중복을 줄일 수 있습니다. 상속을 통해 부모 클래스의 속성과 메서드를 가져올 수 있으며, 필요한 경우 오버라이딩하여 동작을 변경할 수도 있습니다.

반면, 프로토콜은 객체의 유형(Type)을 정의하는 것이 아니라, 그 객체가 어떤 기능을 수행해야 하는지를 선언하는 역할을 합니다. 예를 들어, UITableViewDataSource나 UITableViewDelegate 같은 프로토콜을 채택하면, 특정 기능을 수행해야 한다는 것을 보장할 수 있습니다. 프로토콜은 다중 채택이 가능하기 때문에, 하나의 객체가 여러 가지 역할을 수행해야 할 때 유용합니다. 또한, 클래스뿐만 아니라 구조체와 열거형에서도 채택할 수 있어, 보다 유연한 설계를 가능하게 합니다.

 

따라서, 컴포넌트를 만들고 재사용성을 높이기 위해서는 클래스를 사용하고, 특정한 기능을 정의하고 유연성을 높이기 위해서는 프로토콜을 활용하는 것이 더 적절하다고 판단하였습니다. 추후 개발부터는 뷰 컨트롤러나 모델 객체를 설계할 때 클래스를 사용하고, 뷰 컨트롤러 간의 데이터 전달이나 특정 이벤트 처리를 할 때는 프로토콜을 활용하고자 합니다.

728x90