工厂模式简单介绍
大家好,我是IT修真院成都分院第13期java学员。
今天给大家分享一下关于java工厂模式的相关知识。
1.背景介绍
创建新对象最简单的办法是使用new关键字和具体类。在任何需要生成复杂对象的地方,都可以使用工厂方法模式。构造函数有很多参数的情况,或者一个项目中需要在很多地方需要这个对象,那就比较复杂了,直接用new创建对象就不太合理了,不利于项目管理和变更,这样做可以降低代码的重复率和耦合性。创建的对象只需要在工厂类中进行管理即可;工厂模式(Factory Pattern)是Java中最常用的设计模式之一。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
2.知识剖析
2.1使用目的
定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
2.2优点
(1)一个调用者想创建一个对象,只要知道其名称就可以了。
(2)扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
(3)屏蔽产品的具体实现,调用者只关心产品的接口。
2.3缺点
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
2.4使用场景
任何需要生成复杂对象的地方,就可以运用工厂模式来进行创建,对项目整体起一个解耦作用。
3.常见问题
4.解决方案
5.编码实战
我这里主要用形状类来进行初步理解:
首先创建一个 Shape 接口和实现 Shape 接口的实现类;
然后再定义工厂类 ShapeFactory;
最后使用该工厂,通过传递类型信息来获取实体类的对象。
Shape 接口:
public interface Shape {
void draw();
}Rectangle实现类(具体的产品类):
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("调用接口中draw()方法画矩形");
}
}ShapeFactory工厂类:
//创建一个工厂,生成基于给定信息的实体类的对象
public class ShapeFactory {
//定义 getShape 方法获取形状类型的对象
public Shape getShape(String shapeType) {
if (shapeType == null) {
return null;
}
//equalsIgnoreCase和equals唯一区分就是前者忽略字符串大小写
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;
}
}通过调用工厂类中getShape方法,获取具体的产品类:
public class FactoryDemo {
public static void main(String[] args) {
//实例化Shape工厂
ShapeFactory shapeFactory = new ShapeFactory();
//获取 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();
}
}执行结果:

6.扩展思考
工厂模式按照《Java与模式》中的提法分为三类:
- 简单工厂模式(Simple Factory)
- 工厂方法模式(Factory Method)
- 抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。还有一种分类法,就是将简单工厂模式看为工厂方法模式的一种特例,两个归为一类。最大的区别就是是否只有一个等级结构,具体描述请看文末参考文献
简单来说,第一种扩展性差,不同的产品需要额外不同参数的时候不支持; 而使用工厂方法模式足以应付我们可能遇到的大部分业务需求。但是当产品种类非常多时,就会出现大量的与之对应的工厂类,所以在这种情况下使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类:即对于产品树上类似的种类使用简单工厂模式来实现。
总结:
无论是什么工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,在使用时,我们不必去在意这个模式到底是工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。有时候你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。
7.参考文献
https://www.cnblogs.com/zailushang1996/p/8601808.html
https://blog.csdn.net/southjeff/article/details/79877412
https://blog.csdn.net/bingducaijun/article/details/78686314
8.更多讨论
1、什么情况下我们使用简单工厂模式呢?
答:就是我们需要获取的对象参数比较少的时候,就可以使用简单工厂模式了,简单工厂模式只有一个工厂类,产品类单一,简单的情况就比较适合用这种方法进行对象的获取。
2、说一说工厂方法模式和抽象工厂模式的区别?
答:工厂方法模式:一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
3、工厂方法模式的要素有哪些?
提供一个产品类的接口。产品类均要实现这个接口(也可以是abstract类,即抽象产品)。
提供一个工厂类的接口。工厂类均要实现这个接口(即抽象工厂)。
由工厂实现类创建产品类的实例。工厂实现类应有一个方法,用来实例化产品类。
作者:行者著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。