Mar 12, 2021, TIL (Today I Learned) - MVC, Singleton, Hashable, enum, Dictionary

Inwoo Hwang·2021년 8월 26일
0
post-thumbnail

학습내용


MVC 디자인 패턴 [Model View Controller Programming Design Pattern]

하나의 앱, 또는 프로젝트를 구성할 때 구성요소를 아래와 같이 3가지 역할로 구분:

Model - View - Controller

  • Model
    • 데이터 관리
  • View
    • 사용자에게 보여지는 역할
  • Controller
    • Model과 View 사이의 중간다리

View와 Model은 분리되어있다

  • 사용자의 화면을 구성하는 요소를 업데이트 할 때 데이터 손상을 걱정할 필요가 없다.

사용자가 Controller로 조작 → Model을 통해 데이터 가져오고 → 정보 바탕으로 시각적인 표현을 View가 제어

싱글톤 패턴 [Singleton Pattern]

class FruitStorage {
    static let shared = FruitStorage()
    private(set) var refrigerator: [Fruit: Int]
    
    private init() {
        refrigerator = [:]
        setInitialFruitAmount()
    }
    func setInitialFruitAmount() {
        refrigerator = [Fruit.strawberry: 10, Fruit.banana: 10, Fruit.kiwi: 10, Fruit.mango: 10, Fruit.pineapple: 10]
    }
}

"특정 용도로 객체를 생성해서 해당 객체를 공용으로 사용하고 싶을 때 사용하는 디자인 패턴"

위 코드 같은 경우 과일저장소 속 과일 데이터를 공용으로 사용하기 위해 싱글톤 패턴을 사용하였다.

static property에 인스턴스를 생성하여 싱글톤을 생성해 주었고

추가적으로 다른 곳에서 생성하지 못하도록private init() {}방법을 사용하여 thread-safety한 싱글톤으로 만들어주었다.

enumswitch

enum Juice {
    case strawberryJuice
    case bananaJuice
    case kiwiJuice
    case pineappleJuice
    case mangoJuice
    case strawberryBananaJuice
    case mangoKiwiJuice
    
    var recipe: [Fruit : Int] {
        switch self {
        case .strawberryJuice:
            return [.strawberry : 16]
        case .bananaJuice:
            return [.banana : 2]
        case .kiwiJuice:
            return [.kiwi : 3]
        case .pineappleJuice:
            return [.pineapple : 2]
        case .strawberryBananaJuice:
            return [.strawberry : 10, .banana: 1]
        case .mangoJuice:
            return [.mango : 3]
        case .mangoKiwiJuice:
            return [.mango : 2, .kiwi : 1]
            
        }
    }
}

유레카다. 이렇게 구현을 하니 각 enum case의 조건을 바로 설정할 수 있게 된다.

그리고 recipe변수의 case는 Juice의 인스턴스를 통해서 접근이 가능해진다.

let juice: Juice = Juice()

juice.recipe.strawberryJuice

딕셔너리[Dictionary] 활용하기

딕셔너리에 대한 자세한 내용은 아래 블로그에 잘 정리되어 있습니다.↓↓

Swift3 ) Collection - Dictionary사용해보기 (tistory.com)

딕셔너리의 제약사항!!:

  • 딕셔너리의 Key는 해쉬가능한 타입이어야 한다. [Hashable]

    Hashable: 그 자체로 유일하게 표현이 가능한 방법을 제공해야 한다.

  • 따라서 Int, String, Double 그리고 더 나아가 swift의 열거형 까지 해쉬 가능하기에 들어갈 수 있다.

딕셔너리 사용법

func makeJuice(for juice: Juice) throws -> Bool {
        for (fruit, requirements) in juice.recipe {
            guard let stock = fruitStorage[fruit]
            else {
                throw AppError.unknownError
            }
            if stock >= requirements {
                fruitStorage.updateValue(stock - requirements, forKey: fruit)
            }
            else {
                throw AppError.outOfStock
            }
        }
        return true
    }
  • For(key, value)문을 활용하여 딕셔너리 값의 반복처리를 할 수 있다. 딕셔너리는 넘겨받는 값의 타입이 튜플로 지정되어 넘어 온다.
  • 딕셔너리의 값을 접근하려면 서브스크립트를 활용해야 한다. 그런데 서브스크립트를 통해 접근한 딕셔너리key에 해당되는 value는 optional타입으로 반환된다.
  • 따라서 해당 값을 활용하고 싶으면 옵셔널바인딩을 활용하여 값을 추출해주어야 한다.
  • 또한 딕셔너리의 값을 변경하고 싶다면 updateValue(_:forKey:)를 활용하면 된다.
  • 위 작업을 통해 딕셔너리들의 key를 비교하고 조건에 맞게 value의 변화를 줄 수 있다.

참조:

[iOS, swift] thread-safety 한 싱글톤 사용은? | by Clint Jang | Medium

Swift) 싱글톤 패턴(Singleton Pattern) (tistory.com)

Swift3 ) Collection - Dictionary사용해보기 (tistory.com)

오늘의 Swift 상식 (Subscript). 서브스크립트란? | by 장국진 | Medium

swift3 ) Optional 개념 정리 (tistory.com)

updateValue(_:forKey:) | Apple Developer Documentation

profile
james, the enthusiastic developer

0개의 댓글