지난 시간에 이어 오늘은 Bridge 패턴에 대해 알아보겠습니다.
추상적인 것과 구체적인 것을 분리하여 연결하는 패턴입니다. 둘을 분리하지 않고 하나의 계층에서 사용하면 계층 구조가 커지고 중복된 코드를 여러번 작성해야 하는 불편함이 존재합니다.
패턴 적용 전
protocol Poketmon {
func skill()
func move()
func attack()
}
class 피카츄: Poketmon {
func skill() {
print("피카츄가 백만볼트 스킬을 사용합니다.")
}
func move() {
print("피카츄가 움직입니다.")
}
func attack() {
print("피카츄가 공격합니다.")
}
}
class 파이리: Poketmon {
func skill() {
print("파이리가 브래스 스킬을 사용합니다.")
}
func move() {
print("파이리가 움직입니다.")
}
func attack() {
print("파이리가 공격합니다.")
}
}
프로토콜을 이용해 포켓몬이 가지고 있어야 하는 기능을 정리하고 각각의 클래스를 만들어 프로토콜을 채택하게 만들어 주었습니다.
만약 라이추 클래스를 만들다면 피카추와 똑같은 코드를 작성해야 합니다. 또 한 같은 전기 스킬을 사용하는 포켓몬을 만든다면 모든 전기 속성인 포켓몬이 사용하는 스킬을 따로 분리해 관리해 주는 것이 좋을 것 같습니다.
패턴 적용
class DefaultPoketmon: Poketmon { // Abstraction
let attribute: Attribute
let name: String
init(attribute: Attribute, name: String) {
self.attribute = attribute
self.name = name
}
func skill() {
print("\(name)가 \(attribute.defaultSkill()) 스킬을 사용합니다.")
}
func move() {
print("\(name)가 움직입니다.")
}
func attack() {
print("\(name)가 공격합니다.")
}
}
class 피카추: DefaultPoketmon {
init() {
super.init(attribute: Electricity(), name: "피카추")
}
}
class 파이리: DefaultPoketmon {
init(attribute: Attribute) {
super.init(attribute: Fire(), name: "파이리")
}
}
각각의 타입이 갖는 메서드를 정의해서 사용해도 됩니다.
protocol Attribute {
func defaultSkill() -> String
}
class Electricity: Attribute {
func defaultSkill() -> String {
return "100만 볼트"
}
}
class Fire: Attribute {
func defaultSkill() -> String {
return "브래스"
}
}
이처럼 Bridge 패턴을 적용하면 여러 클래스를 만들어 새로운 계층을 생성해 사용할 수 있습니다.
해당 글은 인프런의 코딩으로 학습하는 GoF 디자인 패턴 강의와 블로그를 참고해 작성했습니다.
⭐️ 부족하거나 잘못된 부분이 있다면 댓글은 언제나 환영입니다!! ⭐️