|
| 1 | +--- |
| 2 | +title: Facade |
| 3 | +category: Structural |
| 4 | +language: ko |
| 5 | +tag: |
| 6 | + - Gang Of Four |
| 7 | + - Decoupling |
| 8 | +--- |
| 9 | + |
| 10 | +## 의도 |
| 11 | + |
| 12 | +하위 시스템의 인터페이스 집합에 통합 인터페이스를 제공합니다. 퍼싸드(Facade)는 상위 레벨을 정의합니다. |
| 13 | +하위시스템을 보다 쉽게 사용할 수 있는 인터페이스. |
| 14 | + |
| 15 | +## 설명 |
| 16 | + |
| 17 | +실제 예제 |
| 18 | + |
| 19 | +> 금광은 어떻게 운영되나요? "광부들이 저 아래로 내려가서 금을 캐죠" 라고 당신은 말합니다. |
| 20 | +> 당신은 금광이 외부에 제공하는 간단한 인터페이스를 사용하고 있기 때문에 그렇게 믿습니다. |
| 21 | +> 그러나 내부적으로는 많은 작업을 수행해야 합니다. 복잡한 하위 시스템에 대한 이 간단한 인터페이스는 |
| 22 | +> 퍼싸드(Facade)입니다. |
| 23 | +
|
| 24 | +쉽게 말하자면 |
| 25 | + |
| 26 | +> 퍼싸드(Facade) 패턴은 복잡한 하위 시스템에 대한 간소화된 인터페이스를 제공합니다. |
| 27 | +
|
| 28 | +Wikipedia에 의하면 |
| 29 | + |
| 30 | +> 퍼싸드(Facade)는 클래스 라이브러리와 같은 더 큰 코드 본운에 간단한 인터페이스를 제공하는 객체입니다. |
| 31 | +
|
| 32 | +**코드 예제** |
| 33 | + |
| 34 | +위의 금광을 예로 들어 보겠습니다. 여기에는 드워프 광산 작업자 계층 구조가 있습니다. |
| 35 | +먼저, 베이스 클래스 `DwarvenMineWorker`가 있습니다.: |
| 36 | + |
| 37 | +```java |
| 38 | + |
| 39 | +@Slf4j |
| 40 | +public abstract class DwarvenMineWorker { |
| 41 | + |
| 42 | + public void goToSleep() { |
| 43 | + LOGGER.info("{} goes to sleep.", name()); |
| 44 | + } |
| 45 | + |
| 46 | + public void wakeUp() { |
| 47 | + LOGGER.info("{} wakes up.", name()); |
| 48 | + } |
| 49 | + |
| 50 | + public void goHome() { |
| 51 | + LOGGER.info("{} goes home.", name()); |
| 52 | + } |
| 53 | + |
| 54 | + public void goToMine() { |
| 55 | + LOGGER.info("{} goes to the mine.", name()); |
| 56 | + } |
| 57 | + |
| 58 | + private void action(Action action) { |
| 59 | + switch (action) { |
| 60 | + case GO_TO_SLEEP -> goToSleep(); |
| 61 | + case WAKE_UP -> wakeUp(); |
| 62 | + case GO_HOME -> goHome(); |
| 63 | + case GO_TO_MINE -> goToMine(); |
| 64 | + case WORK -> work(); |
| 65 | + default -> LOGGER.info("Undefined action"); |
| 66 | + } |
| 67 | + } |
| 68 | + |
| 69 | + public void action(Action... actions) { |
| 70 | + Arrays.stream(actions).forEach(this::action); |
| 71 | + } |
| 72 | + |
| 73 | + public abstract void work(); |
| 74 | + |
| 75 | + public abstract String name(); |
| 76 | + |
| 77 | + enum Action { |
| 78 | + GO_TO_SLEEP, WAKE_UP, GO_HOME, GO_TO_MINE, WORK |
| 79 | + } |
| 80 | +} |
| 81 | +``` |
| 82 | + |
| 83 | +그 다음 구체적인 드워프 클래스인 `DwarvenTunnelDigger`, `DwarvenGoldDigger` 와 |
| 84 | +`DwarvenCartOperator` 입니다: |
| 85 | + |
| 86 | +```java |
| 87 | +@Slf4j |
| 88 | +public class DwarvenTunnelDigger extends DwarvenMineWorker { |
| 89 | + |
| 90 | + @Override |
| 91 | + public void work() { |
| 92 | + LOGGER.info("{} creates another promising tunnel.", name()); |
| 93 | + } |
| 94 | + |
| 95 | + @Override |
| 96 | + public String name() { |
| 97 | + return "Dwarven tunnel digger"; |
| 98 | + } |
| 99 | +} |
| 100 | + |
| 101 | +@Slf4j |
| 102 | +public class DwarvenGoldDigger extends DwarvenMineWorker { |
| 103 | + |
| 104 | + @Override |
| 105 | + public void work() { |
| 106 | + LOGGER.info("{} digs for gold.", name()); |
| 107 | + } |
| 108 | + |
| 109 | + @Override |
| 110 | + public String name() { |
| 111 | + return "Dwarf gold digger"; |
| 112 | + } |
| 113 | +} |
| 114 | + |
| 115 | +@Slf4j |
| 116 | +public class DwarvenCartOperator extends DwarvenMineWorker { |
| 117 | + |
| 118 | + @Override |
| 119 | + public void work() { |
| 120 | + LOGGER.info("{} moves gold chunks out of the mine.", name()); |
| 121 | + } |
| 122 | + |
| 123 | + @Override |
| 124 | + public String name() { |
| 125 | + return "Dwarf cart operator"; |
| 126 | + } |
| 127 | +} |
| 128 | + |
| 129 | +``` |
| 130 | + |
| 131 | +이 모든 금광의 일꾼들을 운영하기 위해 `DwarvenGoldmineFacade` 가 있습니다.: |
| 132 | + |
| 133 | +```java |
| 134 | +public class DwarvenGoldmineFacade { |
| 135 | + |
| 136 | + private final List<DwarvenMineWorker> workers; |
| 137 | + |
| 138 | + public DwarvenGoldmineFacade() { |
| 139 | + workers = List.of( |
| 140 | + new DwarvenGoldDigger(), |
| 141 | + new DwarvenCartOperator(), |
| 142 | + new DwarvenTunnelDigger()); |
| 143 | + } |
| 144 | + |
| 145 | + public void startNewDay() { |
| 146 | + makeActions(workers, DwarvenMineWorker.Action.WAKE_UP, DwarvenMineWorker.Action.GO_TO_MINE); |
| 147 | + } |
| 148 | + |
| 149 | + public void digOutGold() { |
| 150 | + makeActions(workers, DwarvenMineWorker.Action.WORK); |
| 151 | + } |
| 152 | + |
| 153 | + public void endDay() { |
| 154 | + makeActions(workers, DwarvenMineWorker.Action.GO_HOME, DwarvenMineWorker.Action.GO_TO_SLEEP); |
| 155 | + } |
| 156 | + |
| 157 | + private static void makeActions(Collection<DwarvenMineWorker> workers, |
| 158 | + DwarvenMineWorker.Action... actions) { |
| 159 | + workers.forEach(worker -> worker.action(actions)); |
| 160 | + } |
| 161 | +} |
| 162 | +``` |
| 163 | + |
| 164 | +이제 퍼싸드(facade) 패턴을 사용해 봅시다: |
| 165 | + |
| 166 | +```java |
| 167 | +var facade = new DwarvenGoldmineFacade(); |
| 168 | +facade.startNewDay(); |
| 169 | +facade.digOutGold(); |
| 170 | +facade.endDay(); |
| 171 | +``` |
| 172 | + |
| 173 | +프로그램 실행 결과: |
| 174 | + |
| 175 | +```java |
| 176 | +// Dwarf gold digger wakes up. |
| 177 | +// Dwarf gold digger goes to the mine. |
| 178 | +// Dwarf cart operator wakes up. |
| 179 | +// Dwarf cart operator goes to the mine. |
| 180 | +// Dwarven tunnel digger wakes up. |
| 181 | +// Dwarven tunnel digger goes to the mine. |
| 182 | +// Dwarf gold digger digs for gold. |
| 183 | +// Dwarf cart operator moves gold chunks out of the mine. |
| 184 | +// Dwarven tunnel digger creates another promising tunnel. |
| 185 | +// Dwarf gold digger goes home. |
| 186 | +// Dwarf gold digger goes to sleep. |
| 187 | +// Dwarf cart operator goes home. |
| 188 | +// Dwarf cart operator goes to sleep. |
| 189 | +// Dwarven tunnel digger goes home. |
| 190 | +// Dwarven tunnel digger goes to sleep. |
| 191 | +``` |
| 192 | + |
| 193 | +## 클래스 다이어그램 |
| 194 | + |
| 195 | + |
| 196 | + |
| 197 | +## 적용 가능성 |
| 198 | + |
| 199 | +다음과 같은 경우 파사드 패턴을 사용합니다. |
| 200 | + |
| 201 | +* 복잡한 하위시스템에 간단한 인터페이스를 제공하려는 경우, 하위시스템은 점점 더 복잡해지는 경우가 많습니다. 대부분의 패턴들은 적용되었을 때, |
| 202 | + 클래스가 점점 더 작아집니다. 이것은 하위 시스템의 재사용성을 늘리고 커스터마이징을 쉽게 해주지만, 커스터마이징이 필요없는 클라이언트는 사용하기 |
| 203 | + 어려워집니다. 퍼싸드(Facade)는 하위시스템의 간단한 보기를 제공할 수 있습니다. 오직 커스터마이징이 필요한 클라이언트들만 퍼싸드(Facade) 너머를 |
| 204 | + 살펴볼 필요가 있습니다. |
| 205 | +* 클라이언트와 추상화의 구현 클래스 사이에는 많은 종속성이 있습니다. 퍼싸드(Facade)를 도입해 하위 시스템을 클라이언트 및 다른 하위 시스템으로부터 |
| 206 | + 분리하면 다음과 같은 이점이 있습니다. |
| 207 | + 하위 시스템의 독립성과 이식성을 촉진합니다. |
| 208 | +* 하위 시스템을 계층화하려고 합니다. 퍼싸드(Facade)를 이용해 각 하위 시스템 계층에 대한 진입점을 정희합니다. |
| 209 | + 하위 시스템이 종속적인 경우 하위 시스템 간의 종속성을 단순화할 수 있습니다. |
| 210 | + 퍼싸드(Facade)를 통해서만 서로 통신할 수 있습니다. |
| 211 | + |
| 212 | +## 튜토리얼 |
| 213 | + |
| 214 | +*[DigitalOcean](https://www.digitalocean.com/community/tutorials/facade-design-pattern-in-java) |
| 215 | +* [Refactoring Guru](https://refactoring.guru/design-patterns/facade) |
| 216 | +* [GeekforGeeks](https://www.geeksforgeeks.org/facade-design-pattern-introduction/) |
| 217 | +* [Tutorialspoint](https://www.tutorialspoint.com/design_pattern/facade_pattern.htm) |
| 218 | + |
| 219 | + |
| 220 | + |
| 221 | +## 크레딧 |
| 222 | + |
| 223 | +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) |
| 224 | +* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) |
0 commit comments