Метод простейшей фабрики (Simple Factory method)


В качестве примера позвольте вернуться к системе Форм (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( ) имеет доступ к конструкторам, но они не доступны для классов вне этого пакета.