在开发程序的过程中不可避免的要创建很多的对象,如果直接新建对象,那么一旦代码涉及修改就要改动很多的地方。用一个工厂来生产对象,使用者只需要告诉工厂我需要什么,由工厂负责创建,使用者并不关心具体细节。就比如你去餐厅点餐,只需要告诉服务员你想吃什么,厨房会根据你的诉求制作相应的菜品,而你并不需要关系这道菜是怎么做的,用了什么材料。工厂模式的核心就是将对象的创建和使用分离,让代码更加灵活,更容易维护。
案例代码(简单工厂模式)
// 1. 定义产品接口
interface Car {
void drive();
}
// 2. 实现具体产品
class ToyotaCar implements Car {
@Override
public void drive() {
System.out.println("驾驶丰田车...");
}
}
class HondaCar implements Car {
@Override
public void drive() {
System.out.println("驾驶本田车...");
}
}
// 3. 创建工厂(决定生产哪种车)
class CarFactory {
public static Car createCar(String type) {
if ("Toyota".equals(type)) {
return new ToyotaCar();
} else if ("Honda".equals(type)) {
return new HondaCar();
}
throw new IllegalArgumentException("未知车型");
}
}
// 4. 使用工厂
public class Main {
public static void main(String[] args) {
Car car = CarFactory.createCar("Toyota");
car.drive(); // 输出:驾驶丰田车...
}
}
工厂方法模式(进阶)
// 1. 抽象工厂接口
interface CarFactory {
Car createCar();
}
// 2. 每个品牌有自己的工厂
class ToyotaFactory implements CarFactory {
@Override
public Car createCar() {
return new ToyotaCar();
}
}
class HondaFactory implements CarFactory {
@Override
public Car createCar() {
return new HondaCar();
}
}
// 3. 使用
public class Main {
public static void main(String[] args) {
CarFactory factory = new ToyotaFactory();
Car car = factory.createCar();
car.drive(); // 输出:驾驶丰田车...
}
}
实际案例
支付网关集成
场景:
支持支付宝、微信支付等多种支付方式,动态切换支付接口实现。
工厂模式应用:
通过工厂类根据参数创建对应的支付处理器实例。
参考代码:
// 1. 支付接口
interface Payment {
void pay(double amount);
}
// 2. 具体支付实现
class Alipay implements Payment {
@Override
public void pay(double amount) {
System.out.println("支付宝支付: " + amount);
}
}
class WechatPay implements Payment {
@Override
public void pay(double amount) {
System.out.println("微信支付: " + amount);
}
}
// 3. 支付工厂
class PaymentFactory {
public static Payment createPayment(String type) {
if ("alipay".equalsIgnoreCase(type)) {
return new Alipay();
} else if ("wechat".equalsIgnoreCase(type)) {
return new WechatPay();
}
throw new IllegalArgumentException("不支持的支付类型");
}
}
// 4. 使用
public class Main {
public static void main(String[] args) {
Payment payment = PaymentFactory.createPayment("alipay");
payment.pay(100.0); // 输出:支付宝支付: 100.0
}
}
跨平台 UI 组件
场景:
开发跨操作系统的 UI 工具包,根据当前系统生成对应的按钮、文本框。
工厂模式应用:
抽象工厂模式生产一组匹配当前平台的 UI 组件(如 WindowsButton、MacButton)。
参考代码:
// 1. 抽象产品:按钮
interface Button {
void render();
}
// 2. 具体产品
class WindowsButton implements Button {
@Override
public void render() {
System.out.println("Windows 风格按钮");
}
}
class MacButton implements Button {
@Override
public void render() {
System.out.println("Mac 风格按钮");
}
}
// 3. 抽象工厂
interface UIFactory {
Button createButton();
}
// 4. 具体工厂
class WindowsUIFactory implements UIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
}
class MacUIFactory implements UIFactory {
@Override
public Button createButton() {
return new MacButton();
}
}
// 5. 根据系统选择工厂
public class Main {
public static void main(String[] args) {
// 模拟系统检测(实际可能是根据配置或环境变量)
String os = "windows";
UIFactory factory;
if ("windows".equalsIgnoreCase(os)) {
factory = new WindowsUIFactory();
} else {
factory = new MacUIFactory();
}
Button button = factory.createButton();
button.render(); // 输出:Windows 风格按钮
}
}
数据库连接池
场景:
根据配置切换不同的数据库(MySQL、Oracle),避免硬编码数据库驱动类。
工厂模式应用:
用工厂类封装 DriverManager.getConnection() 的创建逻辑。
参考代码:
// 1. 数据库连接接口
interface Connection {
void connect();
}
// 2. 具体数据库连接
class MySQLConnection implements Connection {
@Override
public void connect() {
System.out.println("MySQL 连接成功");
}
}
class OracleConnection implements Connection {
@Override
public void connect() {
System.out.println("Oracle 连接成功");
}
}
// 3. 抽象工厂
interface ConnectionFactory {
Connection createConnection();
}
// 4. 具体工厂
class MySQLConnectionFactory implements ConnectionFactory {
@Override
public Connection createConnection() {
return new MySQLConnection();
}
}
class OracleConnectionFactory implements ConnectionFactory {
@Override
public Connection createConnection() {
return new OracleConnection();
}
}
// 5. 使用
public class Main {
public static void main(String[] args) {
// 根据配置选择工厂
ConnectionFactory factory = new MySQLConnectionFactory();
Connection conn = factory.createConnection();
conn.connect(); // 输出:MySQL 连接成功
}
}
选择建议