Protocol mvvm natasha

프로토콜 지향 MVVM을 소개합니다.

Swift에서 레퍼런스 타입 대신 밸류 타입을 사용하는 것은 Objective-C 보다 쉬우며, 이해하기 쉽고 에러가 적은 코드로 개선하는데 도움이 됩니다. 그러나 공유해서 사용해야 하는 상황에서는 이런 장점을 살리지 못하고 subclassing을 하는 실수를 하기 쉽습니다. do{iOS} 2015에서 MVVM에 대해 소개한 이 강연에서, 프로토콜을 사용하는 방법과 subclass에서 벗어나는 방법을 알아 보세요. 프로토콜 지향 프로그래밍에 대해 익히고 적용하는 등, Swift 2.0의 장점을 살리고 코드를 개선하기 위해 Natasha가 학습한 과정을 차근차근 설명해 줍니다.


Swift에서는 왜 코드를 단순화할까요? (0:00)

안녕하세요, Natasha입니다. Twitter에서는 @NatashaTheRobot을 사용합니다. 제 소개를 조금 하자면 저는 weekly Swift newsletter를 운영하고 있으며 블로그에 Swift에 관한 내용을 많이 기고합니다. Swift는 거의 공개 당일부터 사용해 왔죠.

Objective-C를 사용하는 개발자로써, 처음 Swift가 나왔을 땐 Swift 내부에 Objective-C 코드를 쓰는 방식으로 시작했고 레퍼런스 타입을 사용했습니다. 객체 지향 프로그래밍이 익숙했으므로 모든 것을 클래스로 만드는 것부터 시작하곤 했습니다. 마치 Objective-C의 태생처럼요.

그때까지만 해도 가끔 normal enum보다 복잡한 enum을 사용하기도 했기 때문에 나름 만족하고 있었습니다. 하지만 여러 행사와 강연을 다니고, 특히 Swift 복잡성 제어와 밸류 타입에 대한 Andy Matuschak의 강연을 듣고 나자 생각이 확 달라졌습니다. 그때까지는 Swift의 struct를 알고는 있었지만 Swift로 넘어간 Objective-C 개발자로써 클래스가 훨씬 더 자연스러웠죠.

그 인상적인 강연을 들은 후에는, 이제 모든 것에 밸류 타입을 사용해야겠다고 생각했습니다. 강연에서 밸류 타입을 사용하는 Swift 표준 라이브러리를 보여줬고, 언어 창시자들도 밸류 타입을 사용하니까요. 제 작업을 열어서 새 파일을 만들고 밸류 타입으로부터 시작해 봤습니다.

처음에는 “와, 나는 Swift 개발자야, struct를 사용하지!” 하는 마음에 즐거웠지만 subclass를 만들어야 하는 시점에서 괴로워졌고, 어떻게 이 장벽을 넘어서야 할지 모르겠더군요. 그러다가…

프로토콜 지향 프로그래밍(2:28)

2015년 WWDC의 한 멋진 강연에서 Swift의 프로토콜 지향 프로그래밍을 만났습니다! subclass 대신 프로토콜을 사용하는 방법을 알 수 있있죠. Swift에 적응해가는 분이라면 작년 WWDC 중 이 강연이 가장 유용할 겁니다.

이 강연에서 Apple의 Swift 표준 라이브러리 tech lead인 Dave Abrahams는 이렇게 말했습니다.

“Swift는 프로토콜 지향 프로그래밍 언어입니다.”

강연에서 그는 저를 포함한 모든 관중을 완전히 사로잡았습니다.

table view처럼 Apple이 사용하는 다양한 프로토콜을 보아 왔으므로 이것이 완전히 새로운 개념은 아닐 겁니다. 특히 사용할 때마다 UITableViewController를 subclassing하지 않아도 된다는 점에서 멋진 디자인 패턴이죠. Apple에 table view cell을 몇 개 만들지 알려주는 프로토콜을 사용하면 그만입니다. 자, 이제 이런 디자인 패턴의 위대함을 알았으니 더 나아가 볼까요?

프로토콜 지향 프로그래밍에 큰 감명을 받은 저는 프로토콜 지향 프로그래머가 되고 싶었습니다. 제 작업을 돌아보니 이미 정립된 패턴을 사용한 코드베이스가 보이더군요. 새로운 것을 적용하는 것 이전에 무엇을 사용해야 할지 아는 것부터가 어려웠습니다. 이미 존재하는 프로젝트에 갇힌 느낌이 들었고 이미 알고 있는 것에서 어떻게 개선해가야 할지 몰랐습니다.

심사숙고 후 깨달은 사용예 - MVVM (5:00)

저는 프로토콜을 제 코드에 통합할 방법을 몇 날 며칠 내내 생각했습니다. 그러다 잠에서 깨어난 어느날 모든 것이 하나로 연결된 기분이 들었습니다. 제 코드에 적용할 수 있는 최소 하나의 사용예를 찾아낸 것이죠. 바로 MVVM이었습니다.

이런 개발 뉴스를 더 만나보세요

혹시 MVVM이 낯선 분이라면 Ash Furrow의 “MVVM in Swift.”objc.io“Intro to MVVM.”을 확인해 보세요. 우선 간단한 예제를 보여드리겠습니다.

계좌 잔고를 보여주는 원본 데이터를 가진 모델이 있다고 가정해 보죠. 모델 레이어에서 원본 NSDecimalNumber로 값을 저장합니다.

let amount = 6729383.99

같은 숫자이지만 사용자에게는 “계좌 잔고는 이렇습니다.” 하고 안내하듯 잘 가공해서 보여줘야겠죠. 통화 단위도 붙이고요.

Your balance is $6,729,383.99

흔히 이 코드를 뷰 컨트롤러에 붙이는데, 그러면 뷰 컨트롤러가 무거워지고 테스트가 어려워집니다. 대신 이를 모델에 붙인다면 이번엔 모델이 복잡해지겠죠.

한편 모델을 명료하게 유지하고 원본 데이터를 반영할 수도 있습니다. 뷰 모델을 한번 볼까요?

struct AccountViewModel {
    let displayBalance: String
	
    init(mode: BankAccount) {
        let formattedBalance = model.balance.currencyValue
        displayBalance = "Your balance is \(formattedBalance)"
    }
}

모델을 포함하는 이 뷰 모델을 통해 정보를 뷰에 보여지기 원하는 형식으로 구성할 수 있습니다. 게다가 테스트도 쉽죠. 이 방법 대신 계좌 정보를 모델에 넣을 수도 있겠지만 출력값이 명료하지 않기 때문에 뷰 컨트롤러나 뷰를 테스트하기 어렵습니다.

조에트로프 모델 (8:29)

보여드린 뷰 모델은 밸류 타입입니다. Swift에서 어떻게 작동할까요?

뷰 컨트롤러가 최신 뷰 모델을 가져야 합니다. 밸류 타입의 데이터 타입이므로 단순히 데이터의 복사본일뿐 이 시점에서는 직접 반응해서는 안됩니다. 뷰 컨트롤러가 데이터의 복사본을 추적해서 어떤 정보가 사용자에게 보여질지 결정하죠. 가장 최신 버전의 복사본이 될 겁니다.

Andy Matuschak는 zoetrope에 빗대어 생각해보라고 합니다. 일본 지브리 박물관에 있는 기구죠.

핵심은 zoetrope의 각각의 프레임이 정적 값이라는 점입니다. 캐릭터의 손이 얼마나 높게 들렸는지, 혹은 머리가 얼마나 기울어졌는지에 따라 캐릭터를 인코딩할 수 있습니다. 각 버전은 정적이지만 모든 프레임을 모아서 가운데를 바라보면 항상 새로운 데이터 값이 보이게 되죠. 따라서 멋지게 움직이는 이미지를 만들 수 있습니다.

밸류 타입도 이 같은 방식으로 접근할 수 있습니다. 뷰 컨트롤러는 zoetrope의 가장 최근 프레임을 추적합니다. 즉, 활성화된 가장 최근 데이터를 사용자에게 보여주는 것이죠. 모델이 업데이트되자마자 새 데이터가 생기므로, 새 뷰 모델을 계산할 수 있습니다. 이제 뷰를 최신 정보로 업데이트할 수 있습니다.

var viewModel = ViewModel(model: Account)

최악의 프로토콜 (9:57)

자, 이제 가장 재밌는 부분을 간단한 예제와 함께 살펴볼까요? 대부분의 앱에 있는 설정 화면과 같은 테이블 뷰에 전체 앱을 노란색으로 칠하는 슬라이더 설정 하나만 있다고 가정해 봅시다.

정말 간단한 상황이지만 꽤 복잡해질 수 있습니다. 테이블 뷰 셀 내부의 모든 컴포넌트가 어떤 식으로든 형식이 맞춰져야 하죠. label이 있다면 폰트 종류, 폰트 색, 폰트 크기 등을 선언해야 합니다. switch가 있다면 그 switch가 켜질때도 생각해야겠죠. 단지 두 개의 element만을 포함한 아주 간단한 테이블 뷰 셀이지만 벌써 환경을 설정해야 할 6가지 케이스가 생겼습니다.

class SwitchWithTextTableViewCell: UITableViewCell {
    func configure(
        title: String,
        titleFont: UIFont,
        titleColor: UIColor,
        switchOn: Bool,
        switchColor: UIColor = .purpleColor(),
        onSwitchToggleHandler: onSwitchTogglerHandlerType? = nil)
    {
        // Configure views here
    }
}

아마 이보다 훨씬 더 복잡한 테이블 셀을 사용하는 것이 일반적일 겁니다. 그 경우 제 코드의 configure 메서드가 너무 커져버릴 수도 있습니다. subtitle을 붙인다면 3개의 새 프로퍼티를 더 설정해야 하죠. Swift에서는 이 때 기본 밸류를 사용할 수 있도록 지원하지만, configure 메서드 크기까지 해결해주진 못합니다.

실제로 이 메서드를 호출하는 뷰 컨트롤러에는 자기가 다뤄야할 정보를 담는 스택이 있습니다. 그다지 예쁘지 않아 맘에 들지는 않지만 프로토콜 이전에 사용할 수 있는 최선이었습니다.

뷰 모델과 프로토콜 (12:05)

방대한 configure 메서드를 버리고 셀을 위한 SwitchWithTextCellProtocol에 각 부분을 넣는 방법도 있습니다. 해당 프로토콜을 따르고, 해당 프로퍼티들을 알맞게 설정하는 뷰 모델을 만들 수 있죠. 이제 무식한 configure 메서드에서는 벗어났지만, 아직은 모든 프로퍼티가 실제로 설정되었는지 확인할 방법이 없습니다.

protocol SwitchWithTextCellProtocol {
    var title: String { get }
    var titleFont: UIFont { get }
    var titleColor: UIColor { get }
    
    var switchOn: Bool { get }
    var switchColor: UIColor { get }

    func onSwitchToggleOn(on: Bool)
}

Swift 2.0의 프로토콜 익스텐션을 사용하면 기본 밸류를 통해 같은 작업을 할 수 있습니다. 대부분의 셀과 관련된 특정색이 있다면 프로토콜 익스텐션을 extend해서 그 색을 설정하면 됩니다. 이제 이를 구현하는 모든 뷰 모델은 색을 다시 설정할 필요가 없어서 정말 편리합니다.

extension SwitchWithTextCellProtocol {
    var switchColor: UIColor {
        return .purpleColor()
    }
}

configure 메서드는 이 프로토콜을 따르는 기능을 다음처럼 포함할 수 있습니다.

class SwitchWithTextTableViewCell: UITableViewCell {
    func configure(withDelegate delegate: SwitchWithTextCellProtocol)
    {
        // Configure views here
    }
}

이전에는 6개 이상의 인자가 필요했지만, 이제 하나의 인자만 있으면 충분합니다. 이제 뷰 모델은 다음과 같은 모습입니다.

struct MinionModeViewModel: SwitchWithTextCellProtocol {
    var title = "Minion Mode!!!"
    var switchOn = true
    
    var switchColor: UIColor {
        return .yellowColor()
    }
    
    func onSwitchToggleOn(on: Bool) {
        if on {
            print("The Minions are here to stay!")
        } else {
            print("The Minions went out to play!")
        }
    }
}

위 예제는 프로토콜을 따르고 필요한 모든 것을 설정합니다. 이전 예제에서 봤듯 모델 객체와 함께 뷰 모델을 초기화할 수 있습니다. 이제 뷰에 보여줄 형식을 파악하기 위해 잔고 정보가 필요한 상황처럼 특정 정보가 필요할때라면, 뷰 모델을 통해 정보를 실제로 사용할 수 있습니다.

간단명료하죠? 이제 cellForRowAtIndexPath()도 아주 간결하게 만들 수 있습니다.

// YourViewController.swift
let cell = tableView.dequeueReusableCellWithIdentifier("SwitchWithTextTableViewCell", forIndexPath: indexPath) as! SwitchWithTextTableViewCell

// This is where the magic happens!
cell.configure(withDelegate: MinionModeViewModel())

return cell

셀을 dequeue하고 뷰 모델과 함께 configure 메서드를 호출했습니다. 이 경우, 해당 프레이밍, 모델 레이어를 가지지 않아도 모델을 뷰 컨트롤러 레벨에서 추적할 수 있습니다. 뷰 모델에 넘기면 셀이 생성되죠. 리팩토링 이후 코드에는 오직 세 줄만이 남습니다!

더 많이 추상화하기 (14:10)

이제까지 6개의 인자가 있는 방대한 configure 메서드를 프로토콜로 변환하는 프로토콜 사용예를 보여드렸습니다. 압축적인 로직으로 코드를 멋지게 개선하는 사용예를 찾아내서 만족스러운 마음으로 이에 관한 블로그를 썼습니다. 그런데 “프로토콜을 두 개 만들어서 하나는 실제 인코딩된 정보의 데이터 소스 프로토콜로 사용하면 어떨까요?” 라는 댓글이 달렸습니다. 형식을 만드는 것과 실제 정보가 분리돼야 하듯 색과 폰트처럼 대립되는 정보는 분리돼야 하겠죠. 실제로 Apple이 UITableViewCells나 컬렉션 뷰에서 사용하는 패턴입니다.

정말 멋진 아이디어라고 생각해서 제 로직도 분리해서 아래처럼 셀 데이터 저장소와 셀 델리게이트를 만들었습니다.

protocol SwitchWithTextCellDataSource {
    var title: String { get }
    var switchOn: Bool { get }
}

protocol SwitchWithTextCellDelegate {
    func onSwitchToggleOn(on: Bool)
    
    var switchColor: UIColor { get }
    var textColor: UIColor { get }
    var font: UIFont { get }
}

그 다음, configure 메서드와 데이터 스토리지로 델리게이트를 만들었습니다. 폰트 종류나 색처럼 기본 밸류의 경우 프로토콜 익스텐션에서 델리게이트를 모두 설정할 수 있으므로, 인자를 넘길 필요도 없이 필요할 때 만들기만 하면 됩니다.

// SwitchWithTextTableViewCell
func configure(withDataSource dataSource: SwitchWithTextCellDataSource, delegate: SwitchWithTextCellDelegate?)
{
    // Configure views here
}

익스텐션으로 뷰 모델을 개선했습니다. 데이터 소스를 따르고, 원본 정보를 변환해서 뷰로 넘기는 셀 블록 하나가 생기죠.

struct MinionModeViewModel: SwitchWithTextCellDataSource {
    var title = "Minion Mode!!!"
    var switchOn = true
}

다음으로 독립적인 뷰 모델에 폰트나 색을 보유하고 내부적으로 처리하는 델리게이트를 만듭니다.

extension MinionModeViewModel: SwitchWithTextCellDelegate {
    var switchColor: UIColor {
        return .yellowColor()
    }
    
    func onSwitchToggleOn(on: Bool) {
        if on {
            print("The Minions are here to stay!")
        } else {
            print("The Minions went out to play!")
        }
    }
}

마침내 테이블 뷰 셀이 정말 간결해졌습니다.

// SettingsViewController

let viewModel = MinionModeViewModel()
cell.configure(withDataSource: viewModel, delegate: viewModel)
return cell

뷰 모델을 만들고 configure 메서드에 넘겨서 셀을 반환받았습니다.

Swift 2.0의 Mixins과 Traits (16:32)

프로토콜을 만들고 코드를 간결하게 바꾸며 블로그 기고를 하고 배움도 얻어서 아주 만족스러웠던 그 때, 다른 분에게도 꼭 추천하고 싶은 놀라운 기사, @mhollemansSwift 2.0의 Mixins를 읽었습니다.

게임 개발에서는 계층구조가 강하고 Subclassing이 자주 일어납니다. 몬스터는 여러 다른 몬스터 타입을 가지는 식입니다. 뷰의 Subclassing이 필요해지죠. 하지만 결국 엉망진창인 구조가 될 수밖에 없습니다.

Game Development Hierarchy

이런 계층구조라면 처음 시작은 좋을지 모르지만, 결과적으로 공격을 하는 몬스터를 만들다가 성 위에 캐넌포를 놓을 수 있기 때문에 공격을 하는 성을 만들 수도 있습니다. 따라서 shooting helper를 추출하는게 좋겠죠. 처음 subclassing을 할 때 단순할 것이라고 예상했던 것들이 점점 복잡해지고 결국 스파게티 코드의 주범이 될 수 있습니다.

Matthijs는 이 코드를 리팩토링해서 무엇이 공격이나 치료를 할 수 있는지 하위 객체에 정하는 로직을 버리고 프로토콜 익스텐션을 사용해서 프로토콜로 발췌했습니다.

리팩토링 결과 코드가 훨씬 간결해지고 이해하기 쉬워졌죠. 예제를 볼까요?

class ZapMonster: GameObject, GunTrait, RenderTrait, HealthTrait, MovementTrait {
    ...
}

구현 부분을 보지 않아도 객체의 타입만으로 객체에 어떤 일이 일어날지 파악할 수 있습니다. 이 패턴을 사랑하지 않을 수가 없네요!

앱에 Mixins 적용하기 (19:47)

사실 게임 개발에 대한 얘기였지만 이 컨셉을 테이블 뷰 셀이 있는 제 코드에 적용할 수 있었습니다. 프로토콜을 실제 셀에 결부하지 않고 보다 포괄적인 TextPresentable에 결부시켰죠. 이 방식으로 셀뿐만 아니라 label을 지닌 어떤 뷰이든지 텍스트를 보여주는 프로토콜을 따를 수 있습니다. TextPresentable에서 이 텍스트에 포함될 것이 무엇인지, 혹은 어떤 텍스트, 어떤 색, 어떤 폰트를 사용할 것인지 말할 수 있는 곳입니다.

protocol TextPresentable {
    var text: String { get }
    var textColor: UIColor { get }
    var font: UIFont { get }
}

protocol SwitchPresentable {
    var switchOn: Bool { get }
    var switchColor: UIColor { get }
    
    func onSwitchToggleOn(on: Bool)
}

switch는 어떻게 설정될지 모두 다루는 자체 프로토콜을 가지게 됩니다. 게임 개발 예를 들면 쉽게 연상할 수 있죠. 이미지가 있으면 ImagePresentable 프로토콜도 있습니다. 마찬가지로 텍스트 필드의 모든 설정을 담당하는 TextFieldPresentable 프로토콜이 있죠.

protocol ImagePresentable {
    var imageName: String { get }
}

protocol TextFieldPresentable {
    var placeholder: String { get }
    var text: String { get }
    
    func onTextFieldDidEndEditing(textField: UITextField)
}

프로토콜 익스텐션을 사용해서 모든 폰트와 색 혹은 TextPresentable 프로토콜을 따르는 뷰를 설정할 수 있습니다. TextPresentable 프로토콜은 label 기본 설정을 위한 기본 설정을 가지고, 앱 다른 부분의 label도 비슷하게 구성됩니다.

extension TextPresentable {
    
    var textColor: UIColor {
        return .blackColor()
    }
    
    var font: UIFont {
        return .systemFontOfSize(17)
    }
    
}

더 나아가 헤더 label처럼 다른 종류의 label을 만들 수도 있습니다. 특정 폰트와 색을 가진 이 label은 앱 전체에서 몇 번이고 재사용할 수 있죠. 디자이너가 와서 오늘 모든 헤더를 파란색으로 바꿔달라고 요청한다 해도 즉각 간단하게 바꿀 수 있습니다. 프로토콜 익스텐션에 가서 파란색으로 바꾸면, HeaderTextPresentable를 가진 모든 뷰의 헤더 label이 단 한줄 수정만으로 마법처럼 바뀝니다.

이 아름다운 패턴을 적용한 제 셀입니다.

class SwitchWithTextTableViewCell<T where T: TextPresentable, T: SwitchPresentable>: UITableViewCell {
    private var delegate: T?
    
    func configure(withDelegate delegate: T) {
        // Configure views here
    }
}

이 경우 자기 자신이 직접 이들 프로토콜을 따르지는 않지만, 이를 따를 무언가가 올 것이란 예상 하에 generic을 사용하고 있습니다. 셀은 TextPresentableProtocolSwitchPresentableProtocol을 따르는 델리게이트를 기대하고 있죠. 따라서 configure 메서드에서는 어떤 객체가 올지 고려하지 않아도 됩니다. 제 경우 뷰 모델이 되겠지만, 어쨌거나 이들 프로토콜을 따르는 무언가가 필요할 뿐이죠. 이제 이를 기반으로 셀의 모든 것을 설정할 수 있습니다.

extension MinionModeViewModel: TextPresentable {
    var text: String { return "Minion Mode" }
    var textColor: UIColor { return .blackColor() }
    var font: UIFont { return .systemFontOfSize(17.0) }
}

제 뷰 모델은 텍스트와 색, 폰트, 혹은 프로토콜 익스텐션의 어떤 기본값이든 설정할TextPresentable 블록을 가질텐데, 심지어 뷰 모델을 구현하지 않아도 됩니다.

SwitchPresentable도 마찬가지입니다. switch가 켜져야 할까요? 켜지면 어떻게 될까요?

extension MinionModeViewModel: Switch Presentable {
    var switchOn: Bool { return false } 
    var switchColor: UIColor { return .yellowColor() }
   
    func onSwitchToggleOn(on: Bool) {
        if on {
            print("The Minions are here to stay!")
        } else {
            print("The Minions went out to play!")
        }
    }
}

마지막으로 뷰 컨트롤러 내의 코드는 아주 단순합니다. 셀을 deque하면 끝이죠. 뷰 모델에서 설정해서 셀을 반환받습니다. generic을 사용하므로 어떤 T가 올지 특정할 필요가 없다는 것이 핵심입니다. 여기서는 T가 뷰 모델이었습니다.

진화하는 언어, Swift (24:02)

여기까지 해낸 것도 정말 기뻤지만, Swift는 겨우 2년 된 언어이기 때문에 변화가 많으므로 커뮤니티로서 어떤 것이 베스트 프렉티스인지 결정해야 했습니다.

새로운 패턴을 발견하거나 새 패턴을 코드에 넣기 전 저는 이를 얼마나 쉽게 변경할 수 있는지를 고려합니다. 제 신조는 다음과 같습니다.

변화만이 영원하다.

특히 코딩에 잘 적용되는 말입니다. 테스트를 추가하거나 iOS 7에 맞게 디자인 하는 것같은 수정 사항이 발생하기 때문에 저는 자주 앱을 재작성하곤 합니다. Apple이 새로운 기능을 선보이거나 앱에 기능을 추가하거나 삭제하는 것처럼 변화는 항상 발생하죠.

PM이 와서 “이 셀에 이미지를 넣고 싶은데.” 라고 말한다면, 기존에 있던 label과 switch에 이미지만 더하면 됩니다. 단지 셀에 ImagePresentableProtocol에 맞는 무언가를 기대하라고 정하기만 하면 셀 레이어에서 할 작업은 끝입니다.

또한 코드 두 줄만을 추가해서 configure 메서드가 실제로 이미지를 사용하도록 업데이트했습니다. 마지막으로 뷰 모델을 extend 했습니다.

extension MinionModeViewModel: ImagePresentable {
    var imageName: String { return "minionParty.png" }
}

Natasha the Happy Robot: 결론 (26:26)

요약하자면 다음과 같이 MVVM 패턴을 적용하여 프로토콜을 적용했습니다.

  • 뷰 설정을 위해 프로토콜 사용
  • 주로 subclassing을 하게되는 부분인 폰트와 색, 설정 기본 값을 전체 앱에서 공통으로 사용할 수 있도록 프로토콜 익스텐션 사용
  • 프로토콜을 위한 데이터 제공을 위해 테스트가 편한 뷰 모델 사용, 어떤 뷰 모델 버전을 사용할지 뷰 컨트롤러가 결정 가능

사실 Swift의 새로운 패턴이 내년 WWDC에서 발표되거나 이 강연 직후 누군가 새로운 아이디어를 tweet 할 수도 있습니다. 그러므로 Swift로 작업하는 경우 열린 마음을 가지길 권유합니다. 어떻게 여러분의 코드를 개선할 수 있을지 고민해보세요.

개선할 수 있는 방법은 항상 존재합니다. 동료들이 공유하는 내용이나 커뮤니티 소식을 자주 확인하면 많은 도움이 될 겁니다. 현재 상황으로도 저는 행복하지만 당장 다음 주에 제 마음을 바꾸게 하거나 새로운 것을 알려주는 기고를 발견할 지도 모릅니다.

Swift의 멋진 점은 Swift 개발자들이 제각기 다른 경험을 해왔다는 점입니다. 함수형 언어나 Ruby, .NET 등 여러분의 동료는 각기 다른 환경에서 개발한 경험을 가지고 있을 수 있고, 따라서 여러분과 다른 아이디어를 낼 수도 있을 겁니다. Swift는 진화하는 언어이므로 열린 마음을 갖고 다른 사람들의 시각에서 배워가야 합니다. 그러면 자신의 코드 패턴을 향상할 수도 있고, 나아가 어떤 것이 가장 좋은 패턴인지 파악하는 것에도 도움이 될 수 있습니다. 여러분은 항상 개선해 나갈 수 있고 발견을 공유할 수 있고 이런 활동을 지속할 수 있습니다.

다음: iOS 프로그래밍 아키텍처와 패러다임 #5: Swift와 함수형 프로그래밍의 역사

General link arrow white

컨텐츠에 대하여

2016년 11월에 진행한 DO iOS Conference 행사의 강연입니다. 영상 녹화와 제작, 정리 글은 Realm에서 제공하며, 주최 측의 허가 하에 이곳에서 공유합니다.

Natasha Murashev

Natasha is secretly a robot that loves to learn about Swift and iOS development. She previously worked as a senior iOS Engineer at Capital One in San Francisco, but now she travels around, writing about her experiences with new technologies. In her free time, she works on personal projects, speaks at meetups and conferences, contributes to open source, and likes to cross things off her bucket list.

4 design patterns for a RESTless mobile integration »

close