美文网首页
工厂模式

工厂模式

作者: lj72808up | 来源:发表于2021-04-12 11:49 被阅读0次

一. 简单工厂与实例工厂

1. 什么时候用简单工厂, 什么时候用实例工厂

  • 当创建一个对象及其复杂, 只用 new 关键字不能表达的时候, 就可以用简单工厂模式, 将对象的创建过程写在一个静态方法里.
    如下例子中, 根据文件名类型的不同, 按照不同方法解析文件, 形成配置类
    class RuleConfigSource {
        public RuleConfig load(String ruleConfigFilePath) throws Exception {
            String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath);
            // 简单工厂创建对象
            IRuleConfigParser parser = RuleConfigFactory.createParser(ruleConfigFileExtension);
    
            String configText = "";
            //从ruleConfigFilePath⽂件中读取配置⽂本到configText中
            RuleConfig ruleConfig = parser.parse(configText);
            return ruleConfig;
        }
    
        private String getFileExtension(String filePath) {
        //...解析⽂件名获取扩展名,⽐如rule.json,返回json
            return "json";
        }
    }
    
    // 简单工厂类
    class RuleConfigFactory {
        /**
         * 简单⼯⼚模式的代码实现中,有多处 if 分⽀判断逻辑,违背开闭原则,但
         * 权衡扩展性和可读性,这样的代码实现在⼤多数情况下(⽐如,不需要频繁地添加
         * parser,也没有太多的 parser)是没有问题的。
         */
        public static IRuleConfigParser createParser(String ruleConfigFileExtension) throws Exception {
            IRuleConfigParser parser;
            if ("json".equalsIgnoreCase(ruleConfigFileExtension)) {
                parser = new JsonRuleConfigParser();
            } else if ("xml".equalsIgnoreCase(ruleConfigFileExtension)) {
                parser = new XmlRuleConfigParser();
            } else if ("yaml".equalsIgnoreCase(ruleConfigFileExtension)) {
                parser = new YamlRuleConfigParser();
            } else if ("properties".equalsIgnoreCase(ruleConfigFileExtension)) {
                parser = new PropertiesRuleConfigParser();
            } else {
                throw new Exception("Rule config file format is not supported: ");
            }
    
            return parser;
        }
    }
    
    
    interface IRuleConfigParser{}
    class JsonRuleConfigParser implements IRuleConfigParser{}
    class XmlRuleConfigParser implements IRuleConfigParser{}
    class YamlRuleConfigParser implements IRuleConfigParser{}
    class PropertiesRuleConfigParser implements IRuleConfigParser{}
    
  • 如果在此基础上, 当创建的对象是一类对象中的某一类时 (比如上例中的 xmlParser, jsonParser, htmlParser就属于一类 parser 对象), 如果还要使用简工厂, 那么判断创建出什么样的对象 这个判断逻辑, 就要全部使用 if-else 写在一个静态方法里. 当判断逻辑复杂时, 这些 if-else 就又变得丑陋, 于是将这个 if-else 判断规则抽成一个类, 用来判断返回哪个对象的创建方法, 这就需要用一个接口, 将对象的创建抽象出来, 再让不同的工厂类实现这个接口
    /**
     * 各种工厂对象的接口
     */
    interface IRuleConfigParserFactory {
        IRuleConfigParser createParser();
    }
    
    class JsonRuleConfigParserFactory implements IRuleConfigParserFactory {
        public IRuleConfigParser createParser() {
            /** 这些工厂中创建对象的逻辑是不适用的, 如果创建对象只用new, 那根本不用使用工厂模式来创建对象, 工厂模式是为了封装复杂的创建对象逻辑*/
            return new JsonRuleConfigParser();
        }
    }
    
    class XmlRuleConfigParserFactory implements IRuleConfigParserFactory {
    
        public IRuleConfigParser createParser() {
            return new XmlRuleConfigParser();
        }
    }
    
    class YamlRuleConfigParserFactory implements IRuleConfigParserFactory {
    
        public IRuleConfigParser createParser() {
            return new YamlRuleConfigParser();
        }
    }
    
    
    class RuleConfigSource {
        /** 主要目标是完成从不同格式的文件中加载形成配置对象 */
        public RuleConfig load(String ruleConfigFilePath) throws Exception {
            String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath);
    
            // RuleConfigParserFactoryMap.getParserFactory 判断使用哪个工厂的规则
            IRuleConfigParserFactory parserFactory = RuleConfigParserFactoryMap.getParserFactory(ruleConfigFileExtension);
            if (parserFactory == null) {
                throw new Exception("Rule config file format is not supp");
            }
            IRuleConfigParser parser = parserFactory.createParser();
            String configText = "";
    
            //从ruleConfigFilePath⽂件中读取配置⽂本到configText中
            RuleConfig ruleConfig = parser.parse(configText);
            return ruleConfig;
        }
    
        private String getFileExtension(String filePath) {
        //...解析⽂件名获取扩展名,⽐如rule.json,返回json
            return "json";
        }
    }
    
    //因为⼯⼚类只包含⽅法,不包含成员变量,完全可以复⽤,
    //不需要每次都创建新的⼯⼚类对象,所以,简单⼯⼚模式的第⼆种实现思路更加合适。
    public class RuleConfigParserFactoryMap { //⼯⼚的⼯⼚
        private static final Map<String, IRuleConfigParserFactory> cachedFactories = new ConcurrentHashMap<String, IRuleConfigParserFactory>();
    
        static {
            cachedFactories.put("json", new JsonRuleConfigParserFactory());
            cachedFactories.put("xml", new XmlRuleConfigParserFactory());
            cachedFactories.put("yaml", new YamlRuleConfigParserFactory());
        }
    
        public static IRuleConfigParserFactory getParserFactory(String type) {
            if (type == null || type.isEmpty()) {
                return null;
            }
            IRuleConfigParserFactory parserFactory = cachedFactories.get(type.toLowerCase();
            return parserFactory;
        }
    }
    

二. 抽象工厂

抽象工厂和实例工厂的区别在于, 工厂接口的方法不止有一个,而是有多个. 这种区别主要用来表达, 使用第二个维度划分创建对象的种类. 即用工厂接口的不同方法名划分第二个维度. 实例工厂接口因为只有1个方法, 只能通过工厂的不同区分对象的种类, 只有一个维度上的区分

interface IConfigParserFactory {
    IRuleConfigParser createRuleParser();
    ISystemConfigParser createSystemParser();
//此处可以扩展新的parser类型,⽐如IBizConfigParser
}
class JsonConfigParserFactory implements IConfigParserFactory {
    @Override
    public IRuleConfigParser createRuleParser() {
        return new JsonRuleConfigParser();
    }
    @Override
    public ISystemConfigParser createSystemParser() {
        return new JsonSystemConfigParser();
    }
}
class XmlConfigParserFactory implements IConfigParserFactory {
    @Override
    public IRuleConfigParser createRuleParser() {
        return new XmlRuleConfigParser();
    }

    @Override
    public ISystemConfigParser createSystemParser() {
        return new XmlSystemConfigParser();
    }

    // 省略YamlConfigParserFactory和PropertiesConfigParserFactory代码
}

interface ISystemConfigParser{}

class XmlSystemConfigParser implements ISystemConfigParser{}
class JsonSystemConfigParser implements ISystemConfigParser{}

相关文章

  • 常用设计模式

    设计模式 工厂模式 工厂模式思路上分:简单工厂模式,工厂模式, 抽象工厂模式// 抽象工厂模式可以代替工厂模式,做...

  • 工厂模式

    工厂模式细分三种:简单工厂模式、工厂模式、抽象工厂模式。 工厂模式相当于抽象了简单工厂模式的工厂类,而抽象工厂模式...

  • 工厂模式

    工厂模式 就是工厂---生产-->产品 在设计模式中,分为 简单工厂模式, 工厂方法模式,抽象工厂模式. 工厂模式...

  • 找女朋友之简单工厂模式,工厂模式,抽象工厂模式

    找女朋友之简单工厂模式,工厂模式,抽象工厂模式 找女朋友之简单工厂模式,工厂模式,抽象工厂模式

  • 【设计模式】- 工厂模式

    工厂模式分为三种:简单工厂模式、工厂方法模式和抽象工厂模式。 工厂模式:靠工厂生产对象 简单工厂模式中只有一个工厂...

  • 工厂模式

    工厂模式包含三种模式:简单工厂模式、工厂方法模式和抽象工厂模式。 简单工厂模式 定义简单工厂模式:由一个工厂类根据...

  • Java设计模式——工厂模式

    工厂模式简单工厂模式工厂方法模式抽象工厂模式 1.简单工厂模式 1.基本介绍1)简单工厂模式也叫静态工厂模式,是属...

  • 设计模式-3种工厂模式

    工厂模式包括:简单工厂模式,工厂方法模式,抽象工厂模式 简单工厂模式 工厂方法根据参数直接创建实例:工厂->产品 ...

  • 设计模式-工厂模式

    工厂模式概念 实例化对象,用工厂方法代替new操作。工厂模式包括工厂方法模式和抽象工厂模式。抽象工厂模式是工厂模式...

  • 第一章2.0工厂- 基础类准备

    2.1工厂-简单工厂模式2.2工厂-工厂方法模式2.3工厂-抽象工厂模式

网友评论

      本文标题:工厂模式

      本文链接:https://www.haomeiwen.com/subject/fytxlltx.html