Identify the desired unified interface for a set of subsystems
Design a "wrapper" class that can encapsulate the use of the subsystems
The client uses (is coupled to) the Facade
The facade/wrapper "maps" to the APIs of the subsystems
// 1. Subsystem class PointCartesian { private double x, y; public PointCartesian(double x, double y ) { this.x = x; this.y = y; } public void move( int x, int y ) { this.x += x; this.y += y; } public String toString() { return "(" + x + "," + y + ")"; } public double getX() { return x; } public double getY() { return y; } } // 1. Subsystem class PointPolar { private double radius, angle; public PointPolar(double radius, double angle) { this.radius = radius; this.angle = angle; } public void rotate(int angle) { this.angle += angle % 360; } public String toString() { return "[" + radius + "@" + angle + "]"; } } // 1. Desired interface: move(), rotate() class Point { // 2. Design a "wrapper" class private PointCartesian pointCartesian; public Point(double x, double y) { pointCartesian = new PointCartesian(x, y); } public String toString() { return pointCartesian.toString(); } // 4. Wrapper maps public void move(int x, int y) { pointCartesian.move(x, y); } public void rotate(int angle, Point o) { double x = pointCartesian.getX() - o.pointCartesian.getX(); double y = pointCartesian.getY() - o.pointCartesian.getY(); PointPolar pointPolar = new PointPolar(Math.sqrt(x * x + y * y),Math.atan2(y, x) * 180 / Math.PI); // 4. Wrapper maps pointPolar.rotate(angle); System.out.println(" PointPolar is " + pointPolar); String str = pointPolar.toString(); int i = str.indexOf('@'); double r = Double.parseDouble(str.substring(1, i)); double a = Double.parseDouble(str.substring(i + 1, str.length() - 1)); pointCartesian = new PointCartesian(r*Math.cos(a*Math.PI/180) + o.pointCartesian.getX(), r*Math.sin(a * Math.PI / 180) + o.pointCartesian.getY()); } } class Line { private Point o, e; public Line(Point ori, Point end) { o = ori; e = end; } public void move(int x, int y) { o.move(x, y); e.move(x, y); } public void rotate(int angle) { e.rotate(angle, o); } public String toString() { return "origin is " + o + ", end is " + e; } } public class FacadeDemo { public static void main(String[] args) { // 3. Client uses the Facade Line lineA = new Line(new Point(2, 4), new Point(5, 7)); lineA.move(-2, -4); System.out.println( "after move: " + lineA ); lineA.rotate(45); System.out.println( "after rotate: " + lineA ); Line lineB = new Line( new Point(2, 1), new Point(2.866, 1.5)); lineB.rotate(30); System.out.println("30 degrees to 60 degrees: " + lineB); } }
Output
after move: origin is (0.0,0.0), end is (3.0,3.0) PointPolar is [4.242640687119285@90.0] after rotate: origin is (0.0,0.0), end is (2.5978681687064796E-16,4.242640687119285) PointPolar is [0.9999779997579947@60.000727780827376] 30 degrees to 60 degrees: origin is (2.0,1.0), end is (2.499977999677324,1.8660127018922195)
Support our free website and own the eBook!
22 design patterns and 8 principles explained in depth
406 well-structured, easy to read, jargon-free pages