diff --git a/facade/README.md b/facade/README.md index 22ccd6911..66ca84256 100644 --- a/facade/README.md +++ b/facade/README.md @@ -15,7 +15,188 @@ tags: Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use. -![alt text](./etc/facade_1.png "Facade") +## Explanation + +Real world example + +> How does a goldmine work? "Well, the miners go down there and dig gold!" you say. That is what you believe because you are using a simple interface that goldmine provides on the outside, internally it has to do a lot of stuff to make it happen. This simple interface to the complex subsystem is a facade. + +In plain words + +> Facade pattern provides a simplified interface to a complex subsystem. + +Wikipedia says + +> A facade is an object that provides a simplified interface to a larger body of code, such as a class library. + +**Programmatic Example** + +Taking our goldmine example from above. Here we have the dwarven mine worker hierarchy + +``` +public abstract class DwarvenMineWorker { + + private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenMineWorker.class); + + public void goToSleep() { + LOGGER.info("{} goes to sleep.", name()); + } + + public void wakeUp() { + LOGGER.info("{} wakes up.", name()); + } + + public void goHome() { + LOGGER.info("{} goes home.", name()); + } + + public void goToMine() { + LOGGER.info("{} goes to the mine.", name()); + } + + private void action(Action action) { + switch (action) { + case GO_TO_SLEEP: + goToSleep(); + break; + case WAKE_UP: + wakeUp(); + break; + case GO_HOME: + goHome(); + break; + case GO_TO_MINE: + goToMine(); + break; + case WORK: + work(); + break; + default: + LOGGER.info("Undefined action"); + break; + } + } + + public void action(Action... actions) { + for (Action action : actions) { + action(action); + } + } + + public abstract void work(); + + public abstract String name(); + + static enum Action { + GO_TO_SLEEP, WAKE_UP, GO_HOME, GO_TO_MINE, WORK + } +} + +public class DwarvenTunnelDigger extends DwarvenMineWorker { + + private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenTunnelDigger.class); + + @Override + public void work() { + LOGGER.info("{} creates another promising tunnel.", name()); + } + + @Override + public String name() { + return "Dwarven tunnel digger"; + } +} + +public class DwarvenGoldDigger extends DwarvenMineWorker { + + private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenGoldDigger.class); + + @Override + public void work() { + LOGGER.info("{} digs for gold.", name()); + } + + @Override + public String name() { + return "Dwarf gold digger"; + } +} + +public class DwarvenCartOperator extends DwarvenMineWorker { + + private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenCartOperator.class); + + @Override + public void work() { + LOGGER.info("{} moves gold chunks out of the mine.", name()); + } + + @Override + public String name() { + return "Dwarf cart operator"; + } +} + +``` + +To operate all these goldmine workers we have the facade + +``` +public class DwarvenGoldmineFacade { + + private final List workers; + + public DwarvenGoldmineFacade() { + workers = new ArrayList<>(); + workers.add(new DwarvenGoldDigger()); + workers.add(new DwarvenCartOperator()); + workers.add(new DwarvenTunnelDigger()); + } + + public void startNewDay() { + makeActions(workers, DwarvenMineWorker.Action.WAKE_UP, DwarvenMineWorker.Action.GO_TO_MINE); + } + + public void digOutGold() { + makeActions(workers, DwarvenMineWorker.Action.WORK); + } + + public void endDay() { + makeActions(workers, DwarvenMineWorker.Action.GO_HOME, DwarvenMineWorker.Action.GO_TO_SLEEP); + } + + private static void makeActions(Collection workers, + DwarvenMineWorker.Action... actions) { + for (DwarvenMineWorker worker : workers) { + worker.action(actions); + } + } +} +``` + +Now to use the facade + +``` +DwarvenGoldmineFacade facade = new DwarvenGoldmineFacade(); +facade.startNewDay(); +// Dwarf gold digger wakes up. +// Dwarf gold digger goes to the mine. +// Dwarf cart operator wakes up. +// Dwarf cart operator goes to the mine. +// Dwarven tunnel digger wakes up. +// Dwarven tunnel digger goes to the mine. +facade.digOutGold(); +// Dwarf gold digger digs for gold. +// Dwarf cart operator moves gold chunks out of the mine. +// Dwarven tunnel digger creates another promising tunnel. +facade.endDay(); +// Dwarf gold digger goes home. +// Dwarf gold digger goes to sleep. +// Dwarf cart operator goes home. +// Dwarf cart operator goes to sleep. +// Dwarven tunnel digger goes home. +// Dwarven tunnel digger goes to sleep. +``` ## Applicability Use the Facade pattern when diff --git a/facade/etc/facade.png b/facade/etc/facade.png deleted file mode 100644 index 5cc6271da..000000000 Binary files a/facade/etc/facade.png and /dev/null differ diff --git a/facade/etc/facade.ucls b/facade/etc/facade.ucls deleted file mode 100644 index 28756c189..000000000 --- a/facade/etc/facade.ucls +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/facade/etc/facade.urm.puml b/facade/etc/facade.urm.puml deleted file mode 100644 index 477f9eee7..000000000 --- a/facade/etc/facade.urm.puml +++ /dev/null @@ -1,60 +0,0 @@ -@startuml -package com.iluwatar.facade { - class App { - + App() - + main(args : String[]) {static} - } - class DwarvenCartOperator { - - LOGGER : Logger {static} - + DwarvenCartOperator() - + name() : String - + work() - } - class DwarvenGoldDigger { - - LOGGER : Logger {static} - + DwarvenGoldDigger() - + name() : String - + work() - } - class DwarvenGoldmineFacade { - - workers : List - + DwarvenGoldmineFacade() - + digOutGold() - + endDay() - - makeActions(workers : Collection, actions : Action[]) {static} - + startNewDay() - } - abstract class DwarvenMineWorker { - - LOGGER : Logger {static} - + DwarvenMineWorker() - - action(action : Action) - + action(actions : Action[]) - + goHome() - + goToMine() - + goToSleep() - + name() : String {abstract} - + wakeUp() - + work() {abstract} - } - ~enum Action { - + GO_HOME {static} - + GO_TO_MINE {static} - + GO_TO_SLEEP {static} - + WAKE_UP {static} - + WORK {static} - + valueOf(name : String) : Action {static} - + values() : Action[] {static} - } - class DwarvenTunnelDigger { - - LOGGER : Logger {static} - + DwarvenTunnelDigger() - + name() : String - + work() - } -} -DwarvenGoldmineFacade --> "-workers" DwarvenMineWorker -Action ..+ DwarvenMineWorker -DwarvenCartOperator --|> DwarvenMineWorker -DwarvenGoldDigger --|> DwarvenMineWorker -DwarvenTunnelDigger --|> DwarvenMineWorker -@enduml \ No newline at end of file diff --git a/facade/etc/facade_1.png b/facade/etc/facade_1.png deleted file mode 100644 index 6ed0573fc..000000000 Binary files a/facade/etc/facade_1.png and /dev/null differ diff --git a/pom.xml b/pom.xml index 44461b091..cf1bf9831 100644 --- a/pom.xml +++ b/pom.xml @@ -470,6 +470,7 @@ bridge composite decorator + facade