-
FacadeModeling/DesignPattern 2020. 2. 24. 22:03
1. Overview
Facade is an object that serves as a front-facing interface masking more complex underlying or structural code. A facade can:
- Improve the readability and usability of a software library by masking interaction with more complex components behind a single (and often simplified) API
- Provide a context-specific interface to more generic functionality (complete with context-specific input validation)
- Serve as a launching point for a broader refactor of monolithic or tightly-coupled systems in favor of more loosely-coupled code
A client has to interact with a large number of interfaces and classes in a subsystem to get a result. So the client gets tightly coupled with those interfaces & classes. Facade solves these problems.
Facade provides a simple and unified interface to a subsystem. The client interacts with just the face now to get the same result.
Facade is not just a one to one method forwarding to other classes.
2. Description
2.1 Motivation
- Balancing complexity and presentation usability
- API consumers want it to just work even though many systems working to provide flexibility.
- Facade provides a simple, easy to understand user interface over a large and sophisticated body of code.
2.2 Code Example
class Buffer { private char [] characters; private int lineWidth; public Buffer(int lineHeight, int lineWidth) { this.characters = new char[lineWidth*lineHeight]; this.lineWidth = lineWidth; } public char charAt(int x, int y) { return characters[y*lineWidth + x]; } } class Viewport { private final Buffer buffer; private final int width; private final int height; private final int offsetX; private final int offsetY; public Viewport(Buffer buffer, int width, int height, int offsetX, int offsetY) { this.buffer = buffer; this.width = width; this.height = height; this.offsetX = offsetX; this.offsetY = offsetY; } public char charAt(int x, int y) { return buffer.charAt(x+offsetX, y+offsetY); } } class Console { private List<Viewport> viewports = new ArrayList<>(); int width, height; public Console(int width, int height) { this.width = width; this.height = height; } public void addViewPort(Viewport viewport) { viewports.add(viewport); } // Facade public static Console newConsole(int width, int height) { Buffer buffer = new Buffer(width, height); Viewport viewport = new Viewport(buffer, width, height, 0, 0); Console console = new Console(width, height); console.addViewPort(viewport); return console; } public void render() { for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { for (Viewport vp: viewports) { System.out.println(vp.charAt(x, y)); } System.out.println(); } } } } public class Demo { public static void main(String[] args) { // without facade Buffer buffer = new Buffer(30, 20); Viewport viewport = new Viewport(buffer, 30, 20, 0, 0); Console console = new Console(30, 20); console.addViewPort(viewport); console.render(); // with facade Console console2 = Console.newConsole(30, 20); console2.render(); } }
3. Reference