在软件开发中,我们经常会遇到创建对象的需求。通常情况下,我们可以直接使用 new
关键字来创建对象,但在某些情况下,直接创建对象可能会导致代码的耦合度增加,不利于代码的扩展和维护。这时候,工厂模式就可以发挥作用了。
例如:
- 类耦合: 客户端代码直接引用了具体的类,这使得客户端代码依赖于具体类的实现,从而增加了类之间的耦合度。
- 模块耦合: 客户端代码依赖于特定的实现模块,如果需要替换或修改该模块,则需要修改客户端代码。
- 依赖耦合: 客户端代码依赖于具体类的构造函数参数或方法参数,从而增加了与具体类的依赖关系。
什么是工厂模式?
工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式,而不需要暴露对象的创建逻辑。简单来说,工厂模式就是将对象的创建过程封装起来,客户端不需要关心对象是如何创建的,只需要通过工厂来获取所需的对象即可。
工厂模式的优点
- 降低耦合度: 工厂模式将对象的创建过程与客户端解耦,客户端不需要知道对象的具体创建细节,只需要知道如何获取对象即可。
- 提高代码复用性: 由于对象的创建过程被封装在工厂中,所以可以在多个地方重复使用相同的创建逻辑。
- 更好的扩展性: 当需要添加新的产品类型时,只需要修改工厂类即可,不需要修改客户端代码,符合开闭原则。
工厂模式的类型
工厂模式通常分为三种类型:简单工厂模式、工厂方法模式和抽象工厂模式。
- 简单工厂模式(Simple Factory Pattern): 简单工厂模式是工厂模式中最简单的一种,它通过一个工厂类来负责创建所有的产品对象。客户端只需要知道工厂类即可,不需要关心具体的产品类。设计类图:
- 工厂方法模式(Factory Method Pattern): 工厂方法模式定义了一个用于创建对象的接口,由子类来决定实例化哪一个类。客户端通过调用工厂方法来创建所需的对象,从而实现了解耦。设计类图:
- 抽象工厂模式(Abstract Factory Pattern): 抽象工厂模式提供了一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。它是工厂方法模式的扩展,通过定义一个工厂接口来创建一系列相关的产品。设计类图:
-
三者使用场景:
实现一个简单工厂模式示例
让我们通过一个简单的示例来说明简单工厂模式的具体实现。假设我们有一个形状接口 Shape
和其实现类 Circle
和 Rectangle
,我们希望通过一个工厂类 ShapeFactory
来创建这些形状对象。
// 形状接口
interface Shape {
void draw();
}
// 圆形类
class Circle implements Shape {
@Override
public void draw() {
System.out.println("绘制圆形");
}
}
// 矩形类
class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("绘制矩形");
}
}
// 形状工厂类
class ShapeFactory {
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();
}
return null;
}
}
// 客户端代码
public class Main {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
// 获取圆形对象,并调用绘制方法
Shape circle = shapeFactory.getShape("Circle");
circle.draw();
// 获取矩形对象,并调用绘制方法
Shape rectangle = shapeFactory.getShape("Rectangle");
rectangle.draw();
}
}
实现一个工厂方法模式示例
首先定义一个抽象类产品接口和两个具体产品的实现。再定义一个抽象工厂接口和两个实现工厂。
抽象类产品接口:
//抽象产品类
public interface Produce {
//产品描述
void operation();
}
//产品A
public class ProduceA implements Produce{
@Override
public void operation() {
System.out.println("具体产品A描述");
}
}
//产品B
public class ProduceB implements Produce{
@Override
public void operation() {
System.out.println("具体产品B描述");
}
}
抽象工厂实现
//工厂创建产品的接口
public interface Factory {
Produce createProduct();
}
//工厂A
public class FactoryA implements Factory{
@Override
public Produce createProduct() {
return new ProduceA();
}
}
//工厂B
public class FactoryB implements Factory{
@Override
public Produce createProduct() {
return new ProduceB();
}
}
实现一个抽象工厂模式模式示例
实现结构:
产品族A:
//抽象类产品族A
public interface AbstractProductA {
void operationA();
}
//产品A具体实现
public class ConcreteProductA1 implements AbstractProductA{
@Override
public void operationA() {
System.out.println("ConcreteProductA1 Operation");
}
}
//产品A具体实现
public class ConcreteProductA2 implements AbstractProductA{
@Override
public void operationA() {
System.out.println("ConcreteProductA2 operation");
}
}
产品族B:
//抽象类产品族B
public interface AbstractProductB {
void operationB();
}
//产品B具体实现
public class ConcreteProductB1 implements AbstractProductB{
@Override
public void operationB() {
System.out.println("ConcreteProductB1 operation");
}
}
//产品B具体实现
public class ConcreteProductB2 implements AbstractProductB{
@Override
public void operationB() {
System.out.println("ConcreteProductB2 operation");
}
}
抽象工厂:
//抽象类工厂
public interface AbstractFactory {
AbstractProductA createProductA();
AbstractProductB createProductB();
}
//工厂A实现
public class ConcreteFactory1 implements AbstractFactory{
@Override
public AbstractProductA createProductA() {
return new ConcreteProductA1();
}
@Override
public AbstractProductB createProductB() {
return new ConcreteProductB1();
}
}
//工厂B实现
public class ConcreteFactory2 implements AbstractFactory{
@Override
public AbstractProductA createProductA() {
return new ConcreteProductA2();
}
@Override
public AbstractProductB createProductB() {
return new ConcreteProductB2();
}
}
不同工厂模式对比:
创建及结构对比:
优缺点对比:
总结
工厂模式是一种常用的设计模式,它可以帮助我们更好地管理对象的创建过程,降低代码的耦合度,提高代码的复用性和扩展性。在实际项目中,根据不同的需求可以选择不同类型的工厂模式来创建对象,从而更好地满足项目的需求。