工厂模式是一种对象创建型模式,它提供了一种创建对象的最佳实践。在工厂模式中,我们在创建对象时不使用 new 关键字,而是通过调用工厂方法来创建对象。工厂方法是一种在子类中定义的方法,该方法负责实例化对象。工厂方法可以返回不同的对象类型,因此工厂模式可以创建一组相关或不相关的对象。这样就可以将对象的创建和使用解耦。
简介
工厂模式有三种类型:简单工厂模式、工厂方法模式和抽象工厂模式。
- 简单工厂模式是最基本的工厂模式,它通过一个工厂类来创建所有需要的对象。简单工厂模式将对象的创建逻辑封装在一个工厂类中,客户端通过调用工厂类的静态方法来创建对象。
- 工厂方法模式是对简单工厂模式的改进,它定义了一个用于创建对象的接口或抽象类,让子类决定实例化哪一个类。工厂方法模式将对象的创建过程延迟到子类中进行,从而实现了开闭原则。
- 抽象工厂模式是对工厂方法模式的扩展,它提供了一个创建一系列相关或相互依赖对象的接口或抽象类,而无需指定它们具体的类。抽象工厂模式可以创建多个产品族,每个产品族由多个具体产品组成。
好处和坏处
工厂模式的好处有:
- 可以将对象的创建和使用解耦,从而提高系统的灵活性和可维护性。
- 工厂模式可以隐藏对象的创建细节,使客户端只关心对象的使用,从而降低系统的复杂度。
- 工厂模式可以实现开闭原则,当需要增加新的产品时,只需要增加相应的工厂类即可,无需修改原有代码。
工厂模式的坏处有:
- 工厂模式会增加系统中类的数量,当产品类型较多时,会导致系统过于庞大和复杂。
- 工厂模式需要引入抽象层,这会增加系统的抽象性和理解难度。
- 工厂模式可能会导致类层次过多,增加系统设计难度。
应用场景
工厂模式适用于以下场景:
- 当需要创建的对象类型较多时,可以使用工厂模式来避免大量的new操作。
- 当需要根据不同的条件或参数来创建不同类型的对象时,可以使用工厂模式来实现条件分支的替代。
- 当需要将对象的创建和使用解耦时,可以使用工厂模式来实现依赖倒置原则。
Java代码示例
以下是使用Java实现的三种工厂模式的代码示例。
简单工厂模式
假设我们有一个 Shape 接口和三个实现类 Circle、Rectangle 和 Square,我们想要根据给定的形状类型来创建相应的对象。
首先,我们定义一个 Shape 接口和三个实现类:
java
复制代码
// Shape接口 public interface Shape { void draw(); } // Circle类 public class Circle implements Shape { @Override public void draw() { System.out.println("Draw a circle"); } } // Rectangle类 public class Rectangle implements Shape { @Override public void draw() { System.out.println("Draw a rectangle"); } } // Square类 public class Square implements Shape { @Override public void draw() { System.out.println("Draw a square"); }
然后,我们定义一个 ShapeFactory 类,它有一个静态方法 createShape,根据给定的形状类型来返回相应的对象:
java
复制代码
// ShapeFactory类 public class ShapeFactory { // 静态方法createShape public static Shape createShape(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; } }
最后,我们可以在客户端使用 ShapeFactory 来创建不同类型的形状对象:
java
复制代码
// 客户端 public class Client { public static void main(String[] args) { // 创建一个圆形对象 Shape circle = ShapeFactory.createShape("circle"); // 调用圆形对象的draw方法 circle.draw(); // 创建一个矩形对象 Shape rectangle = ShapeFactory.createShape("rectangle"); // 调用矩形对象的draw方法 rectangle.draw(); // 创建一个正方形对象 Shape square = ShapeFactory.createShape("square"); // 调用正方形对象的draw方法 square.draw(); } }
输出结果如下:
css
复制代码
Draw a circle Draw a rectangle Draw a square
工厂方法模式
假设我们还是有一个Shape接口和三个实现类Circle、Rectangle和Square,我们想要根据给定的形状类型来创建相应的对象,但是我们不想使用一个工厂类来创建所有类型的对象,而是让每个形状类自己定义一个工厂类来创建自己的对象。
首先,我们定义一个Shape接口和三个实现类,这里和简单工厂模式一样:
java
复制代码
// Shape接口 public interface Shape { void draw(); } // Circle类 public class Circle implements Shape { @Override public void draw() { System.out.println("Draw a circle"); } } // Rectangle类 public class Rectangle implements Shape { @Override public void draw() { System.out.println("Draw a rectangle"); } } // Square类 public class Square implements Shape { @Override public void draw() { System.out.println("Draw a square"); } }
然后,我们定义一个抽象工厂类ShapeFactory,它有一个抽象方法createShape,返回一个Shape对象:
java
复制代码
// 抽象工厂类ShapeFactory public abstract class ShapeFactory { // 抽象方法createShape public abstract Shape createShape(); } 接着,我们让每个形状类都定义一个工厂类,继承自ShapeFactory,并实现createShape方法,返回自己的对象: java 复制代码 // CircleFactory类 public class CircleFactory extends ShapeFactory { @Override public Shape createShape() { return new Circle(); } } // RectangleFactory类 public class RectangleFactory extends ShapeFactory { @Override public Shape createShape() { return new Rectangle(); } } // SquareFactory类 public class SquareFactory extends ShapeFactory { @Override public Shape createShape() { return new Square(); } }
最后,我们可以在客户端使用不同的工厂类来创建不同类型的形状对象:
java
复制代码
// 客户端 public class Client { public static void main(String[] args) { // 创建一个圆形工厂对象 ShapeFactory circleFactory = new CircleFactory(); // 通过圆形工厂对象创建一个圆形对象 Shape circle = circleFactory.createShape(); // 调用圆形对象的draw方法 circle.draw(); // 创建一个矩形工厂对象 ShapeFactory rectangleFactory = new RectangleFactory(); // 通过矩形工厂对象创建一个矩形对象 Shape rectangle = rectangleFactory.createShape(); // 调用矩形对象的draw方法 rectangle.draw(); // 创建一个正方形工厂对象 ShapeFactory squareFactory = new SquareFactory(); // 通过正方形工厂对象创建一个正方形对象 Shape square = squareFactory.createShape(); // 调用正方形对象的draw方法 square.draw(); } }
输出结果如下:
css
复制代码
Draw a circle Draw a rectangle Draw a square