工厂模式主要是用来封装对象的创建,达到将代码从具体类中解耦,提高灵活性的目的。
工厂模式在《Java与模式》中分为三类:
- 简单工厂模式(Simple Factory):定义一个用于创建对象的接口。
- 工厂方法模式(Factory Method):把对象的创建委托给子类,子类实现工厂方法来创建对象。
- 抽象工厂模式(Abstract Factory):对象的创建被实现在工厂接口所暴露出来的方法中。
这三种模式从上到下逐步抽象,并且更具一般性。GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。
从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
简单工厂模式之所以也叫静态工厂,因为所用的是静态方法。简单工厂实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
- 工厂(Creator):简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。
- 抽象产品(Product):简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
- 具体产品(Concrete Product):是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。
工厂方法模式定义了一个创建对象的工厂接口,由工厂子类决定要实例化的类。工厂方法将实际创建工作推迟到子类当中。
核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全符合开闭原则,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。
工厂方法模式的对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不再负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。
工厂方法模式是最典型的模板方法模式(Template Method pattern)应用。
- 抽象工厂(Creator):工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
- 具体工厂(Concrete Creator):实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。在上图中有两个这样的角色:BulbCreator与TubeCreator。
- 抽象产品(Product):工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在上图中,这个角色是Light。
- 具体产品(Concrete Product):这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。
抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象
每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结构。在抽象工厂模式中,抽象产品可能是一个或多个,从而构成一个或多个产品族。在只有一个产品族的情况下,抽象工厂模式实际上退化到工厂方法模式。
一般而言,有多少个产品等级结构,就会在工厂角色中发现多少个工厂方法。每一个产品等级结构中有多少个具体的产品,就有多少个产品族,也就会在工厂等级结构中发现多少个具体工厂。
该模式中包含的角色及其职责与工厂方法模式相似,这里不再赘述。
//抽象产品角色
public interface Moveable {
void run();
}
//具体产品角色
public class Plane implements Moveable {
@Override
public void run() {
System.out.println("plane fly ...");
}
}
//工厂
public class VehicleFactory {
public static Moveable create() {
return new Plane();
}
}
//测试类
public class Test {
public static void main(String[] args) {
Moveable m = VehicleFactory.create();
m.run();
}
}
//抽象产品角色
public interface Moveable {
void run();
}
//具体产品角色
public class Plane implements Moveable {
@Override
public void run() {
System.out.println("plane fly ...");
}
}
//具体产品角色
public class Car implements Moveable {
@Override
public void run() {
System.out.println("car run ...");
}
}
//抽象工厂
public abstract class VehicleFactory {
abstract Moveable create();
}
//具体工厂
public class PlaneFactory extends VehicleFactory{
public Moveable create() {
return new Plane();
}
}
//具体工厂
public class CarFactory extends VehicleFactory{
public Moveable create() {
return new Car();
}
}
//测试类
public class Test {
public static void main(String[] args) {
VehicleFactory factory = new CarFactory();
Moveable m = factory.create();
m.run();
}
}
//抽象工厂类
public abstract class AbstractFactory {
public abstract Vehicle createVehicle();
public abstract Weapon createWeapon();
public abstract Food createFood();
}
//具体工厂类
public class DefaultFactory extends AbstractFactory{
@Override
public Food createFood() {
return new Apple();
}
@Override
public Vehicle createVehicle() {
return new Car();
}
@Override
public Weapon createWeapon() {
return new AK47();
}
}
//抽象产品类
public abstract class Food {
public abstract void printName();
}
public abstract class Vehicle {
public abstract void run();
}
public abstract class Weapon {
public abstract void shoot();
}
//具体产品类
public class Apple extends Food {
public void printName() {
System.out.println("apple");
}
}
public class Car extends Vehicle {
public void run() {
System.out.println("冒着烟奔跑中car.......");
}
}
public class AK47 extends Weapon{
public void shoot() {
System.out.println("哒哒哒...");
}
}
//另一个具体工厂类以及相关的产品略。。。
public class AdvancedFactory extends AbstractFactory{
//...
}
//测试类
public class Test {
public static void main(String[] args) {
AbstractFactory f = new DefaultFactory();
Vehicle v = f.createVehicle();
v.run();
Weapon w = f.createWeapon();
w.shoot();
Food a = f.createFood();
a.printName();
}
}
简单工厂核心是封装对象的创建,而非直接 new 对象,但因为不能变更所创建的产品,不具备工厂方法的弹性。
工厂方法核心是通过子类创建对象,采用类继承机制,生成一个子类并重写该工厂方法,在该方法中生产一个产品对象。工厂方法创建了一个框架,让子类决定如何实现。
抽象工厂核心是通过子类创建产品家族,采用的是对象组合机制,专门定义“工厂”来负责对象的创建。抽象工厂提供一个用来创建一个产品家族的抽象类型,这个类型的子类(具体工厂类)定义了产品被生产的方法。