工厂模式目的:将创建对象的具体过程屏蔽起来
简单工厂模式
简单工厂模式(类创建型模式):可以根据参数的不同返回不同类的实例
简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类
简单工厂模式角色:
- Factory:工厂角色根据不同的参数创建不同的实例
- IProduct:抽象产品角色 所有产品实例的接口,负责描述所有产品实例的行为
- ConcreteProduct:具体产品角色:所有创建的对象都充当这个角色的某个具体类的实例
场景示例:
平台做一个机票代购业务,对接了两个供应商A、B,用户选择完机票后,平台拿着机票去供应商下单。,下单时根据机票由那个供应商提供去相应的供应商去下下单
定义抽象接口
public interface IVender {
/**
* 供应商下单方法
*/
void order();
}
实现具象接口
然后分别实现A、B供应商的下单方法
public class VendorA implements IVender {
@Override
public void order() {
// 业务逻辑处理
System.out.println("A供应商下单成功,下单时间" + new Date());
}
}
public class VendorB implements IVender {
@Override
public void order() {
// 业务逻辑处理
System.out.println("B供应商下单成功,下单时间:" + new Date());
}
}
定义工厂类
接着定义一个工厂类,根据传入的不同参数请求,分别创建不同的供应商实例并返回,若碰到无效的参数,则抛出异常
public class VendorFactory {
public static IVender createVendor(String type) {
switch (type) {
case "A":
return new VendorA();
case "B":
return new VendorB();
default:
throw new RuntimeException("供应商不存在");
}
}
}
调用工厂类
public class Client {
public static void main(String[] args) {
String type = "A";
IVender iVender = VendorFactory.createVendor(type);
iVender.order();
}
}
总结
优点:
- 工厂类进行判断逻辑,可以决定在什么时候创建哪一个产品类的实例;客户端可以免除直接创建产品对象的责任,仅仅消费产品;(实现对象的创建和对象的使用分裂,将对象的创建交给专门的工厂类复杂)==》变更时可以不修改客户端代码
- 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数,对于一些负责的类名,通过简单工厂模式可以方便调用
缺点:
- 工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑(违背了开闭原则)
- 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,产品类型较多时可能造成工厂逻辑过于复杂,不利于系统的扩展和维护
使用场景
- 工厂类负责创建的对象比较少:创建的对象较少的情况下,工厂方法中的业务逻辑不会复杂
- 客户端只知道工厂类的参数,对于如何创建对象不关系:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数
抽象工厂模式
抽象工厂模式主要用于创建相关对象的家族。当一个产品族中需要被设计在一起工作时,通过抽象工厂模式,能够保证客户端始终只使用同一个产品族中的对象;
- 抽象工厂 AbstractFactory:定义了一个接口,这个接口包含了一组方法用来生产产品,所有的具体工厂都必须实现此接口。
- 具体工厂 ConcreteFactory:用于生产不同产品族,要创建一个产品,用户只需使用其中一个工厂进行获取,完全不需要实例化任何产品对象。
- 抽象产品 AbstractProduct:这是一个产品家族,每一个具体工厂都能够生产一整组产品。
- 具体产品 Product
代码示例
产品类
//发动机以及型号
public interface Engine {}
public class EngineA implements Engine{
public EngineA(){
System.out.println("制造-->EngineA");
}
}
public class EngineB implements Engine{
public EngineB(){
System.out.println("制造-->EngineB");
}
}
//空调以及型号
public interface Aircondition {}
public class AirconditionA implements Aircondition{
public AirconditionA(){
System.out.println("制造-->AirconditionA");
}
}
public class AirconditionB implements Aircondition{
public AirconditionB(){
System.out.println("制造-->AirconditionB");
}
}
工厂类
//创建工厂的接口
public interface AbstractFactory {
//制造发动机
public Engine createEngine();
//制造空调
public Aircondition createAircondition();
}
//为宝马320系列生产配件
public class FactoryBMW320 implements AbstractFactory{
@Override
public Engine createEngine() {
return new EngineA();
}
@Override
public Aircondition createAircondition() {
return new AirconditionA();
}
}
//宝马523系列
public class FactoryBMW523 implements AbstractFactory {
@Override
public Engine createEngine() {
return new EngineB();
}
@Override
public Aircondition createAircondition() {
return new AirconditionB();
}
}
客户端
public class Customer {
public static void main(String[] args){
//生产宝马320系列配件
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
factoryBMW320.createEngine();
factoryBMW320.createAircondition();
//生产宝马523系列配件
FactoryBMW523 factoryBMW523 = new FactoryBMW523();
factoryBMW523.createEngine();
factoryBMW523.createAircondition();
}
}
工厂模式对比:
简单工厂模式:工厂方法只有一个抽象产品类和一个工厂类,单可以派生出多个具体产品类和具体工厂类,每个具体工厂类只能创建一个具体产品类的实例
抽象工厂模式:抽象工厂拥有多个抽象产品类和一个抽象工厂类,每个抽象产品类可以派生出多个具体产品类;