工厂方法模式又叫虚拟构造函数(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式。工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建性工作推迟到子类中。
工厂模式可以分为简单工厂、工厂方法和抽象工厂模式。
- 简单工厂模式:需要注意的是,简单工厂并不包含在《GoF》一书中定义的23种设计模式,因为它过于简单,更像是一种编程习惯,并且它违反了开闭原则,增加工厂需要修改类的实现。
- 工厂方法模式:是简单工厂模式的进一步抽象和推广,将具体创建工作交给子类去做,避免违反开闭原则。
- 抽象工厂模式:如果说工厂方法模式针对的是一个产品等级结构,那么抽象工厂模式面对的就是多个产品等级结构。
由于简单工厂模式严格来说并不算是一种设计模式,就不再画UML图了,大家通过一个例子感受一下它的用法:
public interface Shape {
void draw();
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("draw a circle");
}
}
public class Square implements Shape {
@Override
public void draw() {
System.out.println("draw a square");
}
}
public class SimpleFactory {
public static Shape createShape(String shapeType) {
if (shapeType == null) {
throw new IllegalArgumentException("Shape type cannot be null.");
}
switch (shapeType.toLowerCase()) {
case "circle":
return new Circle();
case "square":
return new Square();
default:
throw new IllegalArgumentException("Unsupported shape type: " + shapeType);
}
}
}
public class Demo {
public static void main(String[] args) {
Shape circle = SimpleFactory.createShape("circle");
circle.draw();
Shape square = SimpleFactory.createShape("square");
square.draw();
Shape triangle = SimpleFactory.createShape("triangle");
triangle.draw();
}
}
工厂方法模式的UML图如下:
下面还是以一个例子来说明工厂方法模式的用法。假设有一个果农接口,相当于图中的Creator,有一个葡萄果农和一个苹果农分别实现果农接口,这两个类相当于ConcreteCreator类。然后有一个水果接口 ,相当于Product接口,一个苹果类和一个葡萄类分别实现水果接口。这时候注意体会工厂方法模式和简单工厂模式的区别,工厂方法模式把创建对象的工作分别放到葡萄果农和苹果农的类中去实现,也就是在具体类中实现。
public interface GuoNong {
Fruit createFruit();
}
public class GrapeNong implements GuoNong {
@Override
public Fruit createFruit() {
return new Grape();
}
}
public class AppleNong implements GuoNong {
@Override
public Fruit createFruit() {
return new Apple();
}
}
public interface Fruit {
void plant();
void grow();
void harvest();
}
public class Grape implements Fruit {
@Override
public void plant() {
System.out.println("种葡萄");
}
@Override
public void grow() {
System.out.println("葡萄生长");
}
@Override
public void harvest() {
System.out.println("收葡萄");
}
}
public class Apple implements Fruit{
@Override
public void plant() {
System.out.println("种苹果");
}
@Override
public void grow() {
System.out.println("苹果生长");
}
@Override
public void harvest() {
System.out.println("收苹果");
}
}
public class Demo {
public static void main(String[] args) {
GrapeNong grapeNong = new GrapeNong();
Fruit grape = grapeNong.createFruit();
grape.plant();
grape.grow();
grape.harvest();
System.out.println("**************分割线**********************");
AppleNong appleNong = new AppleNong();
Fruit apple = appleNong.createFruit();
apple.plant();
apple.grow();
apple.harvest();
}
}