一、工厂模式
工厂模式是用工厂方法代替new操作的一种模式。简单来讲就是提供给客户端一种统一的调用方式。
- 调用者不必知道对象是怎么被创建出来的;
- 只需知道需要的对象名称或者类型信息即可;
优点:
- 一个调用者想创建一个对象,只要知道其名称就可以了;
- 拓展性较高,如果想增加一个产品,只需拓展一个工厂实现类即可;
- 屏蔽产品的具体实现,对调用者透明化
缺点:
- 拓展性高所带来的缺点是,每增加一个产品,我们都需要额外的拓展一个工厂实现类,使得系统中类的数量成倍增长
- 一定程度上会增加系统复杂度
基础类代码如下:
public interface Car {
void getCar();
}
public class BYD implements Car {
@Override
public void getCar() {
System.out.println("来一辆BYD!");
}
}
public class BMW implements Car{
@Override
public void getCar() {
System.out.println("来一辆BMW!");
}
}
/**
* 飞机接口
*/
public interface Plane {
void getPlane();
}
public class AirPlane implements Plane{
@Override
public void getPlane() {
System.out.println("来一架客机!");
}
}
public class BattlePlane implements Plane{
@Override
public void getPlane() {
System.out.println("来一架战斗机!");
}
}
二、简单工厂
顾名思义,就是将多个具有共同特征的类的创建方法,采用同一个工厂类集中管理,例如汽车工厂。代码如下:
/**
* 简单工厂实现:就是将多个具有共同特征的类的创建方法,采用同一个工厂类集中管理,例如汽车工厂
*/
public class CarFactor {
public static Car carFactor(Class<?> tClass){
if (tClass.getName().equals(BMW.class.getName())){
return new BMW();
}
if (tClass.getName().equals(BYD.class.getName())){
return new BYD();
}
return null;
}
}
三、工厂方法
设计一个工厂的接口,你想要什么东西,就写个类继承于这个工厂,这样就不用修改什么,直接添加(改代码不如新增代码)就行了。就相当于,我这个工厂是用来生汽车的,而要什么品牌的汽车具体分到了每个车间,如果新多了一种品牌的汽车,直接新增一个车间就行了,代码如下:
/**
* 抽象工厂:
*/
public interface CarFactory {
Car getCarByFactory();
}
/**
* BMW 具体工厂类
*/
public class BMWFactory implements CarFactory{
@Override
public Car getCarByFactory() {
return new BMW();
}
}
public class BYDFactory implements CarFactory{
@Override
public Car getCarByFactory() {
return new BYD();
}
}
public class TestFactory {
public static void main(String[] args) {
Car bmw= new BMWFactory().getCarByFactory();
bmw.getCar();
}
}
四、抽象工厂
在工厂方法中,我们可以任意的拓展,但是有一个局限性是我们只能创建车,那么如果我们需要创建飞机该怎么办?
按照工厂方法的思路,需要先新建一个飞机工厂接口,然后多一种类型的飞机就增加一个新的实现类。但是这样有一个问题,Car工厂接口和飞机工厂接口此时属于是平级存在的,我们就需要暴露给外部两个接口,这其实是不合适的。
所以我们将工厂接口进一步进行抽象,可以理解为一个工厂有好几个车间,每个车间都可以生产飞机或者汽车。改造如下:
/**
* 车间接口
*/
public interface Factory {
Car getCarByFactory();
Plane getPlaneByFactory();
}
/**
* 具体工厂类:第一车间
*/
public class FactoryOne implements Factory{
@Override
public Car getCarByFactory() {
return new BMW();
}
@Override
public Plane getPlaneByFactory() {
return new AirPlane();
}
}
/**
* 具体工厂类:第二车间
*/
public class FactoryTwo implements Factory{
@Override
public Car getCarByFactory() {
return new BYD();
}
@Override
public Plane getPlaneByFactory() {
return new BattlePlane();
}
}
public class TestFactory {
public static void main(String[] args) {
Car byd = new FactoryTwo().getCarByFactory();
byd.getCar();
Plane airPlane = new FactoryOne().getPlaneByFactory();
airPlane.getPlane();
}
}
五、思考
抽象工厂已经结束了,但是这里有一个疑问供大家参考:
- 即使我们用抽象工厂这种方式解决了多类型对象的创建,但是如果类型过于庞大的话,那么对于项目复杂度来说是否是一个隐患?