Closed Youngminah closed 2 years ago
import UIKit
struct Eat {
func coffee() {
print("아메리카노")
}
func meal() {
print("피자")
}
}
struct Person {
var todayEat: Eat
func coffee() {
todayEat.coffee()
}
func meal() {
todayEat.meal()
}
}
Person
객체는 Eat
객체를 인스턴스로 사용하고 있으므로, Eat객체에 의존성이 생긴다.Eat
객체에 중요한 수정이나 오류가 발생한다면, Person
객체도 영향을 받을 수 있다. Dependency Injection
, 의존성 주입이다.class Eat:Menu {
var coffee: String
var meal: String
init(coffee: String, meal: String) {
self.coffee = coffee
self.meal = meal
}
func printCoffee() {
print("아메리카노")
}
func printMeal() {
print("피자")
}
}
let menu = Eat(coffee: "아메리카노", meal: "피자")
테스트용이한 코드 작성하기
의 핵심DIP: 의존 관계 역전 법칙
을 알아야 한다. protocol Menu {
func printCoffee()
func printMeal()
}
이후 Eat클래스는 Menu Protocol을 채택한 후, Protocol에 정의한 함수를 실체화 시켜준다.
class Eat: Menu {
var coffee: String
var meal: String
init(coffee: String, meal: String) {
self.coffee = coffee
self.meal = meal
}
func printCoffee() {
print("아메리카노")
}
func printMeal() {
print("피자")
}
}
이제부터 중요한 부분이 나온다. 기존의 방식과 다르게 todayEat변수는 추상적인 객체인 Menu타입에 의존하게 된다. 여기서 changeMenu함수를 활용해서 의존성 주입을 시킬 수 있다.
struct Person {
var todayEat: Menu
func printCoffee() {
todayEat.printCoffee()
}
func printMeal() {
todayEat.printMeal()
}
mutating func changeMenu(menu: Menu) {
self.todayEat = menu
}
}
이렇게 구현한다면 Eat객체와 Person객체는 거의 독립적인 객체가 된다. Eat 객체를 수정하거나 Person을 수정한다고 해서 상대 객체를 함께 수정해야 하는 문제를 방지할 수 있다.
let menu = Eat(coffee: "아메리카노", meal: "피자")
let anotherMenu = Eat(coffee: "라떼", meal: "햄버거")
var suhshin = Person(todayEat: menu)
suhshin.printCoffee() // print 아메리카노
suhshin.changeMenu(menu: anotherMenu)
suhshin.printCoffee() // print 라떼
SOLID
객체 설계에 필요한 5가지 원칙으로써 유지보수가 쉽고, 유연하고, 확장이 쉬운 소프트웨어를 만들기 위한 수단으로 본다.
객체의 책임이란
Knowing
,Doing
으로 나뉜다.S: SRP (Single Responsibility Principle) : 단일 책임 원칙
SRP 적용전
SRP 적용후
O: OCP ( Open-Closed Principle ): 개방, 폐쇄 원칙
OCP 적용전
OCP 적용후
L: LSP ( Liskov Substitution Principle): 리스코프 치환 원칙
LSP 적용전
LSP 적용후
I: ISP(Interface Segregation Principle): 인터페이스 분리 원칙
ISP 적용전
ISP 적용후
D: DIP (Dependency Inversion Principle) : 의존관계 역전 원칙
DIP 적용전
class 개발자 { let 노트북: 맥북13인치
init(노트북: 맥북13인치) { self.노트북 = 노트북 }
func 개발시작() { 노트북.전원켜기() } }