Пример шаблона моста
-
05-07-2019 - |
Вопрос
Я потратил некоторое время на этот пример шаблона моста из википедия, однако, я все еще не понимаю, что этот шаблон моста пытается объяснить.
interface DrawingAPI { public void drawCircle(double x, double y, double radius); } /** "ConcreteImplementor" 1/2 */ class DrawingAPI1 implements DrawingAPI { public void drawCircle(double x, double y, double radius) { System.out.printf("API1.circle at %f:%f radius %f\n", x, y, radius); } } /** "ConcreteImplementor" 2/2 */ class DrawingAPI2 implements DrawingAPI { public void drawCircle(double x, double y, double radius) { System.out.printf("API2.circle at %f:%f radius %f\n", x, y, radius); } } /** "Abstraction" */ interface Shape { public void draw(); // low-level public void resizeByPercentage(double pct); // high-level } /** "Refined Abstraction" */ class CircleShape implements Shape { private double x, y, radius; private DrawingAPI drawingAPI; public CircleShape(double x, double y, double radius, DrawingAPI drawingAPI) { this.x = x; this.y = y; this.radius = radius; this.drawingAPI = drawingAPI; } // low-level i.e. Implementation specific public void draw() { drawingAPI.drawCircle(x, y, radius); } // high-level i.e. Abstraction specific public void resizeByPercentage(double pct) { radius *= pct; } } /** "Client" */ class Main { public static void main(String[] args) { Shape[] shapes = new Shape[2]; shapes[0] = new CircleShape(1, 2, 3, new DrawingAPI1()); shapes[1] = new CircleShape(5, 7, 11, new DrawingAPI2()); for (Shape shape : shapes) { shape.resizeByPercentage(2.5); shape.draw(); } } }
Конструктор подкласса CircleShape принимает 4 аргумента, в его методе draw() первые 3 аргумента передаются 4-му аргументу, который может быть любым подклассом из DrawingAPI.Итак, означает ли это, что использование шаблона bridge может повысить гибкость?и есть ли еще что-то, о чем этот пример может нам рассказать?
Спасибо!!!!
Решение
Более конкретный пример того, почему это полезно, прояснит ситуацию.Предположим, DrawingAPI1 инкапсулирует ваш графический драйвер, в то время как DrawingAPI2 делает то же самое для вашего драйвера принтера.Тогда DrawingAPI - это универсальный API для вашей графической системы.Это позволяет вам нарисовать форму круга на вашем мониторе и распечатать ее на листе бумаги, используя тот же код, вам нужно только передать различные реализации DrawingAPI.Однако, если вы передадите DrawingAPI в Shape.draw() вместо того, чтобы передавать его в конструктор, это будет более гибко, потому что тогда вы сможете использовать один и тот же объектный график для монитора и принтера.
Другие советы
Конструктор подкласса CircleShape принимает 4 аргумента, в его методе draw() первые 3 аргумента передаются 4-му аргументу, который может быть любым подклассом из DrawingAPI.Итак, означает ли это, что использование шаблона bridge может повысить гибкость?и есть ли еще что-то, о чем этот пример может нам рассказать?
Дело не только в гибкости. Шаблон моста отделяет абстракцию от реализации, и то и другое может варьироваться по-разному.
С тех пор как CircleShape
использует композицию для содержания DrawingAPI
без наследования вы можете заменить DrawingAPI
API с любой из нескольких реализаций DrawingAPI
Shape
и CircleShape
может изменяться независимо, без зависимости от DrawingAPI
.
Вы можете найти более подробную информацию о шаблоне моста в следующем посте SE, в котором объясняется другой пример: