728x90
factory pattern (팩토리 패턴)
객체를 사용하는 코드에서 생성 부분을 떼어내 추상화한 패턴.
상속 관계에 있는 두 클래스에서 상위 클래스가 중요한 뼈대를 결정하고,
하위 클래스에서 객체 생성에 관한 구체적인 내용을 결정하는 패턴.
장점
- 낮은 결합도
- 상위 클래스와 하위 클래스가 분리되므로 낮은 결합도를 가진다.
- 확장성 및 유지보수성 증가
- 객체 생성 로직이 분리되어 수정 시 한 곳만 수정할 수 있다.
예제 코드 (Kotlin)

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fun main() { | |
val latte = CoffeeFactory.getCoffee("Latte", 4000) | |
val ame = CoffeeFactory.getCoffee("Americano", 3000) | |
val milk = CoffeeFactory.getCoffee("Milk", 2000) | |
println("Factory latte :: $latte") | |
println("Factory ame :: $ame") | |
println("Factory milk :: $milk") | |
} | |
// 상위 클래스로 중요한 뼈대를 설정 | |
object CoffeeFactory { | |
fun getCoffee(type: String, price: Int): Coffee { | |
return when { | |
"Latte".equals(type, ignoreCase = true) -> Latte(price) | |
"Americano".equals(type, ignoreCase = true) -> Americano(price) | |
else -> DefaultCoffee() | |
// Enum, Map을 이용해 if문을 사용하지 않고 매핑할 수 있다. | |
} | |
} | |
} | |
abstract class Coffee { | |
abstract val price: Int | |
override fun toString(): String { | |
return "This coffee is $price" | |
} | |
} | |
class Latte(override val price: Int): Coffee() | |
class Americano(override val price: Int): Coffee() | |
class DefaultCoffee: Coffee() { | |
override val price: Int | |
init { | |
price = -1 | |
} | |
} | |
/* | |
Factory latte :: This coffee is 4000 | |
Factory ame :: This coffee is 3000 | |
Factory milk :: This coffee is -1 | |
*/ |
* String의 equals 옵션 ignoreCase : true로 설정할 시 문자열의 대소문자를 구분하지 않고 비교한다.
* abstract class (추상 클래스) : 미완성 클래스, 이 자체로 인스턴스화될 수 없는 클래스.
* abstract : 상속을 받는 곳에서 구현을 강제시키는 키워드
(위 코드에서 price 변수에 abstract 키워드가 사용되어 DefaltCoffee class에서 price 변수의 값을 필수로 초기화해야 한다.)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fun main() { | |
var gs: GameServer | |
gs = GameServerFactory.KRGameServer | |
gs.execute("supermario") | |
println() | |
gs = GameServerFactory.JPGameServer | |
gs.execute("tetris") | |
} | |
object GameServerFactory { | |
val KRGameServer = KRGameServer() | |
val JPGameServer = JPGameServer() | |
} | |
abstract class GameServer { | |
protected abstract fun chooseGame(game: String): Games | |
fun GameServer() = println("연결 성공") | |
fun execute(game: String) { | |
val games: Games = chooseGame(game) | |
games.bootUpGame() | |
games.runGame() | |
} | |
} | |
abstract class Games { | |
abstract val title: String | |
abstract val version: String | |
fun bootUpGame() { | |
println("게임: $title") | |
println("버전: $version") | |
println("$title 게임 준비 완료") | |
} | |
fun runGame() = println("$title 게임 시작") | |
} | |
class KRGameServer : GameServer() { | |
private val supermario: Games = KRSuperMario() | |
private val tetris: Games = KRTetris() | |
override fun chooseGame(game: String): Games { | |
return when (game) { | |
"tetris" -> tetris | |
"supermario" -> supermario | |
else -> throw IllegalArgumentException("지원되지 않는 게임입니다.") | |
} | |
} | |
} | |
class JPGameServer : GameServer() { | |
private val supermario: Games = JPSuperMario() | |
private val tetris: Games = JPTetris() | |
override fun chooseGame(game: String): Games { | |
return when (game) { | |
"tetris" -> tetris | |
"supermario" -> supermario | |
else -> throw IllegalArgumentException("지원되지 않는 게임입니다.") | |
} | |
} | |
} | |
class KRSuperMario( | |
override val title: String = "수퍼마뤼오", | |
override val version: String = "1.0.4" | |
) : Games() | |
class KRTetris( | |
override val title: String = "테투리수", | |
override val version: String = "1.0.5" | |
) : Games() | |
class JPSuperMario( | |
override val title: String = "スーーパーーマリオ", | |
override val version: String = "1.0.6" | |
) : Games() | |
class JPTetris( | |
override val title: String = "テトリスですよー!", | |
override val version: String = "1.0.7" | |
) : Games() | |
/* | |
게임: 수퍼마뤼오 | |
버전: 1.0.4 | |
수퍼마뤼오 게임 준비 완료 | |
수퍼마뤼오 게임 시작 | |
게임: テトリスですよー! | |
버전: 1.0.7 | |
テトリスですよー! 게임 준비 완료 | |
テトリスですよー! 게임 시작 | |
*/ |
참고
- https://github.com/wnghdcjfe/csnote/blob/main/ch1/6.java
- https://gold.gitbook.io/kotlin/class/abstract
- https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/equals.html
- [쉽게 배우는 소프트웨어 공학 2판]
필자의 보완점
- Factory Method (팩토리 메서드), Abstract Factory (추상 팩토리) 등이 있는 것 같으나 어떤 차이인지 잘 모르겠다.
728x90
'CS note > 디자인 패턴, 프로그래밍 패러다임' 카테고리의 다른 글
MVC pattern (Model View Controller) (0) | 2023.04.30 |
---|---|
strategy pattern (전략 패턴) (1) | 2023.01.27 |
singleton pattern (싱글톤 패턴) (0) | 2023.01.20 |
디자인 패턴 및 프로그래밍 패러다임 (0) | 2023.01.20 |
댓글