Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Введение в паттерны проектирования Java.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
170.5 Кб
Скачать

Порождающие паттерны

В предыдущей главе мы столкнулись с необходимостью разделения места определения объекта и места его создания. Это видно на примере определения рисуемой фигуры и создания рисуемой фигуры. Определяем фигуру в конструкторе MyFrame

shape = new MyShape(new Rectangle2D.Double(),new ColorShape(Color.GREEN));

и устанавливаем фигуру в контроллере.

controller.setMyShape(shape);

Создаем новую фигуру в модели с помощью метода executePress класса DrawAction.

public void executePress(Model model,Point2D point) {

p[0]=point;

model.setNewActiveShape();

model.add();

}

Для решения такой проблемы могут быть использованы различные порождающие паттерны, которые абстрагируют процесс создания объекта. Они позволяют сделать систему независимой от способа создания, композиции и представления объектов. Шаблон, порождающий классы, использует наследование, чтобы изменять создаваемый класс, а шаблон, порождающий объекты, делегирует создание другому объекту.

Паттерн фабричный метод

Фабричный метод предоставляет подклассам интерфейс для создания экземпляров некоторого класса. В момент создания наследники могут определить, какой класс создавать. Иными словами, Фабрика делегирует создание объектов наследникам родительского класса. Это позволяет использовать в коде программы не специфические классы, а манипулировать абстрактными объектами на более высоком уровне. Также известен под названием виртуальный конструктор (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());

}

}