先唠叨一句工厂方法模式的定义:
定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。
示例
先举一个汽车的栗子
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 及其之前版本的工厂方法
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(); }}
在使用时
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 来简化工厂方法的实现
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 一个新对象,还需要做很多别的事情。这时,使用闭包就变得很容易实现这个目的了。