简单工厂模式
# 一、概述
简单工厂(Simple Factory)模式也称作静态工厂方法(Static Factory Method)模式,其核心是由一个工厂根据不同条件生产不同类型的对象。从命名上来看就知道这种模式足够简单
# 1.1 解决了什么问题
假设有一家工厂,最开始是为生产普通电视投建的,后来又接到了生产投影仪、激光电视的需求。如果要重新选址、建厂肯定是不合理的,最快的方式就是在现有工厂内部重新开辟一条流水线。然后工厂根据不同的订单需求安排不同的流水线进行生产。
# 1.2 解决方案
使用同一个工厂类,提供静态工厂方法,但是通过不同的参数来决定由哪一条流水线生产。
# 二、实现方式
# 2.1 角色
简单工厂模式中有三个主要角色:
- 工厂类:本模式的核心,主要的业务逻辑可能在这里实现,并通过参数创建不同的具体产品角色。
- 抽象产品:指具体产品继承的父类或实现的接口。
- 具体产品:工厂类所创建的具体产品对象。
# 2.2 代码
定义产品类:
/**
* 要生产的产品抽象类,具体的产品需要集成自此类
*/
abstract class Product {
public abstract void music();
public abstract void play();
}
/**
* 电视类
*/
class Television extends Product {
@Override
public void music() {
System.out.println("电视在放音乐");
}
@Override
public void play() {
System.out.println("电视在放电影");
}
}
/**
* 投影类
*/
class Projector extends Product {
@Override
public void music() {
System.out.println("投影仪在放音乐");
}
@Override
public void play() {
System.out.println("投影仪在放电影");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
创建静态工厂:
public class SimpleFactoryTest {
public static void main(String[] args) {
String productType = "PJ";
Product product = SimpleFactory.createProduct(productType);
product.play();
product.music();
}
}
class SimpleFactory {
public static Product createProduct(String productType) {
Product product;
if (productType.equals("TV")) {
product = new Television();
} else if (productType.equals("PJ")) {
product = new Projector();
} else {
throw new IllegalArgumentException();
}
return product;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 三、源码中的应用
# 3.1 java.util.Calendar
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {
public static Calendar getInstance()
{
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}
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;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# 3.2 java.text.NumberFormat
public abstract class NumberFormat extends Format {
public final static NumberFormat getInstance() {
return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
}
private static NumberFormat getInstance(Locale desiredLocale,
int choice) {
LocaleProviderAdapter adapter;
adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class,
desiredLocale);
NumberFormat numberFormat = getInstance(adapter, desiredLocale, choice);
if (numberFormat == null) {
numberFormat = getInstance(LocaleProviderAdapter.forJRE(),
desiredLocale, choice);
}
return numberFormat;
}
private static NumberFormat getInstance(LocaleProviderAdapter adapter,
Locale locale, int choice) {
NumberFormatProvider provider = adapter.getNumberFormatProvider();
NumberFormat numberFormat = null;
switch (choice) {
case NUMBERSTYLE:
numberFormat = provider.getNumberInstance(locale);
break;
case PERCENTSTYLE:
numberFormat = provider.getPercentInstance(locale);
break;
case CURRENCYSTYLE:
numberFormat = provider.getCurrencyInstance(locale);
break;
case INTEGERSTYLE:
numberFormat = provider.getIntegerInstance(locale);
break;
}
return numberFormat;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
上次更新: 2023/11/01, 03:11:44