๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿฅ– Bread Basics/Swift

Swift ๊ณต์‹ ๋ฌธ์„œ ์ •๋ฆฌ - ์ ‘๊ทผ ์ œ์–ด (Access Control)

by BreadDev 2025. 4. 13.
728x90

์•ˆ๋…•ํ•˜์„ธ์š”. ์˜ค๋Š˜์€ ์ฝ”๋“œ ๊ตฌ์กฐํ™”์™€ ์บก์Аํ™”์— ํ•„์š”ํ•œ '์ ‘๊ทผ ์ œ์–ด(Access Control)'์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ ‘๊ทผ ์ œ์–ด๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ์˜ ์–ด๋–ค ๋ถ€๋ถ„์„ ์™ธ๋ถ€์— ๋…ธ์ถœํ•˜๊ณ , ์–ด๋–ค ๋ถ€๋ถ„์„ ์ˆจ๊ธธ์ง€ ํšจ๊ณผ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ ์ ‘๊ทผ ์ œ์–ด๋ž€?

์ ‘๊ทผ ์ œ์–ด(Access Control)๋Š” ๋‹ค๋ฅธ ์†Œ์Šค ํŒŒ์ผ์ด๋‚˜ ๋ชจ๋“ˆ์—์„œ ์ฝ”๋“œ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ ์ œํ•œํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ์˜ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ์ˆจ๊ธฐ๊ณ , ์ฝ”๋“œ๊ฐ€ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ ‘๊ทผ ์ œ์–ด์˜ ์ฃผ์š” ๋ชฉ์ :

  • ์ฝ”๋“œ์˜ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ ์ˆจ๊ธฐ๊ธฐ
  • ์ฝ”๋“œ ์‚ฌ์šฉ์„ ์œ„ํ•œ ๋ช…ํ™•ํ•œ ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜
  • ์‹ค์ˆ˜๋กœ ์ธํ•œ ์ž˜๋ชป๋œ ์ฝ”๋“œ ์‚ฌ์šฉ ๋ฐฉ์ง€
  • ๋‚ด๋ถ€ ๊ตฌํ˜„ ๋ณ€๊ฒฝ ์‹œ ์™ธ๋ถ€ ์ฝ”๋“œ์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ ์ตœ์†Œํ™”

๐Ÿ“Œ ๋ชจ๋“ˆ, ์†Œ์Šค ํŒŒ์ผ, ํŒจํ‚ค์ง€์˜ ์ดํ•ด

Swift์˜ ์ ‘๊ทผ ์ œ์–ด๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋จผ์ € ๋‹ค์Œ ๊ฐœ๋…์„ ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค:

  • ๋ชจ๋“ˆ(Module): ์ฝ”๋“œ ๋ฐฐํฌ์˜ ๋‹จ์ผ ๋‹จ์œ„๋กœ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์—ฌ๊ธฐ์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. Swift์—์„œ import ํ‚ค์›Œ๋“œ๋กœ ๋‹ค๋ฅธ ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์†Œ์Šค ํŒŒ์ผ(Source File): ๋ชจ๋“ˆ ๋‚ด์˜ ๋‹จ์ผ Swift ์†Œ์Šค ์ฝ”๋“œ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.
  • ํŒจํ‚ค์ง€(Package): ํ•˜๋‚˜์˜ ๋‹จ์œ„๋กœ ๊ฐœ๋ฐœ๋˜๋Š” ๋ชจ๋“ˆ ๊ทธ๋ฃน์ž…๋‹ˆ๋‹ค. Swift Package Manager๋‚˜ Xcode ์„ค์ •์—์„œ ์ •์˜๋ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ Swift์˜ 5๊ฐ€์ง€ ์ ‘๊ทผ ์ˆ˜์ค€

Swift๋Š” ์ฝ”๋“œ์˜ ์ ‘๊ทผ์„ฑ์„ ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” 5๊ฐ€์ง€ ์ ‘๊ทผ ์ˆ˜์ค€์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค:

1. Open ์ ‘๊ทผ ์ˆ˜์ค€

  • ๊ฐ€์žฅ ๊ฐœ๋ฐฉ์ ์ธ ์ ‘๊ทผ ์ˆ˜์ค€
  • ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ ์ ‘๊ทผ๊ณผ ์„œ๋ธŒํด๋ž˜์‹ฑ ๊ฐ€๋Šฅ
  • ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋“œ ๊ฐ€๋Šฅ
  • ํด๋ž˜์Šค์™€ ํด๋ž˜์Šค ๋ฉค๋ฒ„์—๋งŒ ์ ์šฉ ๊ฐ€๋Šฅ
  • ์‚ฌ์šฉ ์˜ˆ: ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๊ธฐ๋ณธ ํด๋ž˜์Šค๋กœ ํ™•์žฅ์„ ๊ณ ๋ คํ•œ ์„ค๊ณ„
 
open class OpenClass {
    open func openMethod() {}
}

2. Public ์ ‘๊ทผ ์ˆ˜์ค€

  • ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ ์„œ๋ธŒํด๋ž˜์‹ฑ์ด๋‚˜ ์˜ค๋ฒ„๋ผ์ด๋“œ ๋ถˆ๊ฐ€
  • ์‚ฌ์šฉ ์˜ˆ: ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๊ณต๊ฐœ API
 
public class PublicClass {
    public var publicProperty = 0
}

3. Internal ์ ‘๊ทผ ์ˆ˜์ค€

  • ๊ธฐ๋ณธ ์ ‘๊ทผ ์ˆ˜์ค€
  • ๋ชจ๋“ˆ ๋‚ด์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • ์‚ฌ์šฉ ์˜ˆ: ์•ฑ์ด๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ
 
internal class InternalClass {  // 'internal'์€ ์ƒ๋žต ๊ฐ€๋Šฅ
    var internalProperty = 0
}

4. File-private ์ ‘๊ทผ ์ˆ˜์ค€

  • ์ •์˜๋œ ์†Œ์Šค ํŒŒ์ผ ๋‚ด์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • ์‚ฌ์šฉ ์˜ˆ: ํŒŒ์ผ ๋‚ด ์—ฌ๋Ÿฌ ํƒ€์ž…์—์„œ ๊ณต์œ ํ•˜์ง€๋งŒ ์™ธ๋ถ€์— ๋…ธ์ถœํ•˜์ง€ ์•Š์„ ๊ธฐ๋Šฅ
 
fileprivate class FilePrivateClass {
    fileprivate func filePrivateMethod() {}
}

5. Private ์ ‘๊ทผ ์ˆ˜์ค€

  • ๊ฐ€์žฅ ์ œํ•œ์ ์ธ ์ ‘๊ทผ ์ˆ˜์ค€
  • ์ •์˜๋œ ์„ ์–ธ๊ณผ ๊ทธ ์„ ์–ธ์˜ ํ™•์žฅ ๋‚ด์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • ์‚ฌ์šฉ ์˜ˆ: ํŠน์ • ํƒ€์ž… ๋‚ด์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋Š” ์ƒ์„ธ ๊ตฌํ˜„
 
private class PrivateClass {
    private func privateMethod() {}
}

์ ‘๊ทผ ์ˆ˜์ค€ ๊ณ„์ธต: Open(์ตœ์†Œ ์ œํ•œ) > Public > Internal > File-private > Private(์ตœ๋Œ€ ์ œํ•œ)

๐Ÿ“Œ ์ ‘๊ทผ ์ œ์–ด์˜ ๊ธฐ๋ณธ ์›์น™

Swift์˜ ์ ‘๊ทผ ์ œ์–ด๋Š” ์ค‘์š”ํ•œ ๊ธฐ๋ณธ ์›์น™์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค:

์—”ํ‹ฐํ‹ฐ๋Š” ๋” ๋‚ฎ์€(๋” ์ œํ•œ์ ์ธ) ์ ‘๊ทผ ์ˆ˜์ค€์„ ๊ฐ€์ง„ ๋‹ค๋ฅธ ์—”ํ‹ฐํ‹ฐ๋กœ ์ •์˜๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด:

  • Public ๋ณ€์ˆ˜๋Š” Internal, File-private, Private ํƒ€์ž…์œผ๋กœ ์ •์˜๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ํ•จ์ˆ˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…์ด๋‚˜ ๋ฐ˜ํ™˜ ํƒ€์ž…๋ณด๋‹ค ๋” ๋†’์€ ์ ‘๊ทผ ์ˆ˜์ค€์„ ๊ฐ€์งˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ด ์›์น™์€ ํ•ญ์ƒ ๋” ์ œํ•œ์ ์ธ ์ชฝ์œผ๋กœ ์ ‘๊ทผ ์ˆ˜์ค€์ด ๊ฒฐ์ •๋จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ๊ธฐ๋ณธ ์ ‘๊ทผ ์ˆ˜์ค€

Swift์—์„œ ๋ช…์‹œ์ ์œผ๋กœ ์ ‘๊ทผ ์ˆ˜์ค€์„ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด, ๋Œ€๋ถ€๋ถ„์˜ ์—”ํ‹ฐํ‹ฐ๋Š” internal ์ ‘๊ทผ ์ˆ˜์ค€์„ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๊ฐ–์Šต๋‹ˆ๋‹ค.

์ด๋Š” ๋‹จ์ผ ๋ชจ๋“ˆ ์•ฑ ๊ฐœ๋ฐœ์— ํŽธ๋ฆฌํ•˜์ง€๋งŒ, ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐœ๋ฐœ ์‹œ์—๋Š” ๊ณต๊ฐœํ•  API๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ public ๋˜๋Š” open์œผ๋กœ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ์‚ฌ์šฉ์ž ์ •์˜ ํƒ€์ž…์˜ ์ ‘๊ทผ ์ œ์–ด

ํƒ€์ž…๊ณผ ๋ฉค๋ฒ„์˜ ๊ด€๊ณ„

ํƒ€์ž…์˜ ์ ‘๊ทผ ์ˆ˜์ค€์€ ํ•ด๋‹น ํƒ€์ž…์˜ ๋ฉค๋ฒ„(ํ”„๋กœํผํ‹ฐ, ๋ฉ”์„œ๋“œ, ์ดˆ๊ธฐํ™” ๊ตฌ๋ฌธ, ์„œ๋ธŒ์Šคํฌ๋ฆฝํŠธ)์˜ ๊ธฐ๋ณธ ์ ‘๊ทผ ์ˆ˜์ค€์— ์˜ํ–ฅ์„ ์ค๋‹ˆ๋‹ค:

public class SomePublicClass {
    public var publicProperty = 0     // ๋ช…์‹œ์  public
    var internalProperty = 0          // ์•”์‹œ์  internal
    fileprivate func filePrivateMethod() {}  // ๋ช…์‹œ์  file-private 
    private func privateMethod() {}   // ๋ช…์‹œ์  private
}

์ค‘์š”: Public ํƒ€์ž…์˜ ๋ฉค๋ฒ„๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ public์ด ์•„๋‹Œ internal์ž…๋‹ˆ๋‹ค. ํƒ€์ž… ๋ฉค๋ฒ„๋ฅผ ๊ณต๊ฐœํ•˜๋ ค๋ฉด ๋ช…์‹œ์ ์œผ๋กœ public์œผ๋กœ ํ‘œ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํŠœํ”Œ ํƒ€์ž…

ํŠœํ”Œ์˜ ์ ‘๊ทผ ์ˆ˜์ค€์€ ํŠœํ”Œ์— ํฌํ•จ๋œ ๋ชจ๋“  ํƒ€์ž… ์ค‘ ๊ฐ€์žฅ ์ œํ•œ์ ์ธ ์ ‘๊ทผ ์ˆ˜์ค€์œผ๋กœ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค:

// (Internal, Private) ํŠœํ”Œ์˜ ์ ‘๊ทผ ์ˆ˜์ค€์€ Private
internal class InternalClass {}
private class PrivateClass {}

// ์ด ํ•จ์ˆ˜๋Š” ๋ฐ˜ํ™˜ ํƒ€์ž…์ด Private์ด๋ฏ€๋กœ 
// Private์œผ๋กœ ์„ ์–ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค
private func someFunction() -> (InternalClass, PrivateClass) {
    // ํ•จ์ˆ˜ ๊ตฌํ˜„
}

ํ•จ์ˆ˜ ํƒ€์ž…

ํ•จ์ˆ˜์˜ ์ ‘๊ทผ ์ˆ˜์ค€์€ ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…๊ณผ ๋ฐ˜ํ™˜ ํƒ€์ž… ์ค‘ ๊ฐ€์žฅ ์ œํ•œ์ ์ธ ์ ‘๊ทผ ์ˆ˜์ค€์œผ๋กœ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค:

// ์ด ํ•จ์ˆ˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ private์ด๋ฏ€๋กœ 
// private ์ด์ƒ์˜ ์ ‘๊ทผ ์ˆ˜์ค€์ด ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค
private func processSomeData(data: PrivateClass) -> InternalClass {
    // ํ•จ์ˆ˜ ๊ตฌํ˜„
}

๐Ÿ“Œ ํŠน์ˆ˜ํ•œ ๊ฒฝ์šฐ์˜ ์ ‘๊ทผ ์ œ์–ด

์—ด๊ฑฐํ˜•๊ณผ ์ผ€์ด์Šค

์—ด๊ฑฐํ˜•์˜ ๊ฐ ์ผ€์ด์Šค๋Š” ์ž๋™์œผ๋กœ ์—ด๊ฑฐํ˜• ์ž์ฒด์™€ ๋™์ผํ•œ ์ ‘๊ทผ ์ˆ˜์ค€์„ ๊ฐ–์Šต๋‹ˆ๋‹ค:

public enum CompassPoint {
    case north // ์ž๋™์œผ๋กœ public
    case south // ์ž๋™์œผ๋กœ public
    case east  // ์ž๋™์œผ๋กœ public
    case west  // ์ž๋™์œผ๋กœ public
}

Getter์™€ Setter

ํ”„๋กœํผํ‹ฐ๋‚˜ ์„œ๋ธŒ์Šคํฌ๋ฆฝํŠธ์˜ ์ ‘๊ทผ ์ˆ˜์ค€์„ ๋” ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•ด getter์™€ setter์— ๋‹ค๋ฅธ ์ ‘๊ทผ ์ˆ˜์ค€์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

struct TrackedString {
    private(set) var numberOfEdits = 0  // getter๋Š” internal, setter๋Š” private
    var value: String = "" {
        didSet {
            numberOfEdits += 1
        }
    }
}

var stringToEdit = TrackedString()
stringToEdit.value = "This string will be tracked."
print(stringToEdit.numberOfEdits)  // ์ฝ๊ธฐ ๊ฐ€๋Šฅ
// stringToEdit.numberOfEdits = 0  // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜: setter๋Š” private

์ด ๊ธฐ๋Šฅ์€ ํ”„๋กœํผํ‹ฐ ๊ฐ’์€ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋˜, ์ˆ˜์ •์€ ์ œํ•œํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ์ดˆ๊ธฐํ™” ๊ตฌ๋ฌธ์˜ ์ ‘๊ทผ ์ œ์–ด

์ดˆ๊ธฐํ™” ๊ตฌ๋ฌธ์€ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ํƒ€์ž…๊ณผ ๊ฐ™๊ฑฐ๋‚˜ ๋” ๋‚ฎ์€ ์ ‘๊ทผ ์ˆ˜์ค€์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

public class PublicClass {
    private let privateProperty: Int
    
    // ํƒ€์ž…์€ public์ด์ง€๋งŒ ์ดˆ๊ธฐํ™” ๊ตฌ๋ฌธ์€ internal
    init(value: Int) {
        privateProperty = value
    }
    
    // ํƒ€์ž…๊ณผ ๋™์ผํ•œ public ์ ‘๊ทผ ์ˆ˜์ค€์˜ ์ดˆ๊ธฐํ™” ๊ตฌ๋ฌธ
    public init(publicValue: Int) {
        privateProperty = publicValue
    }
    
    // private ์ ‘๊ทผ ์ˆ˜์ค€์˜ ์ดˆ๊ธฐํ™” ๊ตฌ๋ฌธ
    private init() {
        privateProperty = 0
    }
}

๊ธฐ๋ณธ ์ดˆ๊ธฐํ™” ๊ตฌ๋ฌธ

ํƒ€์ž…์ด public์ด๊ณ  ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ์— ๊ธฐ๋ณธ๊ฐ’์ด ์žˆ์„ ๊ฒฝ์šฐ, ๊ธฐ๋ณธ ์ดˆ๊ธฐํ™” ๊ตฌ๋ฌธ์€ internal๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ public์œผ๋กœ ๋งŒ๋“ค๋ ค๋ฉด ๋ช…์‹œ์ ์œผ๋กœ ์„ ์–ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

public struct PublicStruct {
    public var someValue = 0
    
    // ๋ช…์‹œ์ ์œผ๋กœ public ์ดˆ๊ธฐํ™” ๊ตฌ๋ฌธ ์„ ์–ธ
    public init() {}
}

๐Ÿ“Œ ํ”„๋กœํ† ์ฝœ์˜ ์ ‘๊ทผ ์ œ์–ด

ํ”„๋กœํ† ์ฝœ๊ณผ ์š”๊ตฌ์‚ฌํ•ญ

ํ”„๋กœํ† ์ฝœ์˜ ์ ‘๊ทผ ์ˆ˜์ค€์€ ํ”„๋กœํ† ์ฝœ ๋‚ด ๋ชจ๋“  ์š”๊ตฌ์‚ฌํ•ญ์˜ ์ ‘๊ทผ ์ˆ˜์ค€์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค:

public protocol PublicProtocol {
    // ๋ชจ๋“  ์š”๊ตฌ์‚ฌํ•ญ์€ ์ž๋™์œผ๋กœ public
    func publicRequiredMethod()
    var publicRequiredProperty: Int { get set }
}

์ค‘์š”: Public ํ”„๋กœํ† ์ฝœ์˜ ์š”๊ตฌ์‚ฌํ•ญ์€ ๊ตฌํ˜„ ์‹œ public ์ ‘๊ทผ ์ˆ˜์ค€์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœํ† ์ฝœ ์ค€์ˆ˜์„ฑ

ํƒ€์ž…์ด ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•  ๋•Œ, ํ”„๋กœํ† ์ฝœ ์ค€์ˆ˜์„ฑ์˜ ์ ‘๊ทผ ์ˆ˜์ค€์€ ํƒ€์ž…๊ณผ ํ”„๋กœํ† ์ฝœ ์ค‘ ๋” ์ œํ•œ์ ์ธ ์ ‘๊ทผ ์ˆ˜์ค€์œผ๋กœ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค:

public class PublicClass: InternalProtocol {
    // ํ”„๋กœํ† ์ฝœ ์ค€์ˆ˜์„ฑ์€ internal
    // ์š”๊ตฌ์‚ฌํ•ญ ๊ตฌํ˜„์€ ์ตœ์†Œ internal์ด์–ด์•ผ ํ•จ
}

๐Ÿ“Œ ํ™•์žฅ(Extension)์˜ ์ ‘๊ทผ ์ œ์–ด

ํ™•์žฅ์„ ์‚ฌ์šฉํ•  ๋•Œ, ์ƒˆ ๋ฉค๋ฒ„๋Š” ํ™•์žฅ๋˜๋Š” ํƒ€์ž…์˜ ๊ธฐ๋ณธ ์ ‘๊ทผ ์ˆ˜์ค€์„ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค:

public class PublicClass {
    // ๋ฉค๋ฒ„๋Š” internal ๊ธฐ๋ณธ๊ฐ’
}

extension PublicClass {
    // ์ถ”๊ฐ€๋œ ๋ฉค๋ฒ„๋„ internal ๊ธฐ๋ณธ๊ฐ’
    func newMethod() {}
}

ํ™•์žฅ์— ๋ช…์‹œ์ ์œผ๋กœ ์ ‘๊ทผ ์ˆ˜์ค€์„ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:

extension PublicClass {
    // ์ด ํ™•์žฅ์˜ ๋ชจ๋“  ๋ฉค๋ฒ„๋Š” private
    private func privateMethod() {}
}

๊ฐ™์€ ํŒŒ์ผ ๋‚ด Private ๋ฉค๋ฒ„ ์ ‘๊ทผ

๊ฐ™์€ ํŒŒ์ผ ๋‚ด์—์„œ๋Š” ํ™•์žฅ๊ณผ ์›๋ž˜ ์„ ์–ธ ์‚ฌ์ด์— private ๋ฉค๋ฒ„์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

struct SomeStruct {
    private var privateVariable = 12
}

// ๊ฐ™์€ ํŒŒ์ผ์˜ ํ™•์žฅ์—์„œ private ๋ฉค๋ฒ„ ์ ‘๊ทผ ๊ฐ€๋Šฅ
extension SomeStruct {
    func doSomething() {
        print(privateVariable) // ์ ‘๊ทผ ๊ฐ€๋Šฅ
    }
}

๐Ÿ“Œ ์ œ๋„ค๋ฆญ๊ณผ ํƒ€์ž… ๋ณ„์นญ์˜ ์ ‘๊ทผ ์ œ์–ด

์ œ๋„ค๋ฆญ ํƒ€์ž…

์ œ๋„ค๋ฆญ ํƒ€์ž…์ด๋‚˜ ํ•จ์ˆ˜์˜ ์ ‘๊ทผ ์ˆ˜์ค€์€ ํƒ€์ž… ์ž์ฒด์™€ ํƒ€์ž… ์ œ์•ฝ ์กฐ๊ฑด ์ค‘ ๊ฐ€์žฅ ์ œํ•œ์ ์ธ ์ ‘๊ทผ ์ˆ˜์ค€์œผ๋กœ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค:

// PrivateClass ์ œ์•ฝ์ด ์žˆ์œผ๋ฏ€๋กœ ์ด ์ œ๋„ค๋ฆญ ํ•จ์ˆ˜๋Š” 
// private๋ณด๋‹ค ๋†’์€ ์ ‘๊ทผ ์ˆ˜์ค€์„ ๊ฐ€์งˆ ์ˆ˜ ์—†์Œ
private func genericFunction<T: PrivateClass>(item: T) {}

ํƒ€์ž… ๋ณ„์นญ

ํƒ€์ž… ๋ณ„์นญ์€ ์›๋ณธ ํƒ€์ž…๋ณด๋‹ค ๊ฐ™๊ฑฐ๋‚˜ ๋” ์ œํ•œ์ ์ธ ์ ‘๊ทผ ์ˆ˜์ค€์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋” ๋†’์€ ์ ‘๊ทผ ์ˆ˜์ค€์€ ๊ฐ€์งˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค:

public class SomePublicClass {}

// ์›๋ณธ๋ณด๋‹ค ๋” ์ œํ•œ์ ์ธ ์ ‘๊ทผ ์ˆ˜์ค€ ๊ฐ€๋Šฅ
internal typealias InternalAlias = SomePublicClass

// ์›๋ณธ๋ณด๋‹ค ๋” ๊ฐœ๋ฐฉ์ ์ธ ์ ‘๊ทผ ์ˆ˜์ค€์€ ๋ถˆ๊ฐ€๋Šฅ
// public typealias PublicAlias = SomeInternalClass // ์˜ค๋ฅ˜

๐Ÿ“Œ ์ ‘๊ทผ ์ œ์–ด ์‹ค์ „ ํ™œ์šฉ ์ „๋žต

1. ๋‹จ์ผ ํƒ€๊ฒŸ ์•ฑ ๊ฐœ๋ฐœ ์‹œ

๋‹จ์ผ ์•ฑ ๊ฐœ๋ฐœ ์‹œ์—๋Š” ๊ธฐ๋ณธ ์ ‘๊ทผ ์ˆ˜์ค€์ธ internal์„ ํ™œ์šฉํ•˜๊ณ , ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๊ตฌํ˜„ ์„ธ๋ถ€์‚ฌํ•ญ์€ private์ด๋‚˜ fileprivate๋กœ ์ˆจ๊ธฐ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค:

class ProfileViewController {
    // ๋‹ค๋ฅธ ํด๋ž˜์Šค์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” API
    var user: User?
    func loadUserData() {}
    
    // ๋‚ด๋ถ€ ๊ตฌํ˜„ ์„ธ๋ถ€์‚ฌํ•ญ
    private func formatUserData() {}
    private func setupViews() {}
}

2. ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐœ๋ฐœ ์‹œ

ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐœ๋ฐœ ์‹œ์—๋Š” ๊ณต๊ฐœ API๋ฅผ public์ด๋‚˜ open์œผ๋กœ ๋ช…ํ™•ํžˆ ์ง€์ •ํ•˜๊ณ , ๋‚˜๋จธ์ง€๋Š” internal ์ดํ•˜๋กœ ์œ ์ง€ํ•˜์„ธ์š”:

// ๊ณต๊ฐœ API
open class NetworkManager {
    // ์™ธ๋ถ€์—์„œ ์„œ๋ธŒํด๋ž˜์‹ฑํ•˜๊ณ  ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ
    open func request(url: URL) -> Data? {}
    
    // ์™ธ๋ถ€์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์˜ค๋ฒ„๋ผ์ด๋“œํ•  ์ˆ˜ ์—†๋Š” ๋ฉ”์„œ๋“œ
    public func cancel() {}
    
    // ๋‚ด๋ถ€ ๊ตฌํ˜„ ์„ธ๋ถ€์‚ฌํ•ญ
    internal func parseResponse() {}
    private func setupSession() {}
}

3. ํŒ€ ๊ฐœ๋ฐœ ์‹œ

์—ฌ๋Ÿฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•จ๊ป˜ ์ž‘์—…ํ•  ๋•Œ๋Š” ๋ชจ๋“ˆ ๊ฒฝ๊ณ„๋ฅผ ์ž˜ ์ •์˜ํ•˜๊ณ , API ๊ณ„์•ฝ์„ ๋ช…ํ™•ํžˆ ํ•˜๊ธฐ ์œ„ํ•ด ์ ‘๊ทผ ์ œ์–ด๋ฅผ ์ ๊ทน ํ™œ์šฉํ•˜์„ธ์š”:

// ํŒ€์˜ ๋‹ค๋ฅธ ๊ตฌ์„ฑ์›์ด ์‚ฌ์šฉํ•  API
public protocol UserService {
    func getUser(id: String) -> User?
    func saveUser(_ user: User)
}

// ๊ตฌํ˜„ ์„ธ๋ถ€์‚ฌํ•ญ์€ ์ˆจ๊น€
internal class UserServiceImpl: UserService {
    private let database: Database
    
    public func getUser(id: String) -> User? {
        return findUserInDatabase(id)
    }
    
    public func saveUser(_ user: User) {
        validateUser(user)
        saveUserToDatabase(user)
    }
    
    private func findUserInDatabase(_ id: String) -> User? {}
    private func validateUser(_ user: User) {}
    private func saveUserToDatabase(_ user: User) {}
}

๐Ÿ“Œ ์ •๋ฆฌ

Swift์˜ ์ ‘๊ทผ ์ œ์–ด ์‹œ์Šคํ…œ์€ ์ฝ”๋“œ์˜ ์บก์Аํ™”์™€ ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜์— ํ•„์ˆ˜์ ์ธ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ์˜ฌ๋ฐ”๋ฅธ ์ ‘๊ทผ ์ˆ˜์ค€์„ ์„ ํƒํ•จ์œผ๋กœ์จ:

  • ์ฝ”๋“œ์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์„ ์ˆจ๊ธฐ๊ณ  ๊ฒฌ๊ณ ํ•œ API ๊ฒฝ๊ณ„๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
  • ์‹ค์ˆ˜๋กœ ์ธํ•œ ์ž˜๋ชป๋œ ์‚ฌ์šฉ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
  • ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ ์˜ํ–ฅ ๋ฒ”์œ„๋ฅผ ์ œํ•œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
  • ์ฝ”๋“œ ์˜๋„๋ฅผ ๋ช…ํ™•ํžˆ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค