工厂模式(Factory Pattern)
类型:创造型模式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象,意思就是父类(接口)引用指向子类对象(接口的实现类)。
在一般我们需要得到一个类的时候,首先是定义这个类,然后就是直接显示地new一个对象出来,这样的做法使得我们将创建对象的逻辑毫无保留的暴露了出来;而工厂模式呢是把创建对象的方法封装起来,你如果需要,我就调用工厂的创建对象方法返回一个对象给你,这样一来用户在使用的时候其实只需要知道怎么用(调用方法),不用去理会怎么实现内部逻辑的(实现方法)。这样也把创建对象的逻辑隐藏了起来。
下面来代码实现:(实现交通工具的工厂模式)
首先定义一个交通工具类的接口:
/**
- 交通工具接口;
*/
public interface Vehicle {
public void run(); // 交通工具的行驶方式;
}
交通工具类有一个通用的方法run(),描述的是其行驶方式;
接下来用具体的交通工具类来实现这个接口:
Cycle类:
public class Cycle implements Vehicle {
@Override
public void run() {
System.out.println("I'am Cycle, I use two wheels to run!");
}
}
Bus类:
public class Bus implements Vehicle {
@Override
public void run() {
System.out.println("I'am Bus, I use four wheels to run!");
}
}
接下来是创建一个工厂类,这个工厂类用于创建我们的具体交通工具类:
VehicleFactory类:
/**
-
交通工具工厂类,用于生成交通工具对象;
*/
public class VehicleFactory {// 获取具体的交通工具方法;
public Vehicle getVehicle(String name) {
if (name == null) {
return null;
} else if (name.equalsIgnoreCase("BUS")) {
return new Bus();
} else if (name.equalsIgnoreCase("CYCLE")) {
return new Cycle();
}
return null;
}
}
所以我们可以看到,如果想要得到一个Cycle类或者是Bus类,只要向工厂索要就好了,具体的实现不是我们要操心的问题:
测试类:
public class Main {
public static void main(String [] args) {
VehicleFactory vehicleFactory = new VehicleFactory(); // 新建一个工厂类对象;
// 新建父类引用;
Vehicle vehicle;
// 获取自行车;
vehicle = vehicleFactory.getVehicle("Cycle"); // 父类引用指向子类对象;
vehicle.run();
// 获取大巴车;
vehicle = vehicleFactory.getVehicle("Bus"); // 父类引用指向子类对象;
vehicle.run();
}
}
这样一来对于客户而言,内部实现的逻辑他是不知道的,他只知道自己想得到一个Cycle或者是Bus。
下面是运行结果:
I'am Cycle, I use two wheels to run!
I'am Bus, I use four wheels to run!
工厂模式的优缺点
优点:
调用者想要创建一个对象,只要知道它的名字就可以了;比如Cycle对象就是"cycle",Bus对象就是"bus",其内部实现不用操心;
扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以;例如如果想要增加一个"火车"类,只需要新增一个火车类对象就可以了;
屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。