简单工厂(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
简单工厂模式的优势以下:
缺点以下:
随处可见……