企业网站怎么做才好,php新手网站开发,wordpress充值会员,网站建设运营公司大全本文使用了王争老师设计模式课程中的例子#xff0c;写的很清晰#xff0c;而且中间穿插了代码优化。
由于设计模式就是解决问题的一种思路#xff0c;所以每个设计模式会从问题出发#xff0c;这样比较好理解设计模式出现的意义。
一、简单工厂模式 解决问题#xff1a…本文使用了王争老师设计模式课程中的例子写的很清晰而且中间穿插了代码优化。
由于设计模式就是解决问题的一种思路所以每个设计模式会从问题出发这样比较好理解设计模式出现的意义。
一、简单工厂模式 解决问题在调用时不想判断来实例化哪一个类或者实例化的过程过于复杂。 举个例子我们读取配置文件根据配置文件的后缀jsonxmlyaml来选择不同解析器JsonRuleConfigParser、XmlRuleConfigParser、YamlRuleConfigParser最后将文件解析为RuleConfig格式。这样具体调用的时候我们就不需要管到底实例化哪一个解析器只需要传入需要解析的文件路径。
1、定义解析器接口
public interface IRuleConfigParser {
}2、定义各类解析器
public class JsonRuleConfigParser implements IRuleConfigParser{
}public class XmlRuleConfigParser implements IRuleConfigParser{
}public class YamlRuleConfigParser implements IRuleConfigParser{
}3、定义工厂类
public class RuleConfigParserFactory {public IRuleConfigParser getParserInstance(String path) {//获取文件后缀String fileExtension getFileExtension();IRuleConfigParser parser null;if (json.equals(fileExtension)) {parser new JsonRuleConfigParser();} else if (xml.equals(fileExtension)) {parser new XmlRuleConfigParser();} else if (yaml.equals(fileExtension)) {parser new YamlRuleConfigParser();}return parser;}
} 总结简单工厂模式就是把创建对象的活单独抽出来放一个工厂类中。 优点对象的创建和使用进行了分离如果创建方式改了只修改工厂类就可以了。 缺点扩展性差加一个新的对象的时候需要修改工厂文件增加if-else。
二、工厂方法模式
适用工厂方法优化上面例子代码如下 1、给每个解析器创建一个工厂类工厂类又实现了IRuleConfigParserFactory 接口
public interface IRuleConfigParserFactory {IRuleConfigParser createParser();
}public class JsonRuleConfigParserFactory implements IRuleConfigParserFactory {Overridepublic IRuleConfigParser createParser() {return new JsonRuleConfigParser();}
}public class XmlRuleConfigParserFactory implements IRuleConfigParserFactory {Overridepublic IRuleConfigParser createParser() {return new XmlRuleConfigParser();}
}public class YamlRuleConfigParserFactory implements IRuleConfigParserFactory {Overridepublic IRuleConfigParser createParser() {return new YamlRuleConfigParser();}
}2、工厂抽象出来后看看怎么用
public class RuleConfigParserFactory {public IRuleConfigParser getParserInstance(String path) {//获取文件后缀String fileExtension getFileExtension();IRuleConfigParserFactory factory null;if (json.equals(fileExtension)) {factory new JsonRuleConfigParserFactory();} else if (xml.equals(fileExtension)) {factory new XmlRuleConfigParserFactory();} else if (yaml.equals(fileExtension)) {factory new YamlRuleConfigParserFactory();}return factory.createParser();}
}看完上面的代码是不是觉得又进入了if-else的圈子。看了王争老师的优化优化后代码如下通过单例可以避免if-else但是这种方法也有局限性如果每次需要创建不同的新对象下面的方法就不行了
public class JsonRuleConfigParserFactoryMap {private static final MapString, IRuleConfigParserFactory cachedFactory new HashMap();static {cachedFactory.put(json, new JsonRuleConfigParserFactory());cachedFactory.put(xml, new XmlRuleConfigParserFactory());cachedFactory.put(yaml, new YamlRuleConfigParserFactory());}public static IRuleConfigParserFactory getRuleConfigParserFactory(String fileExtension) {if (TextUtils.isEmpty(fileExtension)) {return null;}return cachedFactory.get(fileExtension);}
}把每个解析器的创建又封装到了工厂类里我个人觉得除了代码结构变复杂了没看到工厂方法比简单工厂好在哪。我看了很多例子大体都是这样要么没有写最后的用法要么僻重就轻把使用改成如下
JsonRuleConfigParserFactory jsonParserFactory new JsonRuleConfigParserFactory();
IRuleConfigParser jsonParser jsonParserFactory.createParser();所以学到这里工厂方法的优势没有get到最终的使用还是要if-else判断并且每增加一个解析器就会增加一个Factory类。
看王争老师总结之所以会有上面的疑惑是因为这种简单的使用场景其实并不适合使用工厂方法因为这个例子中工厂方法需要额外建Factory类并且类里就一句new对象代码没必要设计成独立类所以对于这个例子简单工厂比工厂方法更适合。
工厂方法适用场景对象的创建比较复杂不只是简单new例如还要组合其他类做各种初始化操作这种才比较适合工厂方法场景。
下面是刚才简单工厂获取解析器的逻辑如果获取parser的方式比较复杂还需要组合其他类做各种不同的初始化操作这样getParserInstance函数逻辑就会比较复杂就需要单独拆出工厂类去创建才会更合理。
public class RuleConfigParserFactory {public IRuleConfigParser getParserInstance(String path) {//获取文件后缀String fileExtension getFileExtension();IRuleConfigParser parser null;if (json.equals(fileExtension)) {parser new JsonRuleConfigParser();} else if (xml.equals(fileExtension)) {parser new XmlRuleConfigParser();} else if (yaml.equals(fileExtension)) {parser new YamlRuleConfigParser();}return parser;}
} 三、抽象工厂
抽象工厂主要在工厂方法的基础上解决多分类问题前面我们获取解析器是通过RuleConfig规则来区分的如果再加一个分类要通过系统配置规则来区分的呢使用工厂方法模式我们需要添加三个解析器再加三个工厂类。扩展的时候太过繁琐为解决这个问题可以再抽象出一个接口。
JsonRuleConfigParser()
XmlRuleConfigParser()
YamlRuleConfigParser()
//需要增加的
JsonSystemConfigParser()
XmlSystemConfigParser()
YamlSystemConfigParser()抽象工厂
public interface IConfigParserFactory {IRuleConfigParser createRuleConfigParser();ISystemConfigParser createSystemConfigParser();//扩展分类方式
}public class JsonConfigParserFactory implements IConfigParserFactory {Overridepublic IRuleConfigParser createRuleConfigParser() {return new JsonRuleConfigParser();}Overridepublic ISystemConfigParser createSystemConfigParser() {return new JsonSystemConfigParser();}
}public class XmlConfigParserFactory implements IConfigParserFactory {Overridepublic IRuleConfigParser createRuleConfigParser() {return new XmlRuleConfigParser();}Overridepublic ISystemConfigParser createSystemConfigParser() {return new XmlSystemConfigParser();}
}public class YamConfigParserFactory implements IConfigParserFactory {Overridepublic IRuleConfigParser createRuleConfigParser() {return new YamRuleConfigParser();}Overridepublic ISystemConfigParser createSystemConfigParser() {return new YamSystemConfigParser();}
}按照上面抽象工厂的方式无论添加多少分类方式这三个工厂类就可以满足。
四JDK中工厂使用
DateFormat使用的是简单工厂只需要提供DateStyle和TimeStyle可快速得到一个DateFormat 对象。
public final static DateFormat getDateInstance();
public final static DateFormat getDateInstance(int style);
public final static DateFormat getDateInstance(int style,Locale aLocale);
//使用
public static void main(String[] args) {DateFormat format DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT);String now format.format(new Date());System.out.println(now);}参考文章 简单工厂模式、工厂方法模式和抽象工厂模式有何区别 极客时间《设计模式》王争