设计模式之工厂模式

定义

1
2
工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

优点

1
2
3
4
5
6
遵循开闭原则:可以在不修改现有代码的情况下引入新的产品类型。
遵循单一职责原则:将产品创建代码放在程序的单一位置,使得代码更容易维护。
松耦合:工厂方法模式将产品的使用和产品的创建分离,使它们互相独立、互不影响。
客户端代码与具体产品解耦:客户端只需要知道抽象产品类,而不需要知道具体产品类。
灵活性高:可以通过继承的方式增加新的工厂,非常容易扩展。
可以实现平行类层次结构:每个工厂对应一个产品,形成一个完整的平行结构。

缺点

1
2
3
4
5
6
代码复杂度增加:相比于简单工厂模式,工厂方法模式需要更多的类和接口。
可能导致类的个数增加:每增加一个产品就需要增加一个具体工厂类。
抽象工厂和具体工厂的角色没有太多变化:如果只有一个具体工厂类,那么就没有必要使用工厂方法模式。
客户端代码需要处理选择合适的工厂类:虽然客户端不需要知道具体的产品类,但仍需要知道每个工厂生产什么样的产品。
难以支持新种类的产品:如果需要添加一个新种类的产品,可能需要修改抽象工厂接口,这会影响到所有的具体工厂类。
可能会增加系统的抽象性和理解难度:对于简单的应用来说,使用工厂方法可能会显得过度设计。

代码解释

1
2
3
4
5
VolunteerService 接口定义了所有志愿服务必须实现的 provideHelp() 方法。
HomeCleaning 和 Companionship 是具体的志愿服务类,实现了 VolunteerService 接口。
VolunteerOrganization 接口定义了 createVolunteerService() 方法,这是工厂方法。
HomeHelpOrganization 和 SocialCareOrganization 是具体的志愿者机构类,它们实现了 VolunteerOrganization 接口,负责创建各自的具体志愿服务。
在客户端代码中,我们使用具体的志愿者机构来创建志愿服务,而不直接实例化服务类。

代码

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
// 志愿服务接口
interface VolunteerService {
void provideHelp();
}

// 具体志愿服务:家庭清洁
class HomeCleaning implements VolunteerService {
@Override
public void provideHelp() {
System.out.println("提供家庭清洁服务");
}
}

// 具体志愿服务:陪伴聊天
class Companionship implements VolunteerService {
@Override
public void provideHelp() {
System.out.println("提供陪伴聊天服务");
}
}

// 志愿者机构接口
interface VolunteerOrganization {
VolunteerService createVolunteerService();
}

// 具体志愿者机构:家庭帮助组织
class HomeHelpOrganization implements VolunteerOrganization {
@Override
public VolunteerService createVolunteerService() {
return new HomeCleaning();
}
}

// 具体志愿者机构:社交关怀组织
class SocialCareOrganization implements VolunteerOrganization {
@Override
public VolunteerService createVolunteerService() {
return new Companionship();
}
}

// 客户端代码
public class ElderlySupport {
public static void main(String[] args) {
VolunteerOrganization homeHelp = new HomeHelpOrganization();
VolunteerService homeCleaningService = homeHelp.createVolunteerService();
homeCleaningService.provideHelp();

VolunteerOrganization socialCare = new SocialCareOrganization();
VolunteerService companionshipService = socialCare.createVolunteerService();
companionshipService.provideHelp();
}
}

进阶【骚操作-反射】

代码解释

1
2
3
4
5
6
7
修改后的版本使用了反射来创建 VolunteerService 实例。
主要的变化包括:
移除了具体的 VolunteerOrganization 实现类(HomeHelpOrganization 和 SocialCareOrganization)。
新增了一个通用的 ReflectiveVolunteerOrganization 类,它使用反射来创建 VolunteerService 实例。
ReflectiveVolunteerOrganization 类的构造函数接受一个 Class 对象,用于指定要创建的 VolunteerService 类型。
createVolunteerService 方法使用反射来创建指定类型的实例。
在 main 方法中,现在使用 ReflectiveVolunteerOrganization 来创建 VolunteerService 实例,并传入相应的 Class 对象。
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
58
59
60
61
62
package FactoryClass;

import java.lang.reflect.Constructor;

// 志愿服务接口
interface VolunteerServiceRef {
void provideHelpRef();
}

// 具体志愿服务:家庭清洁
class HomeCleaningRef implements VolunteerServiceRef {
@Override
public void provideHelpRef() {
System.out.println("提供家庭清洁服务");
}
}

// 具体志愿服务:陪伴聊天
class CompanionshipRef implements VolunteerServiceRef {
@Override
public void provideHelpRef() {
System.out.println("提供陪伴聊天服务");
}
}

// 志愿者机构接口
interface VolunteerOrganizationRef {
VolunteerServiceRef createVolunteerServiceRef() throws Exception;
}

// 通用志愿者机构实现
class ReflectiveVolunteerOrganization implements VolunteerOrganizationRef {
private Class<? extends VolunteerServiceRef> serviceClass;

public ReflectiveVolunteerOrganization(Class<? extends VolunteerServiceRef> serviceClass) {
this.serviceClass = serviceClass;
}

@Override
public VolunteerServiceRef createVolunteerServiceRef() throws Exception {
Constructor<? extends VolunteerServiceRef> constructor = serviceClass.getDeclaredConstructor();
return constructor.newInstance();
}
}

// 客户端代码
public class ElderlySupportReflection {
public static void main(String[] args) {
try {
VolunteerOrganizationRef homeHelp = new ReflectiveVolunteerOrganization(HomeCleaningRef.class);
VolunteerServiceRef homeCleaningService = homeHelp.createVolunteerServiceRef();
homeCleaningService.provideHelpRef();

VolunteerOrganizationRef socialCare = new ReflectiveVolunteerOrganization(CompanionshipRef.class);
VolunteerServiceRef companionshipService = socialCare.createVolunteerServiceRef();
companionshipService.provideHelpRef();
} catch (Exception e) {
e.printStackTrace();
}
}
}