Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[Clean Architecture] 4. 코드로 알아보는 SOLID - ISP(Interface Segregation Principle) 인터페이스 분리 원칙 본문

Clean Architecture/Clean Architecture 코드

[Clean Architecture] 4. 코드로 알아보는 SOLID - ISP(Interface Segregation Principle) 인터페이스 분리 원칙

jake-kim 2021. 9. 19. 20:46

0. 코드로 알아보는 SOLID - 클래스 다이어그램 필수 표현

1. 코드로 알아보는 SOLID - SRP(Single Responsibility Principle) 단일 책임 원칙

2. 코드로 알아보는 SOLID - OCP(Open Close Principle) 개방 폐쇄 원칙

3. 코드로 알아보는 SOLID - LSP(Liskov Substitution Principle) 리스코프 치환 원칙

4. 코드로 알아보는 SOLID - ISP(Interface Segregation Principle) 인터페이스 분리 원칙

5. 코드로 알아보는 SOLID - DIP(Dependency Inversion Principle, testable) 의존성 역전 원칙

6. 코드로 알아보는 SOLID - Coordinator 패턴 화면전환

7. 코드로 알아보는 SOLID - Network, REST (URLSession, URLRequest, URLSessionDataTask)

8. 코드로 알아보는 SOLID - 캐싱 Disk Cache (UserDefeaults, CoreData)

ISP

  • Interface Segregation Principle
  • 인터페이스 분리 원칙
  • 여러 클래스가 하나의 모듈을 사용중이면, Interface를 만들어 분리하여 사용

  • 문제: op2에 필요한 parameter가 추가되어서 OPS생성자에 새로운 parameter를 주입해주어야 하는 경우, user1, user3에도 영향
let user1: OPS = OPS()
user1.op1()
  • ISP를 이용한 해결

ISP가 중요한 이유

코드로 보는 ISP 예제

  • Personal, Business가 지불한 금액에 대해서 계산을 해야할 때, 계산하는 클래스 calculator를 이용하는 상황

  • 현재의 문제점
    • 1) calculator에서 Personal인지 Business인지 체크하는 부분이 들어가는데, Personal인지 Business인지 알고 있는것 부터가 calculator가 Personal, Business에도 의존하고 있는 상황
    • 2) 두 개의 클래스가 하나의 모듈을 사용중이므로 Personal, Business가 Calculator에 종속하는 것을 방지하기 위해, ISP를 통해 해결
// ISP미적용된 코드

class Personal {
    let calculator = Calculator(expensesPrice: 1000)

    func calFee() {
        print(calculator.calFee(type: .personal))
    }
}

class Business {
    let calculator = Calculator(expensesPrice: 2000)

    func calFee() {
        print(calculator.calFee(type: .business))
    }
}

class Calculator {

    var expensesPrice: Double

    init(expensesPrice: Double) {
        self.expensesPrice = expensesPrice
    }

    enum CalType {
        case personal
        case business
    }

    func calFee(type: CalType) -> Double {
        switch type {
        case .personal:
            return expensesPrice * 1.2
        case .business:
            return expensesPrice * 0.7
        }
    }
}
  • 해결
    • 1) Calculator에서 Personal, Business의 타입을 모르고 있도록 변경
    • 2) ISP 사용하여 Interface를 만들어서 Personal과 Business를 분리

  • 해결한 코드
class Personal {
    let calculator: CalPersonal = Calculator(expensePrice: 1000)

    func calFee() {
        print(calculator.calFeePersonal())
    }
}

class Business {
    let calculator: CalBusiness = Calculator(expensePrice: 2000)

    func calFee() {
        print(calculator.calFeeBusiness())
    }
}

protocol CalPersonal {
    func calFeePersonal() -> Double
}

protocol CalBusiness {
    func calFeeBusiness() -> Double
}

class Calculator: CalPersonal, CalBusiness {

    var expensePrice: Double

    init(expensePrice: Double) {
        self.expensePrice = expensePrice
    }

    func calFeePersonal() -> Double {
        return expensePrice * 1.2
    }

    func calFeeBusiness() -> Double {
        return expensePrice * 0.7
    }
}

* 전체 소스코드: https://github.com/JK0369/SOLID

Comments