Java设计模式:Simple Factory(简单工厂)模式

概念定义

简单工厂(Simple Factory)模式,又称静态工厂方法(Static Factory Method)模式,即定义一个工厂类,根据传入的不一样参数建立不一样的产品实例,这些实例对象具备共同的父类或接口。java

应用场景

  • 须要建立的产品对象较少,不然工厂逻辑会过于复杂。
  • 客户端只关心产品的接口,而不关心对象的具体建立过程。

示例代码

简单工厂模式由一个工厂类、一个产品接口(或抽象类)和一组实现该接口的具体产品组成。这个工厂类根据传入的参数创造一个具体的产品实现类,并向上转型为接口做为结果返回。数据库

本节经过一个"喜闻乐见"的豪车系列,展现简单工厂模式的实现。示例代码以下:ide

// 产品接口 //
public interface ICar { // 抽象类没法多重继承,而接口支持多实现,扩展性更好
    void drive();
}
// 若干具体的产品 //
public class Bmw implements ICar {
    @Override
    public void drive() { System.out.println("drive a Bmw"); }
}
public class Benz implements ICar {
    @Override
    public void drive() { System.out.println("drive a Benz"); }
}
public class Audi implements ICar {
    @Override
    public void drive() { System.out.println("drive a Audi"); }
}
// 工厂类 //
public class SimpleFactory {
    private SimpleFactory() {}
    public static ICar create(String car) { // 工厂不须要有状态,所以创造产品的方法是静态的
        if ("Bmw".equalsIgnoreCase(car)) {
            return new Bmw(); // 后续可在工厂里变动产品类名、构造方法参数甚至实例化方式
        } else if ("Benz".equalsIgnoreCase(car)) {
            return new Benz();
        } else if("Audi".equalsIgnoreCase(car)) {
            return new Audi();
        } else {
            return null;
        }
    }
}

客户端经过SimpleFactory.create("BMW").drive()便可建立Bmw实例并调用其drive()方法。code

如注释所示,工厂类封装了产品对象的建立过程,从而可在客户端不感知的状况下修改产品的建立方式。例如,若产品类实现了Cloneable接口,就能够在工厂中用(ICar)Bmw.clone()替代new Bmw()对象

此外,还能够经过枚举甚至注解实现简单工厂模式。以枚举实现为例:继承

public enum EnumCarFactory {
    BMW {
        @Override
        public ICar create() { return new Bmw(); }
    },
    BENZ {
        @Override
        public ICar create() { return new Benz(); }
    },
    AUDI {
        @Override
        public ICar create() { return new Audi(); }
    };

    public abstract ICar create(); // abstract修饰方法,强制每一个枚举实现该方法
}

客户端经过EnumCarFactory.AUDI.create().drive()EnumCarFactory.valueOf("AUDI").create().drive(),便可建立Audi实例并调用其draw()方法。接口

注意,以上实现并不符合开放-封闭原则(对扩展开放,对修改关闭)。例如新增产品时,SimpleFactory工厂内须要添加分支条件,EnumCarFactory工厂内则要添加对应的枚举定义。这一缺陷能够经过反射机制来避免:get

public class EnhancedSimpleFactory {
    private EnhancedSimpleFactory() {}
    public static <T> T create(Class<? extends T> clazz) {
        T obj = null;
        try {
            obj = (T) Class.forName(clazz.getName()).newInstance();
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return obj;
    }
}

客户端经过EnhancedSimpleFactory.create(Benz.class).drive(),便可建立Benz实例并调用其draw()方法。产品

注意,EnhancedSimpleFactory.create(clazz)的入参类路径也可来自配置文件、数据库等,所以更具灵活性。io

模式优缺点

简单工厂模式的优势以下:

  • 解耦:将对象的建立和使用过程分开(客户端只接触产品接口),下降对象和客户端的耦合关系。
  • 下降代码重复: 将建立对象的过程集中于工厂内部,当建立对象较为复杂且频繁建立时,能够减小重复性代码。
  • 下降维护成本:建立过程由工厂统一管理,当业务逻辑变动时在工厂里修改便可,而无需逐个修正全部须要建立对象的地方。

缺点以下:

  • 简单工厂使用静态工厂方法,静态方法不能被继承和重写,所以工厂角色没法造成基于继承的等级结构。
  • 简单工厂容易违背开放-封闭原则(虽然能够经过反射机制改善),可能致使工厂逻辑过于复杂。
  • 工厂类集中负责全部产品对象的建立逻辑,一旦工厂不能正常工做,整个系统都会受到影响。

业界实践

随处可见……

相关文章
相关标签/搜索