override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let cell = sender as? UICollectionViewCell, let indexPath = planetCollectionView.indexPath(for: cell){
let selected = solarSystemPlanets[indexPath.item]
if let vc = segue.destination as? PlanetDetailViewController{
//의존성 주입
vc.planet = selected
}
}
}
주입
: 의존 화면이 동작 가능하도록 필요한 객체를 외부에서 전달해 주는 것Property Injection
은 생성 후 주입되기 때문에 외부에서 접근할 수 있도록 처리해야 한다.class NoirFilter{
func apply(to image: UIImage) -> UIImage{
print("느와르 필터 적용중...")
return image
}
}
class SkyFilter{
func apply(to image: UIImage) -> UIImage{
print("스카이 필터 적용중...")
return image
}
}
class OceanFilter{
func apply(to image: UIImage) -> UIImage{
print("오션 필터 적용중...")
return image
}
}
이러한 예시 클래스가 있다고 가정해보자.
class PhotoExporter{
var filter: NoirFilter?
func export(image: UIImage){
guard let filter else{
fatalError("필터가 필요합니다.")
}
filter.apply(to: image)
print("사진을 익스포트 합니다.")
}
}
export
메소드를 정상적으로 실행하려면 필터가 반드시 존재해야 한다.export
메소드가 filter속성에 의존하게 되는 것이다.let img = UIImage(systemName: "star")!
let exporter = PhotoExporter()
exporter.filter = NoirFilter() // 속성 주입, Property Injection
exporter.export(image: img)
Initializer Injection
은 만들어진 시점에 의존성 주입이 된다.property Injection
에 비해 은닉성을 높이고, 효율적이고 안전한 코드를 짤 수 있다.class PhotoExporterIDI{
private let filter: NoirFilter
init(filter: NoirFilter) {
self.filter = filter
}
func export(image: UIImage){
filter.apply(to: image)
print("사진을 익스포트 합니다.")
}
}
let exporter2 = PhotoExporterIDI(filter: NoirFilter())
exporter2.export(image: img)
coupling
,결합도
: 다른 타입에 의존하는 정도의존관계 역전 원칙(Dependency Inversion Principle, DIP)
이다.protocol Filter{
func apply(to image: UIImage) -> UIImage
}
class NoirFilter: Filter{
func apply(to image: UIImage) -> UIImage{
print("느와르 필터 적용중...")
return image
}
}
class SkyFilter: Filter{
func apply(to image: UIImage) -> UIImage{
print("스카이 필터 적용중...")
return image
}
}
class OceanFilter: Filter{
func apply(to image: UIImage) -> UIImage{
print("오션 필터 적용중...")
return image
}
}
이렇게 프로토콜을 생성하게 되면 실제 PhotoExporter에서 사용하는 Filter를 전부 프로토콜로 변경 가능하게 되고, 여기에 NoirFilter, OceanFilter, SkyFilter중 무엇이 오든 상관없게 된다.
class PhotoExporterII{
private var filter: Filter
init(filter: Filter) { //Interface Injection
self.filter = filter
}
func export(image: UIImage){
filter.apply(to: image)
print("사진을 익스포트 합니다.")
}
}
let exporter3 = PhotoExporterII(filter: NoirFilter())
exporter3.export(image: img)