六个创建模式之工厂方法模式(Factory Method Pattern)

问题:
在使用简单工厂模式的时候,如果添加新的产品类,则必需修改工厂类,违反了开闭原则。

定义:
定义一个用于创建对象的接口,让子类决定具体实例化哪个产品类。此时工厂和产品都具有相同的继承结构,抽象产品类与抽象工厂对应,具体的产品类和具体的工厂类对应。工厂方法模式又称为:工厂模式(Factory Pattern)、虚拟构造器模式(Virtual Constructor Pattern)、多态工厂模式(Polymorphic Factory Pattern)等。

结构图:

  • Product:抽象产品类,是所有具体产品的超类型,封装了具体产品的公共方法。
  • ConcreteProduct:具体产品类,实现了抽象产品类的接口,和具体工厂一一对应。
  • Factory:抽象工厂类,定义了返回抽象产品类的工厂方法,是工厂方法模式的核心。
  • ConcreteFactory:具体工厂类,实现了抽象工厂定义的工厂方法,由客户端直接调用,返回其对应的具体产品类。

注意:

  • 为了让系统有更好的灵活性和可扩展性,可以使用XML技术和反射技术让客户端通过配置文件指定具体工厂类。

  • 可以在抽象工厂中定义多个重载的工厂方法,包含不同的业务逻辑,来满足对不同产品对象的需求。例如可以传入数据库配置信息,文件配置信息等。

interface LoggerFactory {  
    public Logger createLogger();  
    public Logger createLogger(String args);  
    public Logger createLogger(Object obj);  
}
class DatabaseLoggerFactory implements LoggerFactory {  
    public Logger createLogger() {  
            //使用默认方式连接数据库,代码省略  
            Logger logger = new DatabaseLogger();   
            //初始化数据库日志记录器,代码省略  
            return logger;  
    }  

    public Logger createLogger(String args) {  
            //使用参数args作为连接字符串来连接数据库,代码省略  
            Logger logger = new DatabaseLogger();   
            //初始化数据库日志记录器,代码省略  
            return logger;  
    }     

    public Logger createLogger(Object obj) {  
            //使用封装在参数obj中的连接字符串来连接数据库,代码省略  
            Logger logger = new DatabaseLogger();   
            //使用封装在参数obj中的数据来初始化数据库日志记录器,代码省略  
            return logger;  
    }     
}  

  • 还可以由工厂直接调用具体产品的业务方法,而隐藏工厂创建具体实例的方法。
abstract class LoggerFactory {  
    //在工厂类中直接调用日志记录器类的业务方法writeLog()  
    public void writeLog() {  
        Logger logger = this.createLogger();  
        logger.writeLog();  
    }  

    public abstract Logger createLogger();    
}

优点:

  • 利用工厂的工厂方法类创建具体的实例,隐藏了具体实例的创建细节,无需知道具体实例的类名,只需关心对应工厂。
  • 加入新的产品类是,只需要同时加入工厂类就可以实现扩展。如果利用反射和XML技术,不需要修改任何源码,符合“开闭原则”

缺点:

  • 系统中类的个数显著增加,不利于系统的维护,增加系统编译和运行的开销。

适用场景

  • 具体产品类数目不多,客户不需要知道具体产品类的详细信息,只需要知道具体对应的工厂。

实例:

FactoryMethodPattern.java

原文地址:https://www.cnblogs.com/zhangfei614/p/5994054.html