工厂模式
- [1. 引言](#1. 引言)
- [2. 什么是工厂模式?](#2. 什么是工厂模式?)
- [3. 简单工厂模式](#3. 简单工厂模式)
- [4. 工厂方法模式](#4. 工厂方法模式)
- [5. 抽象工厂模式](#5. 抽象工厂模式)
- [6. 工厂模式的优势](#6. 工厂模式的优势)
- [7. 工厂模式的应用场景](#7. 工厂模式的应用场景)
- [8. 实际应用示例:数据库连接工厂](#8. 实际应用示例:数据库连接工厂)
- [9. 结论](#9. 结论)
1. 引言
在软件开发中,创建对象是一个常见但有时复杂的任务。工厂模式作为一种创建型设计模式,提供了一种优雅的方式来处理对象的创建。
2. 什么是工厂模式?
工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。
3. 简单工厂模式
汽车制造示例代码:
java
// 汽车接口
interface Car {
void drive();
}
// 轿车
class Sedan implements Car {
@Override
public void drive() {
System.out.println("驾驶轿车");
}
}
java
// SUV
class SUV implements Car {
@Override
public void drive() {
System.out.println("驾驶SUV");
}
}
java
// 跑车
class SportsCar implements Car {
@Override
public void drive() {
System.out.println("驾驶跑车");
}
}
java
// 简单汽车工厂
class SimpleCarFactory {
public Car createCar(String type) {
switch (type.toLowerCase()) {
case "sedan":
return new Sedan();
case "suv":
return new SUV();
case "sportscar":
return new SportsCar();
default:
throw new IllegalArgumentException("未知的汽车类型: " + type);
}
}
}
java
// 汽车经销商
class CarDealer {
private SimpleCarFactory factory;
public CarDealer(SimpleCarFactory factory) {
this.factory = factory;
}
public Car orderCar(String type) {
Car car = factory.createCar(type);
System.out.println("订购了一辆" + type);
return car;
}
}
java
// 客户端代码
public class CarExample {
public static void main(String[] args) {
SimpleCarFactory factory = new SimpleCarFactory();
CarDealer dealer = new CarDealer(factory);
Car sedan = dealer.orderCar("sedan");
sedan.drive();
Car suv = dealer.orderCar("suv");
suv.drive();
Car sportsCar = dealer.orderCar("sportscar");
sportsCar.drive();
}
}
在这个简单工厂模式中,SimpleCarFactory 负责创建不同类型的汽车,而 CarDealer 使用这个工厂来获取汽车实例。
简单工厂模式虽然简单,但违反了开闭原则,因为每次添加新产品都需要修改工厂类。
4. 工厂方法模式
工厂方法模式是对简单工厂模式的进一步抽象和推广。
现在,假设有不同的汽车制造商,每个制造商都有自己的生产线。
java
// 抽象汽车制造商
abstract class CarManufacturer {
public Car orderCar(String type) {
Car car = createCar(type);
System.out.println("生产了一辆" + type);
return car;
}
// 工厂方法
protected abstract Car createCar(String type);
}
java
// 丰田制造商
class ToyotaManufacturer extends CarManufacturer {
@Override
protected Car createCar(String type) {
switch (type.toLowerCase()) {
case "sedan":
return new ToyotaSedan();
case "suv":
return new ToyotaSUV();
default:
throw new IllegalArgumentException("丰田不生产这种类型的汽车: " + type);
}
}
}
java
// 特斯拉制造商
class TeslaManufacturer extends CarManufacturer {
@Override
protected Car createCar(String type) {
switch (type.toLowerCase()) {
case "sedan":
return new TeslaSedan();
case "suv":
return new TeslaSUV();
default:
throw new IllegalArgumentException("特斯拉不生产这种类型的汽车: " + type);
}
}
}
java
// 丰田轿车
class ToyotaSedan implements Car {
@Override
public void drive() {
System.out.println("驾驶丰田轿车");
}
}
java
// 丰田SUV
class ToyotaSUV implements Car {
@Override
public void drive() {
System.out.println("驾驶丰田SUV");
}
}
java
// 特斯拉轿车
class TeslaSedan implements Car {
@Override
public void drive() {
System.out.println("驾驶特斯拉轿车");
}
}
java
// 特斯拉SUV
class TeslaSUV implements Car {
@Override
public void drive() {
System.out.println("驾驶特斯拉SUV");
}
}
java
// 客户端代码
public class CarExample {
public static void main(String[] args) {
CarManufacturer toyota = new ToyotaManufacturer();
CarManufacturer tesla = new TeslaManufacturer();
Car toyotaSedan = toyota.orderCar("sedan");
toyotaSedan.drive();
Car teslaSUV = tesla.orderCar("suv");
teslaSUV.drive();
}
}
在这个工厂方法模式中,每个具体的汽车制造商都实现了自己的 createCar 方法,允许不同的制造商创建自己品牌的汽车。
这些例子展示了工厂模式如何将对象的创建与使用分离,提供了一种灵活的方式来创建不同类型的对象:
- 简单工厂模式适用于创建对象的逻辑相对简单的情况,如一个通用的汽车工厂。
- 工厂方法模式则更适合需要不同变体的情况,如不同品牌的汽车制造商。
工厂方法模式符合开闭原则,允许系统在不修改现有代码的情况下引入新的产品类型。
5. 抽象工厂模式
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
在这个例子中,将考虑不同类型的汽车部件(如引擎、轮胎)以及不同的汽车制造商。每个制造商都会生产这些部件的特定版本。
java
// 抽象产品 - 引擎
interface Engine {
void start();
}
java
// 抽象产品 - 轮胎
interface Tire {
void rotate();
}
java
// 具体产品 - 丰田引擎
class ToyotaEngine implements Engine {
@Override
public void start() {
System.out.println("丰田引擎启动");
}
}
java
// 具体产品 - 丰田轮胎
class ToyotaTire implements Tire {
@Override
public void rotate() {
System.out.println("丰田轮胎旋转");
}
}
java
// 具体产品 - 特斯拉引擎
class TeslaEngine implements Engine {
@Override
public void start() {
System.out.println("特斯拉电动引擎启动");
}
}
java
// 具体产品 - 特斯拉轮胎
class TeslaTire implements Tire {
@Override
public void rotate() {
System.out.println("特斯拉轮胎旋转");
}
}
java
// 抽象工厂
interface CarFactory {
Engine createEngine();
Tire createTire();
}
java
// 具体工厂 - 丰田工厂
class ToyotaFactory implements CarFactory {
@Override
public Engine createEngine() {
return new ToyotaEngine();
}
@Override
public Tire createTire() {
return new ToyotaTire();
}
}
java
// 具体工厂 - 特斯拉工厂
class TeslaFactory implements CarFactory {
@Override
public Engine createEngine() {
return new TeslaEngine();
}
@Override
public Tire createTire() {
return new TeslaTire();
}
}
java
// 汽车类
class Car {
private Engine engine;
private Tire tire;
public Car(CarFactory factory) {
engine = factory.createEngine();
tire = factory.createTire();
}
public void start() {
engine.start();
tire.rotate();
}
}
java
// 客户端代码
public class AbstractFactoryExample {
public static void main(String[] args) {
// 创建丰田汽车
CarFactory toyotaFactory = new ToyotaFactory();
Car toyotaCar = new Car(toyotaFactory);
System.out.println("启动丰田汽车:");
toyotaCar.start();
System.out.println();
// 创建特斯拉汽车
CarFactory teslaFactory = new TeslaFactory();
Car teslaCar = new Car(teslaFactory);
System.out.println("启动特斯拉汽车:");
teslaCar.start();
}
}
在这个抽象工厂模式的例子中:
- 定义了两个抽象产品接口: Engine 和 Tire。
- 对于每个制造商(丰田和特斯拉),创建了这些接口的具体实现。
- CarFactory 是抽象工厂接口,声明了创建引擎和轮胎的方法。
- ToyotaFactory 和 TeslaFactory 是具体的工厂,实现了 CarFactory 接口,负责创建各自品牌的引擎和轮胎。
- Car 类使用给定的工厂来创建它的部件(引擎和轮胎)。
- 在客户端代码中,可以使用不同的工厂来创建不同品牌的汽车,而无需关心具体的部件创建过程。
抽象工厂模式的优点:
- 它确保一个族的产品对象相互匹配。例如,丰田引擎总是与丰田轮胎配对,特斯拉引擎总是与特斯拉轮胎配对。
- 它将具体类的创建封装在具体工厂中,使客户端与具体类解耦。
- 添加新的产品族很容易。例如,如果想添加一个新的汽车制造商(如宝马),只需创建新的具体产品类和一个新的具体工厂类。
- 它促进了产品的一致性。当产品对象需要一起工作时,抽象工厂确保一个应用始终只使用同一个族的对象。
6. 工厂模式的优势
- 封装性好,创建对象的细节对客户端透明。
- 符合单一职责原则,将创建对象的职责从使用对象的代码中分离出来。
- 可扩展性强,遵循开闭原则。
7. 工厂模式的应用场景
- 当一个类不知道它所必须创建的对象的类时。
- 当一个类希望由它的子类来指定它所创建的对象时。
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化时。
8. 实际应用示例:数据库连接工厂
java
interface DatabaseConnection {
void connect();
void disconnect();
}
class MySQLConnection implements DatabaseConnection {
@Override
public void connect() {
System.out.println("Connecting to MySQL database");
}
@Override
public void disconnect() {
System.out.println("Disconnecting from MySQL database");
}
}
class PostgreSQLConnection implements DatabaseConnection {
@Override
public void connect() {
System.out.println("Connecting to PostgreSQL database");
}
@Override
public void disconnect() {
System.out.println("Disconnecting from PostgreSQL database");
}
}
interface DatabaseConnectionFactory {
DatabaseConnection createConnection();
}
class MySQLConnectionFactory implements DatabaseConnectionFactory {
@Override
public DatabaseConnection createConnection() {
return new MySQLConnection();
}
}
class PostgreSQLConnectionFactory implements DatabaseConnectionFactory {
@Override
public DatabaseConnection createConnection() {
return new PostgreSQLConnection();
}
}
public class DatabaseClient {
public static void main(String[] args) {
DatabaseConnectionFactory mysqlFactory = new MySQLConnectionFactory();
DatabaseConnection mysqlConnection = mysqlFactory.createConnection();
mysqlConnection.connect();
mysqlConnection.disconnect();
DatabaseConnectionFactory postgresFactory = new PostgreSQLConnectionFactory();
DatabaseConnection postgresConnection = postgresFactory.createConnection();
postgresConnection.connect();
postgresConnection.disconnect();
}
}
这个例子展示了如何使用工厂模式来创建不同类型的数据库连接,而不需要在客户端代码中直接实例化具体的连接类。
9. 结论
工厂模式是一种强大而灵活的创建型设计模式,它可以帮助解耦对象的创建和使用。从简单工厂到抽象工厂,每种形式都有其适用的场景。通过掌握工厂模式,可以编写出更加灵活、可维护和可扩展的代码。