• 六个创建模式之工厂方法模式(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

  • 相关阅读:
    redis key全量导出与导出指定前缀的key
    php魔术变量
    搭建高可用mysql系列(2)-- Percona XtraDB Cluster 安装
    搭建高可用mysql系列(1)-- Percona XtraDB Cluster介绍
    memcached迁移方案——记一次memcached session服务的迁移
    php获取两个数组相同的元素(交集)以及比较两个数组中不同的元素(差集)
    PHP运行模式简单总结
    解决osx下 ssh: connect to host localhost port 22: Connection refused
    linux增加自己的可执行目录 $PATH
    macbook下 go 语言的 helloworld
  • 原文地址:https://www.cnblogs.com/zhangfei614/p/5994054.html
Copyright © 2020-2023  润新知