先唠叨一句工厂方法模式的定义:
定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。
示例
先举一个汽车的栗子
<!-- lang: java -->
interface Vehicle {
public void drive();
public void clean();
}
class Car implements Vehicle {
@Override
public void drive() {
System.out.println("Driving a car...");
}
@Override
public void clean() {
System.out.println("Cleaning a car...");
}
}
class Bus implements Vehicle {
@Override
public void drive() {
System.out.println("Driving a Bus...");
}
@Override
public void clean() {
System.out.println("Cleaning a Bus...");
}
}
Java 7 及其之前版本的工厂方法
<!-- lang: java -->
abstract class VehicleDriver {
public abstract Vehicle getVehicle();
public void driveVehicle() {
getVehicle().drive();
}
public void cleanVehicle() {
getVehicle().clean();
}
}
class CarDriver extends VehicleDriver {
@Override
public Vehicle getVehicle() {
return new Car();
}
}
class BusDriver extends VehicleDriver {
@Override
public Vehicle getVehicle() {
return new Bus();
}
}
在使用时
<!-- lang: java -->
public class FactoryMethodPattern {
public static void main(String[] args) {
handleVehicle(new CarDriver());
handleVehicle(new BusDriver());
}
static void handleVehicle(VehicleDriver2 vDriver) {
System.out.println("Handling a new vehicle. Pre lambda way");
vDriver.driveVehicle();
vDriver.cleanVehicle();
}
}
Java 8 中的工厂方法
在 Java 8 中,我们可以通过 Lambda 来简化工厂方法的实现
<!-- lang: java -->
interface VehicleDriver {
public Vehicle getVehicle();
public default void driveVehicle() {
getVehicle().drive();
}
public default void cleanVehicle() {
getVehicle().clean();
}
}
public class FactoryMethodPatternLambda {
public static void main(String[] args) {
handleVehicle(Car::new); // Method reference
handleVehicle(() -> new Bus()); // Closure
}
static void handleVehicle(VehicleDriver vDriver) {
System.out.println("Handling a new vehicle...");
vDriver.driveVehicle();
vDriver.cleanVehicle();
}
}
方法接口
在 Java 8 中引入了方法接口这个概念,其定义是只包含一个方法定义的接口(新引入的默认方法不算,因为它算是方法实现)。在本例中,VehicleDriver 就是一个方法接口。在 Java 8 中可以通过使用闭包和方法引用的方式简化对方法接口的使用。
使用闭包时,闭包就会自动作为方法接口中唯一的方法定义的实现。使用方法引用时,方法引用则会被调用,其返回值被作为方法接口中的方法定义的返回值。
方法引用与闭包
相比较方法引用和闭包,我更倾向于后者,因为其语法更为清晰易懂,也容易扩展。因为很多时候你不只是需要 new 一个新对象,还需要做很多别的事情。这时,使用闭包就变得很容易实现这个目的了。