Swift-style-guide: ํ”„๋กœํ† ์ฝœ ๋ช…๋ช…

์— ๋งŒ๋“  2015๋…„ 12์›” 07์ผ  ยท  9์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: raywenderlich/swift-style-guide

ํ”„๋กœํ† ์ฝœ์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋Š” ์„ ํ˜ธํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ? "able" ๋˜๋Š” "ing" ์ ‘๋ฏธ์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ฝค ์ข‹์€ ๋‹ต๋ณ€์œผ๋กœ ์ด StackExchange ์งˆ๋ฌธ ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์„ ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@mitchellporter ๊ฐ€ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ "ํ”„๋กœํ† ์ฝœ"์„ ์‚ฌ์šฉํ•˜์ž๋Š” ์ œ์•ˆ์„ ๋ณด์•˜์ง€๋งŒ "์œ ํ˜•" ์ ‘๋ฏธ์‚ฌ๋Š” ๊ณต๋ฃก์˜ ๊ธธ์„ ๊ฐ€๊ณ  ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Swift API ๋””์ž์ธ ์ง€์นจ์—์„œ :

๋ฌด์—‡์ธ๊ฐ€๋ฅผ ์„ค๋ช…ํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์€ ๋ช…์‚ฌ๋กœ ์ฝ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ์ปฌ๋ ‰์…˜). ๊ธฐ๋Šฅ์„ ์„ค๋ช…ํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์€able, ible ๋˜๋Š” ing ์ ‘๋ฏธ์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฆ„์„ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: Equatable, ProgressReporting).

๋ชจ๋“  9 ๋Œ“๊ธ€

C# ์ด๋ฆ„ ์Šคํƒ€์ผ์„ Swift๋กœ ๋ฒˆ์—ญํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ค์šธ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค์˜ 'I'๋Š” ๋„ค์ž„์ŠคํŽ˜์ด์Šค๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— .NET์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋™๋ช…์‚ฌ("able" ๋ฐ "ing")๋Š” ์˜์–ด์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘๋™ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
"๋™๋ช…์‚ฌ๋Š” ๋™์‚ฌ์— "-ing"์„ ๋ถ™์—ฌ ๋งŒ๋“  ๋ช…์‚ฌ์ž…๋‹ˆ๋‹ค.

์˜ˆ: ์ด ํด๋ž˜์Šค๋ฅผ ํ•ด์‹œ(๋™์‚ฌ)ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•ด์‹œ ๊ฐ€๋Šฅ(๋™๋ช…์‚ฌ)์ž…๋‹ˆ๊นŒ? ๋น„๊ตํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค(๋™์‚ฌ), ์ด ํด๋ž˜์Šค๋Š” ๋น„๊ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ(๋™๋ช…์‚ฌ)?

C#์„ ๋ณด๋ฉด ๋ชจ๋“  ์ธํ„ฐํŽ˜์ด์Šค์— ๋™๋ช…์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋„ ์•Š์Šต๋‹ˆ๋‹ค. Point(ํด๋ž˜์Šค) ๋ฐ IPoint(X ๋ฐ Y๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค)๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์˜๋ฏธ ์žˆ๋Š” ๊ฒƒ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ์•ฝ๊ฐ„ ์˜คํ•ด์˜ ์†Œ์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

UITableViewDelegate ๋ฐ UITableViewDataSource์™€ ๊ฐ™์€ ํ”„๋กœํ† ์ฝœ์€ ๋‚˜์—๊ฒŒ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ฐœ์ธ์ ์œผ๋กœ ...ํ”„๋กœํ† ์ฝœ ์ ‘๋ฏธ์‚ฌ์— ๋ฌธ์ œ๊ฐ€ ์—†์ง€๋งŒ ์ผ๋ฐ˜์ ์ธ ๊ทœ์น™์œผ๋กœ ์›ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๋•Œ๋กœ๋Š” 'able'์ด ๋” ์ž˜ ์ž‘๋™ํ•˜๊ณ  ๋•Œ๋กœ๋Š” ...Delegate ๋˜๋Š” ...DataSource์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ์ ‘๋ฏธ์‚ฌ๊ฐ€ ๋” ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

์˜ค๋Š˜ ๋งŒ๋“ค์–ด์ง€๋ฉด UITableViewDelegateType ๋ฐ UITableViewDataSourceType์ด๋ผ๊ณ  ๋ถ€๋ฅผ ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. Greg Heo๋Š” ์ด๊ฒƒ์„ "is a"๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค: http://www.skilled.io/gregheo/what-the-55-swift-standard-library-protocols-taught-me

๋‚ด ์ž์‹ ์˜ ๋งŽ์€ ํ”„๋กœํ† ์ฝœ์€ ํ•˜๋‚˜์˜ ๊ธฐ๋Šฅ์ด๋‚˜ ์†์„ฑ๋งŒ ์บก์Šํ™”ํ•ฉ๋‹ˆ๋‹ค. Swift๋Š” ํ”„๋กœํ† ์ฝœ ์ด๋ฆ„์„ ๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ์ง€์ •ํ•˜๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€ ์—†์œผ๋ฉฐ ๋งค์šฐ ๊นจ๋—ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

protocol bool {
   var bool: Bool {get}
}

struct Struct: bool {
   let bool = true
}

ํ•„์š”ํ•  ๋•Œ ์ผ๋ฐ˜ ๋Œ€๋ฆฌ์ž ๋ฐ ๋ฐ์ดํ„ฐ ์†Œ์Šค ๋ช…๋ช… ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ ๋‹จ์ˆœํžˆ ๊ฐœ์ฒด๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ํ”„๋กœํ† ์ฝœ์˜ ๊ฒฝ์šฐ ์ด๋ฆ„์— Protocol ๋ฅผ ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ชจ๋ฒ” ์‚ฌ๋ก€์ธ์ง€ ์•„๋‹Œ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์กฐ์‚ฌํ–ˆ์„ ๋•Œ ์ •๋ณด๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

protocol AlertModalProtocol {
func titleText() -> String
func messageText() -> String
}

struct NewUserAlertModal: AlertModalProtocol {

    func titleText() -> String {
        return "Welcome new user"
    }

    func messageText() -> String {
        return "Thanks for joining the app."
    }
}

@mitchellporter ๊ฐ€ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ "ํ”„๋กœํ† ์ฝœ"์„ ์‚ฌ์šฉํ•˜์ž๋Š” ์ œ์•ˆ์„ ๋ณด์•˜์ง€๋งŒ "์œ ํ˜•" ์ ‘๋ฏธ์‚ฌ๋Š” ๊ณต๋ฃก์˜ ๊ธธ์„ ๊ฐ€๊ณ  ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Swift API ๋””์ž์ธ ์ง€์นจ์—์„œ :

๋ฌด์—‡์ธ๊ฐ€๋ฅผ ์„ค๋ช…ํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์€ ๋ช…์‚ฌ๋กœ ์ฝ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ์ปฌ๋ ‰์…˜). ๊ธฐ๋Šฅ์„ ์„ค๋ช…ํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์€able, ible ๋˜๋Š” ing ์ ‘๋ฏธ์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฆ„์„ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: Equatable, ProgressReporting).

๊ทธ ํฅ๋ฏธ ๋กญ๊ตฐ์š”. ๋‚ด ๊ฒฝํ—˜์ƒ, Thing์€ ์ „ํ†ต์ ์œผ๋กœ ๋น„์ถ”์ƒ ํด๋ž˜์Šค์˜€์„ ๋•Œ ThingType์ด ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค. (์ฆ‰, Thing์€ ThingType์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ตฌ์ฒด์ ์ธ ์œ ํ˜•์ด๊ณ  ๋” ๊ตฌ์ฒด์ ์ธ ๋‹ค๋ฅธ ์œ ํ˜•๋„ ThingType์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.) NSObjectProtocol์€ ์ด๋Ÿฌํ•œ ์œ ํ˜•์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค.

API ๋””์ž์ธ ์ง€์นจ ์ดˆ์•ˆ์˜ ๋ผ์ธ์„ ๋”ฐ๋ผ ๋ช‡ ๊ฐ€์ง€ ํ…์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋น ๋ฅธ
๋‹ค๋ฅธ ์‚ฌ๋žŒ์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด์„œ ๋ฌธ์ œ์— ์ง๋ฉดํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฌด์—‡์ธ์ง€, ๋ช…์‚ฌ์ผ ๋•Œ ์„ค๋ช…ํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์ด ์ข…์ข… ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ์™€ ํ˜ผ๋™๋˜๊ธฐ ๋•Œ๋ฌธ์— ์กฐ์šฉํžˆ ๋ถˆํŽธํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ๋‹ค์Œ ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹์Šต๋‹ˆ๋‹ค.

When the protocol name is a noun - write ..Protocol (yes, even in swift);
์˜ˆ: PhotoModuleProtocol
When the protocol is an adverb or an adjective - write ..able, ..ing and so on;
์˜ˆ: ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ

๋‚ด ์ƒ๊ฐ์—๋Š” Swift hipster์˜ ๊ฒƒ๋ณด๋‹ค ๋ˆ„๊ตฐ๊ฐ€์˜ ์ฝ”๋“œ๋ฅผ ์ธ์‹ํ•˜๋Š” ์‹œ๊ฐ„์„ ์นด์šดํŠธ๋‹ค์šดํ•˜๋Š” ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ๋ช…์‹œ์ ์œผ๋กœ ์ง€๊ธˆ ๋ฐํžˆ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

2015๋…„์— ๋งˆ์ง€๋ง‰ ๋Œ“๊ธ€์„ ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค... ๊ทธ ์ดํ›„๋กœ @gregheo๊ฐ€ ์ด์ „์— ๊ณต์œ ํ•œ ๊ฒƒ์„ ์ฃผ๋กœ ์‚ฌ์šฉํ•˜๋„๋ก ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฌด์—‡์ธ๊ฐ€๋ฅผ ์„ค๋ช…ํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์€ ๋ช…์‚ฌ๋กœ ์ฝ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ์ปฌ๋ ‰์…˜). ๊ธฐ๋Šฅ์„ ์„ค๋ช…ํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์€able, ible ๋˜๋Š” ing ์ ‘๋ฏธ์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฆ„์„ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: Equatable, ProgressReporting).

์˜ˆ๋ฅผ ๋“ค์–ด ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋ณธ ๋ชจ๋ธ ์œ ํ˜•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

protocol BaseType {
    var objectId: String { get set }
    var createdAt: NSDate? { get set }
    var updatedAt: NSDate? { get set }
    func toJSON() -> [String: AnyObject]
    static func from(json: [String: AnyObject]) -> AnyObject
}

์•ฑ ์ „์ฒด์˜ ๋ชจ๋“  ๋ชจ๋ธ์—๋Š” ์ด ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•˜๋ฏ€๋กœ ๋ชจ๋‘ BaseType ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์•ฑ ์ด๋ฆ„์„ ๋”ฐ์„œ ์ด ๊ธฐ๋ณธ ์œ ํ˜•์˜ ์ด๋ฆ„์„ ์ง€์ •ํ–ˆ์œผ๋ฏ€๋กœ ์•ฑ ์ด๋ฆ„์ด Instagram ์ด๋ฉด InstagramType ๋ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ ์ƒ๊ฐํ•ด๋ณด๋‹ˆ ์ด๋ฆ„์— Type ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ์€ ๋ฌด์˜๋ฏธํ•ด ๋ณด์ž…๋‹ˆ๋‹ค... ์ด๋ฆ„์„ BaseModel , InstagramModel ๋˜๋Š” ์‹ฌ์ง€์–ด Model .

๊ธฐ๋Šฅ์„ ์„ค๋ช…ํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์— ๊ด€ํ•ด์„œ๋Š” ๊ฐ€๋Šฅ, ible ๋ฐ ing ์œ ํ˜• ์ ‘๋ฏธ์‚ฌ๋„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด ์ด๋ฆ„์— protocol ๋ผ๋Š” ๋‹จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ค‘๋ณต๋˜๋Š” ๋Š๋‚Œ์ด ๋“ค์—ˆ๊ณ  "์ด๋ด, ์ด๊ฒƒ์€ ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ํ”„๋กœํ† ์ฝœ์ž…๋‹ˆ๋‹ค" ํ”„๋กœํ† ์ฝœ์€ ํด๋ž˜์Šค ์œ„๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ์‹ ์†ํ•˜๊ฒŒ ํด๋ž˜์Šค์™€ ๋™์ผํ•˜๊ฒŒ ๊ฐ„์ฃผ๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž˜๋ชป๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ด๋ฆ„์— ํ”„๋กœํ† ์ฝœ์„ ํฌํ•จํ•˜์—ฌ ๋‹จ์ผ ํ•ญ๋ชฉ์œผ๋กœ ์ง€์ •ํ•˜์ง€ ์•Š๊ณ  ๊ทธ๋ƒฅ ๋‘ก๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹จ์ง€ ๋‚˜์—๊ฒŒ ์˜ณ๋‹ค๊ณ  ๋Š๋ผ๋Š” ๊ฒƒ์ด๋ฉฐ, ๋‚˜๋Š” ์ด๊ฒƒ์ด ์˜ณ๋‹ค ๊ทธ๋ฅด๋‹ค๋ฅผ ์ฃผ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ช‡ ๋…„์ด ์ง€๋‚œ ํ›„์—๋„ ๋‚˜๋Š” ํ•ญ์ƒ Swift์—์„œ ์ƒˆ๋กœ์šด ๊ฒƒ์„ ๋ฐœ๊ฒฌํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋ชจ๋“  ๊ฒƒ์„ ์•Œ์•„๋‚ด๋ ค๋Š” ์‹œ๋„๋ฅผ ํฌ๊ธฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ด ์‹œ์ ์—์„œ ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ๋ฌด์—‡์„ ์ œ๊ณตํ•˜๋Š”์ง€ ์‹คํ—˜ํ•˜๊ณ  ํ™•์ธํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. :)

๊ทธ๋ž˜๋„ ๋ช…์‚ฌ๋กœ ํ”„๋กœํ† ์ฝœ์„ ๋ช…๋ช…ํ•˜๋ฉด ํด๋ž˜์Šค๊ฐ€ ์•„๋‹ˆ๋ผ ํ”„๋กœํ† ์ฝœ์ž„์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋‹จ์–ด("..Model", "..Type" ๋“ฑ์ด ๋  ์ˆ˜ ์žˆ์Œ)๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ด ๋‹จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ๋ณ€๊ฒฝ =)

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰

๊ด€๋ จ ๋ฌธ์ œ

luki picture luki  ยท  3์ฝ”๋ฉ˜ํŠธ

agirault picture agirault  ยท  3์ฝ”๋ฉ˜ํŠธ

hollance picture hollance  ยท  28์ฝ”๋ฉ˜ํŠธ

designatednerd picture designatednerd  ยท  22์ฝ”๋ฉ˜ํŠธ

icanzilb picture icanzilb  ยท  6์ฝ”๋ฉ˜ํŠธ