0%

设计模式-抽象工厂

抽象工厂, 将工厂抽象出来

工厂方法模式和抽象工厂模式都是创建型设计模式,它们的主要区别在于所创建的对象范围不同。

工厂方法模式(Factory Method)通过让子类实现工厂接口,来决定具体应该创建哪一个产品类的实例对象。它允许我们在不改变现有代码基础上添加新的产品类型,并且可以将具体产品的实现与调用方分离开来。

抽象工厂模式(Abstract Factory)与工厂方法模式类似,也是用于创建一系列相关的对象。不同之处在于,抽象工厂是针对多个产品族而言的,即每个工厂可以创建多种不同类型的产品。这样的话,抽象工厂为创建一组相关或独立的对象提供了一种方式。

工厂方法模式通常只针对一个抽象产品类进行创建,而抽象工厂模式则需要针对多种抽象产品进行创建。

示例为实现切换不同数据库

原程序

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
//User表
class User
{
private int id;
public int ID
{
get{return id;}
set{id = ID;}
}
private string name;
public string Name
{
get{return name;}
set{name = value;}
}
}
//SQLServer操作User表
class SqlServerUser
{
public void Insert(User user)
{
Console.WriteLine("在SQLServer中增加一条记录");
}
public User GerUser(int id)
{
Console.WriteLine("在SQLServer中根据ID获取User表的一条记录")
return null;
}
}
//Client
User user = new User();
SqlServerUser su = new SqlServerUser();//--此处定义了必须是SQL无法直接替换其他类型数据库
su.Insert(user);
su.GetUser(1);

工厂方法

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 IUser
{
void Insert(User user);
User GetUser(int id);
}
class SqlServerUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在SQLServer中增加一条记录");
}
public User GerUser(int id)
{
Console.WriteLine("在SQLServer中根据ID获取User表的一条记录")
return null;
}
}
class AccessUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Access中增加一条记录");
}
public User GerUser(int id)
{
Console.WriteLine("在Access中根据ID获取User表的一条记录")
return null;
}
}
interface IFactory
{
IUser CreateUser();
}
class SqlserverFactory : IFactory
{
public IUser CreateUser()
{
return new SqlserverUser();
}
}
class AccessFactory : IFactory
{
public IUser CreateUser()
{
return new AccessUser();
}
}
//Client
User user = new User();
IFactory factory = new SqlserverFactory();
IUser iu = factory.CreateUser();

iu.Insert(user);
iu.GetUser(1);

抽象工厂

工厂方法模式通常只针对一个抽象产品类进行创建,而抽象工厂模式则需要针对多种抽象产品进行创建。

随着表的增多(比如增加一个Department部门表),
需要增加很多类(IDepartment, SqlserverDepartment, AccessDepartment),
还要修改很多类(IFactory, SqlserverFactory, AccessFactory)增加接口函数

简单工厂优化抽象工厂

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
class DataAccess
{
private static readonly string db = "Sqlserver";
public static IUser CreateUser()
{
IUser user = null;
switch(db)
{
case "Sqlserver":
user = new SqlserverUser();
break;
case "Access":
user = new AccessUser();
break;
}
return user;
}
public static IDepartment CreateDepartment()
{
IDepartment deparement = null;
switch(db)
{
case "Sqlserver":
deparement = new SqlserverDeparement();
break;
case "Access":
deparement = new AccessDeparement();
break;
}
return deparement;
}
}
//Client
User user = new User();
Department department = new Department();

IUser iu = DataAccess.CreateUser();
iu.Insert(user);
iu.GetUser(1);

IDepartment id = DataAccess.CreateDepartment();
id.Insert(department);
id.GetDepartment(1);

简单工厂去除了工厂类, 比如但若是增加Oracle数据库的访问, 抽象工厂只需要增加OracleFactory, 简单工厂却需要更改DataAccess类中的case

反射+抽象工厂

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
using System.Reflection;

class DataAccess
{
private static readonly string assemblyName = "抽象工厂模式";//程序集名
private static readonly string db = "Sqlserver";//--可放在配置文件中实现真正的开闭原则
public static IUser CreateUser()
{
string className = assemblyName + "." + db + "User";
return (IUser)Assembly.Load(assemblyName).CreateInstance(className);
}
public static IDepartment CreateDepartment()
{
string className = assemblyName + "." + db + "Department";
return (IDepartment)Assembly.Load(assemblyName).CreateInstance(className);
}
}
//Client
User user = new User();
Department department = new Department();

IUser iu = DataAccess.CreateUser();
iu.Insert(user);
iu.GetUser(1);

IDepartment id = DataAccess.CreateDepartment();
id.Insert(department);
id.GetDepartment(1);
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//java抽象工厂示例

//为形状创建一个接口
public interface Shape {
void draw();
}
//创建实现接口的实体类
public class Rectangle implements Shape {

@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
public class Square implements Shape {

@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
public class Circle implements Shape {

@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
//为颜色创建一个接口
public interface Color {
void fill();
}
//创建实现接口的实体类
public class Red implements Color {

@Override
public void fill() {
System.out.println("Inside Red::fill() method.");
}
}
public class Green implements Color {

@Override
public void fill() {
System.out.println("Inside Green::fill() method.");
}
}
public class Blue implements Color {

@Override
public void fill() {
System.out.println("Inside Blue::fill() method.");
}
}
//为 Color 和 Shape 对象创建抽象类来获取工厂
public abstract class AbstractFactory {
public abstract Color getColor(String color);
public abstract Shape getShape(String shape);
}
//创建扩展了 AbstractFactory 的工厂类,基于给定的信息生成实体类的对象
public class ShapeFactory extends AbstractFactory {

@Override
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}

@Override
public Color getColor(String color) {
return null;
}
}
public class ColorFactory extends AbstractFactory {

@Override
public Shape getShape(String shapeType){
return null;
}

@Override
public Color getColor(String color) {
if(color == null){
return null;
}
if(color.equalsIgnoreCase("RED")){
return new Red();
} else if(color.equalsIgnoreCase("GREEN")){
return new Green();
} else if(color.equalsIgnoreCase("BLUE")){
return new Blue();
}
return null;
}
}
//创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂
public class FactoryProducer {
public static AbstractFactory getFactory(String choice){
if(choice.equalsIgnoreCase("SHAPE")){
return new ShapeFactory();
} else if(choice.equalsIgnoreCase("COLOR")){
return new ColorFactory();
}
return null;
}
}
//Client
public class AbstractFactoryPatternDemo {
public static void main(String[] args) {

//获取形状工厂
AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");

//获取形状为 Circle 的对象
Shape shape1 = shapeFactory.getShape("CIRCLE");

//调用 Circle 的 draw 方法
shape1.draw();

//获取形状为 Rectangle 的对象
Shape shape2 = shapeFactory.getShape("RECTANGLE");

//调用 Rectangle 的 draw 方法
shape2.draw();

//获取形状为 Square 的对象
Shape shape3 = shapeFactory.getShape("SQUARE");

//调用 Square 的 draw 方法
shape3.draw();

//获取颜色工厂
AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");

//获取颜色为 Red 的对象
Color color1 = colorFactory.getColor("RED");

//调用 Red 的 fill 方法
color1.fill();

//获取颜色为 Green 的对象
Color color2 = colorFactory.getColor("GREEN");

//调用 Green 的 fill 方法
color2.fill();

//获取颜色为 Blue 的对象
Color color3 = colorFactory.getColor("BLUE");

//调用 Blue 的 fill 方法
color3.fill();
}
}
/*
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside Red::fill() method.
Inside Green::fill() method.
Inside Blue::fill() method.
*/