03|工厂模式

一、原始类

有太多的if-else,语句。

package com.geek.jeep.designpattern.factory;

/**
 * @author geek
 * 演示工厂模式最原始的代码:
 * 根据不同的配置文件,选择不同的文件解析器
 *  封装变化:创建逻辑有可能变化,封装成工厂类之后,创建逻辑的变更对调用者透明。
 *  代码复用:􏰀创建代码抽离到独立的工厂类之后可以复用。
 *  隔离复杂性:封装复杂的创建逻辑,调用者无需了解如何创建对象。
 *  控制复杂度:将创建代码抽离出来,让原本的函数或类职责更单一,代码更简洁。
 */
public class RuleConfigSource {

    public RuleConfig load(String ruleConfigFilePath) throws Exception {

        String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath);
        IRuleConfigParser parser = null;
        if ("json".equalsIgnoreCase(ruleConfigFileExtension)) {
            parser = new JsonRuleConfigParser();
        } else if ("xml".equalsIgnoreCase(ruleConfigFileExtension)) {
            parser = new XmlRuleConfigParser();
        } else if ("yam".equalsIgnoreCase(ruleConfigFileExtension)) {
            parser = new YamlRuleConfigParser();
        } else {
            throw new Exception("Rule config file format is not supported:"+ ruleConfigFilePath);
        }
        String configText = "";
        RuleConfig ruleConfig = parser.parse(configText);
        return ruleConfig;
    }


    private String getFileExtension(String filePath) {
        // 解析文件扩展名,如 rule.json 返回 json
        return "json";
    }
}

 

二、第一次改造

将if-else 剥离到函数中,抽象成方法

package com.geek.jeep.designpattern.factory;

/**
 * @author geek
 * <p>
 * 剥离函数
 */
public class RuleConfigSource1 {


    public RuleConfig load(String ruleConfigFilePath) throws Exception {

        String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath);
        IRuleConfigParser parser = createIRuleConfigParser(ruleConfigFileExtension);
        String configText = "";
        RuleConfig ruleConfig = parser.parse(configText);
        return ruleConfig;
    }

    private IRuleConfigParser createIRuleConfigParser(String ruleConfigFileExtension) throws Exception {
        IRuleConfigParser parser = null;
        if ("json".equalsIgnoreCase(ruleConfigFileExtension)) {
            parser = new JsonRuleConfigParser();
        } else if ("xml".equalsIgnoreCase(ruleConfigFileExtension)) {
            parser = new XmlRuleConfigParser();
        } else if ("yam".equalsIgnoreCase(ruleConfigFileExtension)) {
            parser = new YamlRuleConfigParser();
        } else {
            throw new Exception("Rule config file format is not supported:" + ruleConfigFileExtension);
        }
        return parser;
    }


    private String getFileExtension(String filePath) {
        // 解析文件扩展名,如 rule.json 返回 json
        return "json";
    }
}

 

 

三、第二次改造

为了让类的职责更加单一,代码更加清晰,

进一步 将 抽象方法,转移到了类里面, 新建一个工厂类 RuleConfigParserFactory

 

第一种工厂类:

package com.geek.jeep.designpattern.factory;

/**
 * @author geek
 */
public class RuleConfigParserFactory {

    public static IRuleConfigParser createIRuleConfigParser(String ruleConfigFileExtension) throws Exception {
        IRuleConfigParser parser = null;
        if ("json".equalsIgnoreCase(ruleConfigFileExtension)) {
            parser = new JsonRuleConfigParser();
        } else if ("xml".equalsIgnoreCase(ruleConfigFileExtension)) {
            parser = new XmlRuleConfigParser();
        } else if ("yam".equalsIgnoreCase(ruleConfigFileExtension)) {
            parser = new YamlRuleConfigParser();
        } else {
            throw new Exception("Rule config file format is not supported:"+ ruleConfigFileExtension);
        }
        return parser;
    }
}
package com.geek.jeep.designpattern.factory;

/**
 * 为了让类的职责更加单一,代码更加清晰,
 * 进一步 将 抽象方法,转移到了类里面, 新建一个工厂类 RuleConfigParserFactory
 */
public class RuleConfigSource2 {

    public RuleConfig load(String ruleConfigFilePath) throws Exception {

        String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath);
        //第一种
        IRuleConfigParser parser = RuleConfigParserFactory.createIRuleConfigParser(ruleConfigFileExtension);
        //第二种
        IRuleConfigParser parser2 = RuleConfigParserFactory2.createIRuleConfigParser(ruleConfigFileExtension);

        String configText = "";
        RuleConfig ruleConfig = parser.parse(configText);
        return ruleConfig;
    }

    private String getFileExtension(String filePath) {
        // 解析文件扩展名,如 rule.json 返回 json
        return "json";
    }
}

 

 

 

第二种工厂类:

 

避免多次创建,实现复用。

 

package com.geek.jeep.designpattern.factory;

import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 简单工厂的第二种实现方式
 */
public class RuleConfigParserFactory2 {

    private static final Map<String, IRuleConfigParser> cachedParsers = new HashMap<>();

    static {
        cachedParsers.put("json", new JsonRuleConfigParser());
        cachedParsers.put("xml", new XmlRuleConfigParser());
        cachedParsers.put("yam", new YamlRuleConfigParser());
    }

    public static IRuleConfigParser createIRuleConfigParser(String ruleConfigFileExtension) throws Exception {
        if (StringUtils.isEmpty(ruleConfigFileExtension)) {
            return null;
        }
        return cachedParsers.get(ruleConfigFileExtension.toLowerCase());
    }


}

 

 

 

工厂方法

 

一、工厂类

package com.geek.jeep.designpattern.factory.method;

import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @author geek
 * 工厂的工厂
 */
public class RuleConfigParserFactoryMap {

    private static final Map<String, IRuleConfigParserFactory> cachedFactories = new HashMap<>();

    static {
        cachedFactories.put("json", new JsonRuleConfigParserFactory());
        cachedFactories.put("xml", new XmlRuleConfigParserFactory());
        cachedFactories.put("yam", new YamlRuleConfigParserFactory());
    }

    public static IRuleConfigParserFactory getParserFactory(String type) {
        if (StringUtils.isEmpty(type)) {
            return null;
        }
        return cachedFactories.get(type);
    }
}

 

package com.geek.jeep.designpattern.factory.method;

import com.geek.jeep.designpattern.factory.IRuleConfigParser;
import com.geek.jeep.designpattern.factory.RuleConfig;
import com.geek.jeep.designpattern.factory.RuleConfigParserFactory;
import com.geek.jeep.designpattern.factory.RuleConfigParserFactory2;

/**
 *
 * @author geek
 */
public class RuleConfigSourceMap {

    public RuleConfig load(String ruleConfigFilePath) throws Exception {

        String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath);
        IRuleConfigParserFactory factory = RuleConfigParserFactoryMap.getParserFactory(ruleConfigFileExtension);
        IRuleConfigParser parser = factory.createParser();
        String configText = "";
        RuleConfig ruleConfig = parser.parse(configText);
        return ruleConfig;
    }

    private String getFileExtension(String filePath) {
        // 解析文件扩展名,如 rule.json 返回 json
        return "json";
    }
}

 

 

package com.geek.jeep.designpattern.factory.method;

import com.geek.jeep.designpattern.factory.IRuleConfigParser;

/**
 * @author geek
 */
public interface IRuleConfigParserFactory {
    IRuleConfigParser createParser();
}



#--------------------------
package com.geek.jeep.designpattern.factory.method;

import com.geek.jeep.designpattern.factory.IRuleConfigParser;
import com.geek.jeep.designpattern.factory.JsonRuleConfigParser;

/**
 * @author geek
 * 工厂方法模式 : 利用多态
 */
public class JsonRuleConfigParserFactory implements IRuleConfigParserFactory{
    @Override
    public IRuleConfigParser createParser() {
        return new JsonRuleConfigParser();
    }
}


#--------------------------
package com.geek.jeep.designpattern.factory.method;

import com.geek.jeep.designpattern.factory.IRuleConfigParser;
import com.geek.jeep.designpattern.factory.XmlRuleConfigParser;

/**
 * @author geek
 */
public class XmlRuleConfigParserFactory implements IRuleConfigParserFactory{
    @Override
    public IRuleConfigParser createParser() {
        return new XmlRuleConfigParser();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值