1、 简单工厂模式定义
提供一个创建对象实例的功能,而无须关心其具体实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类。
2、简单工厂包含以下角色
- CarFactory:生产汽车的简单工厂
生产汽车的简单工厂负责实现生产汽车的所有逻辑 - Car:抽象汽车产品
抽象汽车产品是所有汽车的父类,负责描述所有汽车的属性和行为 - Porsche:保时捷汽车
具体产品是生产的保时捷汽车。 - Ferrari:法拉利汽车
具体产品是生产的法拉利汽车。
3、简单工厂模式用UML类图表示
4、简单工厂模式用代码表示
- 车辆接口
/**
* 汽车接口
*/
public interface Car {
void run();
}
- 保时捷
/**
* 保时捷
*/
public class Porsche implements Car {
@Override
public void run() {
System.out.println("Porsche running ...");
}
}
- 法拉利
public class Ferrari implements Car {
@Override
public void run() {
System.out.println("Ferrari running ...");
}
}
- 车辆工厂
/**
* 车辆工厂
*
*/
public class CarFactory {
public static Car getCar(String carType) {
switch (carType) {
case "ferrari":
return new Ferrari();
case "porsche":
return new Porsche();
default:
throw new RuntimeException("无此车辆");
}
}
}
- 收到客户订单,开始生产
/**
* 简单工厂模式
*
*/
public class SimpleFactoryPattern {
public static void main(String[] args) {
// 第一天开法拉利
String carType = "ferrari";
CarFactory.getCar(carType).run();
// 第二天开保时捷
carType = "porsche";
CarFactory.getCar(carType).run();
System.out.println("Happiness is so simple");
}
}
- 执行结果:
5、工厂模式优缺点
优点:
-
封装
简单工厂帮助我们实现组件的封装,让组件外部实现面向接口编程 -
解耦
通过简单工厂,客户端和具体的实现逻辑解耦
缺点:
-
违反开闭原则
-
增加扩展的复杂度
添加新产品需要修改工厂逻辑,在产品类型较多时,造成工厂过于臃肿,增加复杂度。
6、何时选用简单工厂
- 封装具体实现,让客户端通过接口操作具体实现。
- 想把创建对象的具体职责集中管理和控制
7、简单工厂模式的应用
- 简单工厂模式在Java中的应用
public static Calendar getInstance()
{
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}
public static Calendar getInstance(TimeZone zone,
Locale aLocale)
{
return createCalendar(zone, aLocale);
}
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 no known calendar type is explicitly specified,
// perform the traditional way to create a Calendar:
// create a BuddhistCalendar for th_TH locale,
// a JapaneseImperialCalendar for ja_JP_JP locale, or
// a GregorianCalendar for any other locales.
// NOTE: The language, country and variant strings are interned.
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;
}
mark,欢迎评论交流