Инкапсуляция
Суть
Инкапсуляция — это объединение данных и работающего с ними поведения в одном типе плюс контроль доступа к этому состоянию. Снаружи виден только контракт (публичный интерфейс), а инварианты («баланс не бывает отрицательным») защищены внутри типа. Это локализует изменения: можно переписать хранение данных, не трогая клиентов.
Как это выглядит в Swift
Уровни доступа от самого закрытого к самому открытому: private (внутри объявления и его extension в том же файле), fileprivate, internal (по умолчанию, весь модуль), package (несколько модулей одного пакета, Swift 5.9), public (виден из других модулей), open (можно ещё и наследовать/переопределять извне модуля). Отдельно есть private(set) — читать можно всем, писать только внутри.
import Foundation
struct BankAccount {
private(set) var balance: Decimal = 0
private var history: [Decimal] = []
mutating func deposit(_ amount: Decimal) {
precondition(amount > 0)
balance += amount
history.append(amount)
}
}
var account = BankAccount()
account.deposit(100)
print(account.balance) // 100
// account.balance = 1_000 // error: setter is private
На что смотрит интервьюер
- Инкапсуляция — не «скрыть всё», а выставить минимальный контракт и защищать инварианты. Свойства с
didSet/вычисляемые свойства позволяют поменять реализацию, не меняя API. privateв Swift работает на уровне файла дляextension, а не на уровне класса, как в Java — частый вопрос-ловушка.- Value types усиливают инкапсуляцию: копия
structне делит состояние с оригиналом, поэтому «чужой» код не может изменить ваш объект через случайно сохранённую ссылку. @testable importоткрываетinternalдля тестов, но неprivate: тестируйте поведение через публичный API.