Design Pattern

[01] Facade 패턴

y0ngha 2021. 10. 26. 17:27

회사에서 프로젝트를 진행하면서, 결제 로직을 만들 때 결제를 하기 위한 파라미터가 너무 많아 실제로 사용하는 Class에서는 많은 파라미터를 넘기지 않고, 간단히 찾아올 수 있으며 그 찾아온 것을 따로 가공하지 않고 원형 그대로 넘겨서 바로 처리하고 싶어서 찾은 패턴이다.

Facade 패턴이란 ? 

밖에서는 최대한 Simple한 구조를 갖고 있으며, 내부로 들어갈 수록 Deep한 Logic을 사용하는것이라고 이해했다.

 

예를들어, 사용자가 게임을 실행시키고자 하면 사용자는 아래 동작을 거치게 된다.

  1. 컴퓨터를 킨다.
  2. 모니터를 킨다.
  3. 컴퓨터에 게임을 설치한다.
  4. 설치된 게임을 실행한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
fun executionGame(): Boolean {
    val computer = Computer()
    val moniter = Moniter()
    val game = Game("리그오브레전드") // 실행시킬 게임에 대한 정보를 담고있는 Class
 
    computer.powerOn()
    moniter.powerOn()
 
    if(!game.isInstalled) {
        game.install()
    }
 
    game.execute()
 
    return true
}
    
    
    
cs

사용자가 게임을 실행할 때 마다 위 Process를 거쳐야 한다.

세부적인 Class들을 생성하고, 해당 Class들에 대해 특정 Method를 실행시켜 복잡한 관리를 진행해야한다.

저 세부적인 Class들은 이제 더이상 안보고, 하나의 통합적인 Interface 시켜주는 것이 Facade 패턴이다.

 

예제를 만들어보면 아래와 같이 생성할 수 있다.

먼저 세부적인 Class들의 정의된 내용은 아래와 같다고 하자.

 

1. Computer Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Computer {
    val isPowerOn: Boolean = false
 
    fun powerOn() {
        if(isPowerOn) {
            throw Exception("이미 컴퓨터가 켜져 있습니다.")        
        }
 
        isPowerOn = true
    }
 
 
    fun powerOff() {
        if(!isPowerOn) {
            throw Exception("이미 컴퓨터가 꺼져 있습니다.")        
        }
        isPowerOn = false
    }
}
cs

2. Monitor Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Monitor {
    val isPowerOn: Boolean = false
 
    fun powerOn() {
        if(isPowerOn) {
            throw Exception("이미 모니터가 켜져 있습니다.")        
        }
 
        isPowerOn = true
    }
 
 
    fun powerOff() {
        if(!isPowerOn) {
            throw Exception("이미 모니터가 꺼져 있습니다.")        
        }
        isPowerOn = false
    }
}
cs

3. Game Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Game constructor(private val gameName: String) {
    val isExecution: Boolean = false
    val isInstalled: Boolean = false
 
    fun install() {
        if(isInstalled) {
            throw Exception("이미 $gameName 이 설치가 되어 있습니다.")
        }
        isInstalled = true
    }
 
    fun execute() {
        if(isExecution) {
            throw Exception("이미 $gameName 이 실행되고 있습니다.")
        }
        isExecution = true
    }
}
cs

이제 위에 있는 세부적인 Class들을 하나의 Class에서 모두 선언하고 통합시킨 Facade Class를 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class SimpleGameStarter constructor(private val gameName: String) {
    fun execute() {
        val game = Game(gameName)
        val moniter = Moniter()
        val computer = Computer()
 
        computer.powerOn()
        moniter.powerOn()
 
        if(!game.isInstalled) {
            game.install()
        }
 
        game.execute()
    }
}
cs

위처럼 하나로 통합시킨 Class를 사용하면, 이제 사용자는 간단하게 게임을 실행시킬 수 있다.

1
2
3
4
fun executionGame() {
    val simpleGameStarter = SimpleGameStarter("리그오브레전드")
    simpleGameStarter.execute()
}
cs