В качестве примера позвольте вернуться к системе Форм (Shape).
Один из подходов состоит в создании статического метода производства в базовом классе:
//: factory:shapefact1:ShapeFactory1.java
// Метод простейшей фабрики.
package factory.shapefact1;
import java.util.*;
import junit.framework.*;
abstract class Shape {
public abstract void draw();
public abstract void erase();
public static Shape factory(String type) {
if (type.equals("Circle"))
return new Circle();
if (type.equals("Square"))
return new Square();
throw new RuntimeException("Bad shape creation: " + type);
}
}
class Circle extends Shape {
Circle() {
} // Конструктор с пакетным уровнем доступа
public void draw() {
System.out.println("Circle.draw");
}
public void erase() {
System.out.println("Circle.erase");
}
}
class Square extends Shape {
Square() {
} // Конструктор с пакетным уровнем доступа
public void draw() {
System.out.println("Square.draw");
}
public void erase() {
System.out.println("Square.erase");
}
}
public class ShapeFactory1 extends TestCase {
String shlist[] = { "Circle", "Square", "Square", "Circle", "Circle",
"Square" };
List shapes = new ArrayList();
public void test() {
Iterator it = Arrays.asList(shlist).iterator();
while (it.hasNext())
shapes.add(Shape.factory((String) it.next()));
it = shapes.iterator();
while (it.hasNext()) {
Shape s = (Shape) it.next();
s.draw();
s.erase();
}
}
public static void main(String args[]) {
junit.textui.TestRunner.run(ShapeFactory1.class);
}
} // /:~
Метод factory( ) принимает аргумент, который позволяет определить тип создаваемой Формы (Shape); в данном случае это Строка (String), но это может быть любой набор данных. Теперь только factory( ) является частью кода, которую нужно менять при добавлении нового типа Формы (Shape) (инициализирующие данные для объекта будут, предположительно, приходить откуда-то извне системы, и не будут жестко заданным массивом, как в приведенном выше примере).
Для поощрения создания только с помощью метода factory( ), конструктор для указанных типов Формы (Shape) сделан с пакетным уровнем доступа, так что метод factory( ) имеет доступ к конструкторам, но они не доступны для классов вне этого пакета.
← | Инкапсуляция создания (Encapsulating creation) | Полиморфные фабрики (Polymorphic factories) | → |