[iOS 3주차] 프로토콜(Protocol)

황석범·2024년 11월 4일
0

내일배움캠프_iOS_5기

목록 보기
12/76

프로토콜(Protocol)

class , struct , enum 에서 공통으로 구현해야 하는 메소드프로퍼티 의 청사진을 정의하는 기능입니다.

  • 프로토콜 자체는 기능을 구현하지 않으며, 오직 설계만 제공합니다.
  • class , struct , enum 에서 프로토콜을 채택 할 수있으며, 프로토콜에서 정의한 프로퍼티와 메소드를 모두 구현해야 합니다.
    • 프로토콜을 채택 하는 방법은 타입의 이름 뒤에 : 콜론을 넣은 후 프로토콜 이름을 작성하면 됩니다.
    • 프로토콜은 여러 개를 채택 할 수 있으며, 프로토콜 이름을 , 로 구분합니다.
  • 프로토콜 에서 정의된 프로퍼티는 항상 var 로 선언되어야 합니다.
  • 프로토콜 에서 정의하는 프로퍼티는 읽기 전용 {get} 또는 읽기-쓰기 가능 {get set} 으로 설정할 수 있습니다.
  • 프로토콜에서 정의하는 메소드는 이름 , 파라미터 , 리턴타입 만 선언하며, 구현부 {} 는 작성하지 않습니다.
  • Swift에서 프로토콜은 다른 언어에서 말하는 인터페이스 개념과 유사합니다.

프로토콜 정의 방법


protocol 프로토콜이름 {
	// 프로퍼티 정의
    // 메소드 정의
}

protocol FullyNamed{
	var fullName: String { get }
    
    func sayMyFullName() -> String //  구현부는 작성하지 않습니다.
}

프로토콜 채택하여 구현하는 방법


// 1개의 프로토콜 채택
protocol FullyNamed{
	var fullName: String { get }
    
    func sayMyFullName() -> String // 구현부는 작성하지 않습니다.
}

class Person: FullyNamed { // FullyName 프로토콜을 채택합니다.
	var fullName: String  // FullyName 프로토콜에 있는 fullyName 프로퍼티를 구현해야 합니다.
    
    func sayMyFullName() -> String { // 프로토콜에 있는 메소드를 구현해야 합니다.
    	return fullName
    }
    
    init(fullName: String) {
    	self.fullName = fullName
    }
}

var person = Person(fullName: "Brody")

print(person.fullName) // "Brody" 출력
print(person.sayMyFullName()) // "Brody" 출력

객체지향 프로그래밍에서 인터페이스를 사용하여 이유와 장단점에 대해 찾아보았다.

  • 구현한 클래스에서 특정 기능(메소드)을 구현하도록 강제 할 수 있는 기능을 제공한다.

  • 다형성이 가능하도록 기능을 제공한다.

  • 추상 클래스는 수직적이지만, 수평적 구조를 제공한다.

    • 하나의 클래스가 여러 인터페이스를 상속받을 수 있다.
  • 인터페이스를 사용하면, 변경에 유연하게 설계할 수 있다.
    기능에 대한 명세 집합

    인터페이스하면 상속과 추상화라는 개념이 나온는 것 같다.

  • 상속

    정의는 부모 클래스의 모든 멤버를 하위 클래스가 물려 받는 것이다. 단, IS A 관계가 성립해야 한다. 아무런 규약 없이 상속을 하게 되면 객체간에 강한 결합을 가지게 된다.

    연관된 객체들끼리만 상속을 하는것이 강한 결합을 줄일 수 있다.

  • 추상화

    데이터나 프로세스 등을 의미가 비슷한 개념이나 표현으로 정의해 나가는 과정을 의미한다. 각 개별 개체의 구체적인 구현에 대한 상세함은 갖추는 것을 의미한다.

객체지향 5원칙인 SOLID중 O(Open-closed-principle)을 지킬 수 있게 된다.

🐱객체지향 설계의 5가지 원칙, SOLID

SOLID 라는 좋은 객체지향의 설계의 5가지 원칙이 존재한다. SOLIDSRP (단일 책임 원칙), OCP (개방-폐쇄 원칙), LSP (리스코프 치환 원칙), ISP (인터페이스 분리 원칙), DIP (의존 역전 원칙)의 앞글자를 따서 만들어졌다. SOLID 원칙을 철저히 지키면 시간이 지나도 변경이 용이하고, 유지보수와 확장이 쉬운 소프트웨어를 개발하는데 도움이 된다.

SRP (Single Responsibility Principle) 단일 책임 원칙

  • 하나의 클래스는 하나의 책임만 가져야 한다.
  • 클래스를 변경하는 이유는 단 하나여야 한다. 변경이 있을 때 파급 효과가 적어야 한다.
    • 이를 지키지 않으면, 한 책임의 변경에 의해 다른 책임과 관련된 코드에 영향을 미칠 수 있다.
  • 결국, 유지보수가 매우 비효율적이게 된다.
    책임?

OCP (Open-Closed Principle) 개방-폐쇄 원칙

  • 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
    즉, 기존의 코드를 변경하지 않고 기능을 수정, 추가할 수 있도록 설계해야한다.
  • 인터페이스를 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현

LSP (Liskov Substitution Principle) 리스코프 치환 원칙

  • 하위 타입 객체는 상위 타입 객체에서 가능한 행위를 수행할 수 있어야 한다.
    • 즉, 상위 타입 객체를 하위 타입 객체로 대체하여도 정상적으로 동작해야 한다.
  • 다형성에서 하위 클래스는 인터페이스의 규약을 다 지켜야 한다.
  • 상속 관계에서는 꼭 일반화 관계(IS-A)가 성립해야 한다.
  • 상속 관계가 아닌 클래스들을 상속관계로 설정하면, LSP 위반이다.

ISP (Interface Segregation Principle) 인터페이스 분리 원칙

  • 클라이언트는 자신이 사용하는 메소드에만 의존해야 한다.
  • 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 한 개보다 낫다.
  • 인터페이스는 해당 인터페이스를 사용하는 클라이언트를 기준으로 잘게 분리되어야 한다.

DIP (Dependency Inversion Principle) 의존 역전 원칙

프로그래머는 "추상회에 의존해야지, 구체화에 의존하면 안된다." 의존성 주입은 이 말을 따르는 방법 중 하나다.

  • 의존 관계를 맺을 때, 변하기 쉬운 구체적인 것 보다는 변하기 어려운 추상적인 것에 의존해야 한다는 것이다.
    • 즉, 구현 클래스에 의존하지 말고, 인터페이스에 의존하라는 뜻이다.
  • 클라이언트가 인터페이스에 의존해야 유연하게 구현체를 변경할 수 있다. 구현체에 의존한다면 변경에 어려움이 생긴다.
  • 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안된다.
    • 저수준 모듈이 변경되어도 고수준 모듈은 변경이 필요없는 형태가 이상적이다.
profile
iOS 공부중...

0개의 댓글

관련 채용 정보