zoukankan      html  css  js  c++  java
  • 六个创建模式之工厂方法模式(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

  • 相关阅读:
    [Algorithm] Delete a node from Binary Search Tree
    [Javascript] Check both prop exists and value is valid
    对象的多态性
    spring 定时任务(3)--配置多个定时任务
    能上QQ无法打开网页
    [置顶] Ajax核心--XMLHttpRequest对象
    linux内核--进程地址空间(一)
    [SQL]一个删选数据的例子,使用GROUP、DISTINCT
    [置顶] 腾讯2014软件开发笔试题目
    DBS小结
  • 原文地址:https://www.cnblogs.com/zhangfei614/p/5994054.html
Copyright © 2011-2022 走看看