【Java设计模式 | 创建者模式】工厂方法模式

前言:

创建者模式主要关注是"怎么创建对象?",它的主要特点是将对象的创建和使用分离。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。

创建者模式分为:

单例模式(Singleton): 【Java设计模式 | 创建者模式】单例模式-CSDN博客

工厂方法模式(Factory Method):【Java设计模式 | 创建者模式】工厂方法模式-CSDN博客

抽象工厂模式(Abstract Factory)

建造者模式(Builder)

原型模式(Prototype)

在Java中,万物皆对象,这些对象都需要创建,如果都是用new来创建该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象的地方都需要去修改,这显然违背了软件设计的开闭原则。如果我们我们使用工厂来生产对象,就可以只和工厂打交道,实现对对象的解耦。所以说工厂模式最大的优点就是:解耦。

简单工厂模式(并不属于GOF的23种经典模式):

结构:

简单工厂模式包含如下角色:

**产品接口:**定义了产品的规范,描述了产品的主要特性和功能。

**具体产品:**实现或者继承抽象产品的子类。

**具体工厂:**提供了创建产品的方法,调用者通过该方法来创建产品。

实现:

  1. 产品接口定义了所有产品共有的方法display()
  2. 具体产品类ConcreteProductAConcreteProductB实现了产品接口
  3. 工厂类SimpleFactory包含静态方法createProduct(),根据输入参数创建不同类型的产品对象
  4. 客户端代码通过调用工厂方法获取产品实例,无需直接实例化具体产品类
java 复制代码
// 定义产品接口
interface Product {
    void display();
}

// 具体产品类A
class ConcreteProductA implements Product {
    @Override
    public void display() {
        System.out.println("This is Product A");
    }
}

// 具体产品类B
class ConcreteProductB implements Product {
    @Override
    public void display() {
        System.out.println("This is Product B");
    }
}

// 简单工厂类
class SimpleFactory {
    public Product createProduct(String type) {
        if (type.equalsIgnoreCase("A")) {
            return new ConcreteProductA();
        } else if (type.equalsIgnoreCase("B")) {
            return new ConcreteProductB();
        }
        throw new IllegalArgumentException("Unknown product type");
    }
}

// 客户端代码
public class FactoryPatternDemo {
    public static void main(String[] args) {
        Product productA = SimpleFactory.createProduct("A");
        productA.display();

        Product productB = SimpleFactory.createProduct("B");
        productB.display();
    }
}
 

优点:

封装了创建对象的过程,可以通过参数创建对应的对象。把对象的创建和业务逻辑层分开,这样就降低了修改客户端代码的可能性。

缺点:

如果后期需要添加产品"C",还是需要修改工厂中的代码,产生了新的耦合,还是违背了开闭原则。

静态工厂模式(并不属于GOF的23种经典模式):

与简单工厂模式唯一不同的就是创建产品的方法使用static修饰。

java 复制代码
// 简单工厂类
class SimpleFactory {
    public static Product createProduct(String type) {
        if (type.equalsIgnoreCase("A")) {
            return new ConcreteProductA();
        } else if (type.equalsIgnoreCase("B")) {
            return new ConcreteProductB();
        }
        throw new IllegalArgumentException("Unknown product type");
    }
}

 

工厂方法模式:

针对简单工厂模式和静态工厂模式的弊端,我们选择引入工厂方法模式来解决,工厂方法模式完全遵循了开闭原则。

概念:

定义一个用于创建对象的接口,让子类决定实例化哪个产品对象。工厂方法使一个产品类的实例化延迟到其工厂的子类。

结构:

工厂方法模式的主要角色:

**抽象工厂(Abstract Factory):**提供了创建产品的接口,调用者通过它访问的具体工厂的工厂方法来创建产品。

**具体工厂(ConcreteFactory):**主要是实现抽象工厂中的抽象方法,完成了具体产品的创建。

**产品接口(Product):**定义了产品的规范,描述了产品的主要特性和功能。

**具体产品(ConcreteProduct):**实现了抽象产品角色所定义的接口,由具体工厂来创建。它同具体工厂之间一一对应。

实现:

java 复制代码
//抽象产品接口(Product)
public interface Product {
    void operation();
}


//具体产品类(ConcreteProduct)
public class ConcreteProductA implements Product {
    @Override
    public void operation() {
        System.out.println("ConcreteProductA operation");
    }
}

public class ConcreteProductB implements Product {
    @Override
    public void operation() {
        System.out.println("ConcreteProductB operation");
    }
}

//抽象工厂类(Abstract Factory)
public abstract class AbstractFactory {
    public abstract Product createProduct();
}

//具体工厂类(Concrete Factory)
public class ConcreteFactoryA extends AbstractFactory {
    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

public class ConcreteFactoryB extends AbstractFactory {
    @Override
    public Product createProduct() {
        return new ConcreteProductB();
    }
}

//客户端代码示例
public class Client {
    public static void main(String[] args) {
        AbstractFactory factoryA = new ConcreteFactoryA();
        Product productA = factoryA.createProduct();
        productA.operation();

        AbstractFactory factoryB = new ConcreteFactoryB();
        Product productB = factoryB.createProduct();
        productB.operation();
    }
}
//输出结果
ConcreteProductA operation
ConcreteProductB operation

优点:

用户只需要知道具体工厂的名称即可创建对应的产品,无需知道产品的创建过程;

在系统增加新的产品时只需要添加对应的具体产品类和具体工厂类即可,无需对原工厂类进行任何修改,满足开闭原则。

缺点:

每增加一个产品就需要添加对应的具体产品类和具体工厂类,写起来更繁琐。

相关推荐
tHeya06II2 小时前
涵盖 Cursor、Claude Code、Skills
java·服务器
kim_puppy2 小时前
TCP的三次握手,四次挥手
java·网络·tcp
诗人不写诗2 小时前
spring boot apm生态
java·数据库·spring boot
海参崴-2 小时前
C++代码格式规范
java·前端·c++
better_liang2 小时前
每日Java面试场景题知识点之-Redisson热门使用场景
java·redis·微服务·分布式锁·redisson·分布式系统
2301_792674862 小时前
java学习 day26
java
so2F32hj22 小时前
拆解 OpenHands(14)--- Microagents
java·开发语言
明灯伴古佛3 小时前
面试:什么是可重入性?为什么 synchronized 是可重入锁?
java·jvm·面试
卓怡学长3 小时前
m307自习室预订座位管理分析与实现
java·spring boot·spring