工厂方法模式
意图
定义一个用于创建对象的接口,让子类决定实例化哪一个类。FactoryMethod使一个类的实例化延迟到其子类。
别名
虚构造器模式(Virtual Constructor)
动机
- 在软件系统创建过程中,经常面临着“某个对象”的创建工作:由于需求的变化,这个对象(的具体实现)经常面临着剧烈的变化,但是它却拥有比较稳定的接口。
- 如何应对这种变化?如何提供一种“封装机制”来隔离出“这个易变对象”的变化,从而保持系统中“其他依赖对象的对象”不随着需求改变而改变?
结构
适用性
1 当一个类不知道它所必须创建的对象的类的时候。
2.当一个类希望由它的子类来指定它所创建的对象的时候。
3.当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
参与者
1.简单理解就是Creator充当抽象工厂角色,定义工厂类所具有的基本的操作(用来生产具体工厂),任何具体工厂都必须继承该抽象类。
2.ConcreteCreator是具体工厂,继承抽象工厂,用来实现抽象工厂的方法,创建具体产品.
3.抽象产品角色(Product)定义了产品类型所有具有的基本操作,具体产品必须继承该抽象类.
4.具体产品角色(ConcreteProduct)充当具体产品角色,实现抽象产品类对定义的抽象方法,由具体工厂类创建,它们之间有一一对应的关系。
具体场景Java代码实现
场景描述:我们需要不同品牌的车,但是CarFactory(Creator)不再直接生产我们需要的车,而是把生产车的责任交给AodiFactory和BmwFactory(ConcreteCreator).
/**
* 第一步:创建工厂方法类CarFactory,用来创建具体的工厂.
* 第二步:创建抽象产品类Car
* 第三步:创建具体的产品实现类实现Car
* 第四步:创建具体的工厂方法AodiFactory和BmwFactory
* 第五步:测试,创建安迪车和宝马车对象.
*/
//第一步:创建工厂方法类CarFactory,用来创建具体的工厂.
public interface CarFactory {
/**
* 生产汽车的方法
*
* @return {@link Car}
*/
Car getCar();
}
//第二步:创建抽象产品类Car
public interface Car {
void name();
}
//第三步:创建具体的产品实现类实现Car
public class BMW implements Car {
/**
* 名字
*/
@Override
public void name() {
System.out.println("宝马");
}
}
public class Aodi implements Car {
/**
* 名字
*/
@Override
public void name() {
System.out.println("奥迪");
}
}
//第四步:创建具体的工厂方法AodiFactory和BmwFactory
public class BmwFactory implements CarFactory {
/**
* 生产宝马汽车
*
* @return {@link Car}
*/
@Override
public Car getCar() {
return new BMW();
}
}
public class AodiFactory implements CarFactory {
/**
* 生产奥迪汽车
*
* @return {@link Car}
*/
@Override
public Car getCar() {
return new Aodi();
}
}
//第五步:测试
public class Consumer {
public static void main(String[] args) {
Car bmw = new BmwFactory().getCar();
Car aodi = new AodiFactory().getCar();
bmw.name();
aodi.name();
//如果此时我们需要奔驰,只需要创建BenChiFactory即可。无需去改动原来的代码。
}
}
优点
1.在工厂方法中,用户只需要知道所要产品的具体工厂,无须关系具体的创建过程,甚至不需要具体产品类的类名。此案例中,用户只需要知道需要什么车,就去找什么车的工厂,而不需要知道Aodi和Bwm具体的类名.
2.在系统增加新的产品时,我们只需要添加一个具体产品类和对应的实现工厂,无需对原工厂进行任何修改,很好地符合了“开闭原则”(对访问开放,对修改关闭)。比如我们要增加一个五菱汽车,我们只需要创建WuLing去实现Car接口,创建WuLingFactory去实现CarFactory接口,这样我们就可以创建WuLing汽车了,对原有的代码未进行修改.
缺点
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,是的系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
Note:如有错误,欢迎指正.