定义:定义一个用户创建对象的接口,让子类来决定实例化哪一个类,Factory Method使一个类实例化延迟到子类------研磨设计模式
定义二:定义一个用于创建对象的接口,让子类决定实例化哪个类---------Android源码设计模式解析与实现
思考:如何将一个类实例化延迟到子类?
先上工厂方法模式的UML图
然后我们看一个例子:
小车里面,我对奥迪是有情怀的,我就觉得好看,有曲线美,还低调,我们就以奥迪车举例。
我们先定义一个接口,接口里面有两个方法,一个是司机驾驶,一个是自动驾驶。
public abstract class AudiCar {
/**
* 汽车的抽象产品类
* 司机驾驶
*/
public abstract void drive();
/***
* 汽车的抽象产品类
* 可以自动驾驶
*/
public abstract void selfNavigation();
}
然后定义两个对象,Q5和Q7
public class AudiQ5Car extends AudiCar {
@Override
public void drive() {
System.out.println("Q5的驾驶");
}
@Override
public void selfNavigation() {
System.out.println("Q5自动驾驶");
}
}
public class AudiQ7Car extends AudiCar {
@Override
public void drive() {
System.out.println("Q7的驾驶");
}
@Override
public void selfNavigation() {
System.out.println("Q7自动驾驶");
}
}
那么如何将AudiCar这个类的实例化延迟到子类呢?
我们再定义一个接口,用来创建AudiCar的
public abstract class AudiFactory {
public abstract <A extends AudiCar> A createAudiCar(Class<A> clz);
}
然后实现这个接口
public class AudiCarFactory extends AudiFactory {
@Override
public <A extends AudiCar> A createAudiCar(Class<A> clz) {
AudiCar audiCar = null;
try {
audiCar = (AudiCar) Class.forName(clz.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return (A) audiCar;
}
}
这样就已经完成了,我们写个Client来调用试试
public class Client {
public static void main(String[] args) {
AudiFactory audiFactory = new AudiCarFactory();
AudiCar audiCar = audiFactory.createAudiCar(AudiQ7Car.class);
audiCar.drive();
audiCar.selfNavigation();
audiCar = audiFactory.createAudiCar(AudiQ5Car.class);
audiCar.drive();
audiCar.selfNavigation();
}
}
分析:
- 创建一个对象的接口,这个接口就是AudiFactory,里面有创建AudiCar的方法。
- 让子类决定实例化哪个类,在Client里面将想要实例化的类传入到AudiFactory里去。
再回到文章刚开始的问题,如何将一个类实例化延迟到子类?
这个类指的是AudiCar,子类指的是AudiCarFactory。其实就是有一个中间类AudiCarFactory,然后在AudiCarFactory里面去创建AudiCar。