设计模式学习(二)-简单工厂模式
-
简单工厂模式定义:
简单工厂设计模式又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
-
简单工厂主要分为如下几个角色
-
抽象产品(abstract product):为所有具体产品的抽象表现,一般为抽象类
-
具体产品(product):为抽象产品的具体实现
-
生成产品工厂(factory):负责实现创建所有实例的内部逻辑
-
-
具体类图
-
Book 抽象产品
-
-
BookFactory:工厂类
-
-
具体Java实现
package cn.lonecloud.pattern.creational.simplefactory; /** * @author lonecloud * @version v1.0 * @Package cn.lonecloud.pattern.creational.simplefactory * @Description: TODO * @date 2018/12/2下午12:09 */ public class BookFactory { public static Book getBook(String name){ if ("english".equals(name)){ return new EnglishBook(); }else { return new ChineseBook(); } } }
-
该模式的优点:
-
将类的创建缩小到factory类中进行,免除调用方对创建类时候的一个责任,
-
客户端无需知道类名,只需要知道对应的参数即可
-
可以在引入配置文件的基础上,可以无需改变代码即可更换产品,实现灵活
-
-
该模式的缺点
-
所有类创建都建立在factory中进行,一旦该类出现了问题,则其他的所依赖的类都无法进行
-
系统扩展复杂,如果产品类型比较多的话,会导致factory中逻辑判断会非常多,不利于系统维护和扩展
-
简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构
-
-
使用场景
-
负责创建的类的数量相对较少,由于创建类的数量相对比较少,类的复杂性也就不会这么高
-
客户端创建类的时候,既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。
-
-
应用
-
Calendar中的使用
private static Calendar createCalendar(TimeZone zone, Locale aLocale) { CalendarProvider provider = LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale) .getCalendarProvider(); if (provider != null) { try { return provider.getInstance(zone, aLocale); } catch (IllegalArgumentException iae) { // fall back to the default instantiation } } Calendar cal = null; if (aLocale.hasExtensions()) { String caltype = aLocale.getUnicodeLocaleType("ca"); if (caltype != null) { switch (caltype) { case "buddhist": cal = new BuddhistCalendar(zone, aLocale); break; case "japanese": cal = new JapaneseImperialCalendar(zone, aLocale); break; case "gregory": cal = new GregorianCalendar(zone, aLocale); break; } } } if (cal == null) { if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") { cal = new BuddhistCalendar(zone, aLocale); } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja" && aLocale.getCountry() == "JP") { cal = new JapaneseImperialCalendar(zone, aLocale); } else { cal = new GregorianCalendar(zone, aLocale); } } return cal; }
-