Паттерн фабричный метод
Фабричный метод предоставляет подклассам интерфейс для создания экземпляров некоторого класса. В момент создания наследники могут определить, какой класс создавать. Иными словами, Фабрика делегирует создание объектов наследникам родительского класса. Это позволяет использовать в коде программы не специфические классы, а манипулировать абстрактными объектами на более высоком уровне. Также известен под названием виртуальный конструктор (Virtual Constructor). Рассмотрим использование паттерна «фабричный метод» в нашем графическом редакторе. Создадим интерфейс для создания экземпляров классов фигур различной формы. public interface ShapeMaker { RectangularShape createShape(); } Пусть этот интерфейс наследуют классы, которые создают классы прямоугольников и эллипсов. public class RectangleCreator implements ShapeMaker{
public RectangularShape createShape() { return new Rectangle2D.Double(); }
} public class EllipseCreator implements ShapeMaker{
public RectangularShape createShape() { return new Ellipse2D.Double(); } }
Тогда, применяя метод createShape к объектам типа ShapeMaker можно получить новые объекты соответствующего типа. Например, имеется объект ShapeMaker rectangleCreator = new RectangleCreator(); В любой момент можно вызвать метод createShape и создать прямоугольник или эллипс RectangularShape s =rectangleCreator.createShape(); s = new EllipseCreator().createShape();
Аналогичным образом поступим с закрашенными и незакрашенными фигурами. Создадим абстрактный класс для создания закрашенных фигур и фигур с контуром различного цвета. Цвет будем хранить в переменной color, доступной для обеих реализаций интерфейса ColorBehavior. public abstract class ColorBehaviorMaker { protected Color color; public ColorBehaviorMaker(Color c){ color = c; } public ColorBehaviorMaker(){ color = Color.BLACK; } public abstract ColorBehavior createColorBehavior();
public void setColor(Color color) { this.color = color; } } Пусть этот интерфейс наследуют классы, которые создают реализации интерфейса ColorBehavior. public class ColorShapeCreator extends ColorBehaviorMaker{
public ColorShapeCreator(Color c){ super(c); } public ColorShapeCreator(){super(Color.BLACK);} public ColorBehavior createColorBehavior() { return new ColorShape(color); } } public class NoColorCreator extends ColorBehaviorMaker{
public NoColorCreator(Color color){ super(color); } public NoColorCreator(){super(Color.BLACK);} @Override public ColorBehavior createColorBehavior() { return new NoColorShape(color); } } Тогда, применяя метод createColorBehavior к объектам типа ColorBehaviorMaker можно получить новые объекты соответствующего типа. Например, имеется объект colorShapeCreator. ColorBehaviorMaker colorShapeCreator = new ColorShapeCreator(); Установим цвет будущей фигуры colorShapeCreator.setColor(Color.yellow); Имея объект colorShapeCreator можно в любой момент создать закрашенную фигуру. ColorBehavior colorShape = colorShapeCreator.createColorBehavior(); Применим написанные классы для создания новой фигуры с соответствующими свойствами. shape = new MyShape(rectangleCreator.createShape(),colorShapeCreator.createColorBehavior());
Передавать экземпляры двух классов, необходимых для создания фигуры неудобно. Поэтому создадим новый класс MyShapeCreator. public class MyShapeCreator {
private ShapeMaker shapeMaker; private ColorBehaviorMaker colorBehaviorMaker; public MyShapeCreator(){ shapeMaker = new RectangleCreator(); colorBehaviorMaker = new NoColorCreator(); } public void setShapeMaker(ShapeMaker shapeMaker) { this.shapeMaker = shapeMaker; }
public void setColorBehaviorMaker(ColorBehaviorMaker colorBehaviorMaker) { this.colorBehaviorMaker = colorBehaviorMaker; } public MyShape createMyShape(){ return new MyShape(shapeMaker.createShape(),colorBehaviorMaker.createColorBehavior()); } }
|