简单工厂模式
简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
简单工厂模式适用情况包括:工厂类负责创建的对象比较少;客户端只知道传入工厂类的参数,对于如何创建对象不关心。
简单工厂模式包含如下角色:
- Factory:工厂角色
工厂角色负责实现创建所有实例的内部逻辑 - Product:抽象产品角色
抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口 - ConcreteProduct:具体产品角色
具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
abstract class Product{
public abstract void print();
}
class ProductA extends Product{
@Override
public void print() {
System.out.println("A");
}
}
class ProductB extends Product{
@Override
public void print() {
System.out.println("B");
}
}
public class Simplle {
public enum ProductType{
A,B;
}
public static Product createProduct(String type){
if(type.equals(ProductType.A)){
return new ProductA();
}
if(type.equals(ProductType.B)){
return new ProductB();
}
return null;
}
}
工厂类逻辑非常简单,只负责Product类的实例化,符合单一职责原则;用户只调用Product接口,可以减少耦合,符合依赖倒置原则;但是增加一个新的Product类时,要修改工厂方法,打破了开闭原则。
改进简单工厂模式,使得注册的类在使用时才被实例化,从而保证对扩展开放,同时对修改闭合。
具体的实现方式有以下两种:
- 使用反射机制注册产品类对象和实例化
- 注册产品对象并向每个产品添加newInstance方法,该方法返回与自身类型相同的新实例
使用反射机制进行类注册的简单工厂模式
public class Simplle{
private Map<String,Class> registeredProducts = new HashMap<>();
public void registerProduct(String productType,Class productClass){
registeredProducts.put(productType, productClass);
}
public Product createProdcut(String type) throws IllegalAccessException, InstantiationException {
Class productClass = registeredProducts.get(type);
return (Product) productClass.newInstance();
}
}
反射在某些情况下并不适用,比如,反射机制需要运行时权限,也会降低运行效率。
使用newInstance方法将进行类注册的简单工厂模式
首先在基类添加一个抽象方法(newInstance),在工厂类中保存对象类型与其对应的product对象,通过实例注册一种新的product对象。
abstract class Product{
abstract public Product newInstance();
public abstract void print();
}
class ProductA extends Product{
@Override
public ProductA newInstance() {
return new ProductA();
}
@Override
public void print() {
System.out.println("A");
}
}
class ProductB extends Product{
@Override
public ProductB newInstance() {
return new ProductB();
}
@Override
public void print() {
System.out.println("B");
}
}
public class Simplle{
private Map<String,Product> registeredProducts = new HashMap<>();
public void registerProduct(String productType,Product product){
registeredProducts.put(productType, product);
}
public Product createProdcut(String type) throws IllegalAccessException, InstantiationException {
return registeredProducts.get(type).newInstance();
}
}