设计模式 | 挑战工厂模式

本文介绍了工厂模式的三种形式:简单工厂模式、工厂方法模式和抽象工厂模式。通过示例展示了每种模式的特点及应用场景,帮助读者理解如何根据不同需求选择合适的工厂模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


theme: vue-pro

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

一、工厂模式

工厂模式分为

  • 简单工厂模式(Simple Factory Pattern)
  • 工厂方法模式(Fatory Method Pattern)
  • 抽象工厂模式(Abastract Factory Pattern)

其中简单工厂模式不在GOF 总计出来的23中设计模式中。工厂模式属于创建型模式,就是创建对象的模式,抽象了实例化的过程。创建型模式关心的是对象的创建,即将创建对象的过程进行了封装,作为客户程序仅仅需要去使用对象,而不再关心创建对象过程中的逻辑。

为了后面的示例,我们先准备一个Product接口。

public interface Product {   String description(); }

然后实现这个接口,创建类BlackProduct

public class BlackProduct implements Product {   @Override   public String description() {       return "black BlackProduct";   } }

RedProduct

public class RedProduct implements Product {   @Override   public String description() {       return "red RedProduct";   } }

我们不使用任何模式,创建并使用Product。

public class NoneApp {   public static void main(String[] args) {       Product product = new RedProduct();       System.out.println(product.description());   } }

父类 Product 指向子类 RedProduct的引用,应用层代码需要依赖RedProduct,如果业务扩展,我继续增加更多的Product实现,那么我们客户端的依赖会变得越来越臃肿。因此,我们要想办法把这种依赖减弱,把创建细节隐藏。虽然目前的代码中,我们创建对象的过程并不复杂,但从代码设计角度来讲不易于扩展。

二、 简单工厂模式

简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心。

siProduct.png

使用简单工厂,我们需要准备一个工厂,通过传入产品的特征信息,创建对应的实例。

public class ProductFactory {   static final String RED = "red";   static final String BLACK = "black"; ​   public Product create(String trait) {       if (trait.equals(RED)) {           return new RedProduct();       } else if (trait.equals(BLACK)) {           return new BlackProduct();       }       throw new IllegalArgumentException();   } }

这个创建对象的逻辑有缺点,就是当我们要更新增加更加丰富的其它实现的时候,需要修改代码逻辑,不符合开闭原则,所以优化一版。

public class ProductUltraFactory {   @SneakyThrows   public Product create(Class<? extends Product> clazz) {       if (clazz != null) {           return clazz.newInstance();       }       throw new IllegalArgumentException();   } }

针对上面两个工厂,使用方法如下。

public class SimpleApp {   public static void main(String[] args) {       final ProductFactory productFactory = new ProductFactory();       final Product product = productFactory.create(ProductFactory.RED);       System.out.println(product.description()); ​       final ProductUltraFactory productUltraFactory = new ProductUltraFactory();       final Product otherProduct = productUltraFactory.create(RedProduct.class);       System.out.println(otherProduct.description());   } }

简单工厂的缺点一目了然:工厂类的职责相对过重,不易于扩展过于复杂的产品结构

三、工厂方法模式

工厂方法模式是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。在工厂方法模式中用户只需要关心所需产品对应的工厂,无须关心创建细节,而且加入新的产品符合开闭原则。

工厂方法模式主要解决产品扩展的问题,在简单工厂中,随着产品链的丰富,如果每个产品的创建逻辑有区别的话,工厂的职责会变得越来越多,有点像万能工厂,并不便于维护。根据单一职责原则我们将职能继续拆分,专人干专事。

所以我们要为每个产品单独配置一个工厂。

medthodProduct.png

黑色产品的生产工厂BlackProductFactory

public class BlackProductFactory implements ProductFactory {   @Override   public Product create() {       return new BlackProduct();   } }

红色产品的生产工厂RedProductFactory

public class RedProductFactory implements ProductFactory {   @Override   public Product create() {       return new RedProduct();   } }

使用方法如下

public class MethodApp {   public static void main(String[] args) {       final RedProductFactory redProductFactory = new RedProductFactory();       final Product product = redProductFactory.create();       System.out.println(product.description()); ​       final BlackProductFactory blackProductFactory = new BlackProductFactory();       final Product otherProduct = blackProductFactory.create();       System.out.println(otherProduct.description());   } }

适用场景:

  • 创建对象需要大量重复的代码。
  • 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节。
  • 一个类通过其子类来指定创建哪个对象。

缺点

类的个数容易过多,增加复杂度。

增加了系统的抽象性和理解难度。

四、抽象工厂模式

抽象工厂模式是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们具体的类。

客户端(应用层)不依赖于产品类实例如何被创建、实现等细节,强调的是一系列相关的产品对(属于同一产品族)一起使用创建对象需要大量重复的代码。需要提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。

absProduct.png

我们现在已经有一种产品Product,我们假设一系列的产品中还有AnotherProduct

public interface AnotherProduct {   String description(); }

RedAnotherProduct 是它的实现。

public class RedAnotherProduct implements AnotherProduct { ​   @Override   public String description() {       return "red AnotherProduct";   } }

抽象工厂模式最关键的是准备一个一系列抽象产品的工厂ComposeFactory

public interface ComposeFactory {   AnotherProduct createAnotherProduct();   Product createProduct(); }

这个抽象工厂的一种具体实现,比如红色产品的组合RedComposeFactory

public class RedComposeFactory implements ComposeFactory {   @Override   public AnotherProduct createAnotherProduct() {       return new RedAnotherProduct();   } ​   @Override   public Product createProduct() {       return new RedProduct();   } }

使用方法如下。

public class AbsApp {   public static void main(String[] args) {       final RedComposeFactory redComposeFactory = new RedComposeFactory();       final AnotherProduct anotherProduct = redComposeFactory.createAnotherProduct();       final Product product = redComposeFactory.createProduct();       System.out.println(anotherProduct.description());       System.out.println(product.description());   } }

抽象工厂非常完美清晰地描述这样一层复杂的组合关系。但它也有缺点。

  • 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。
  • 增加了系统的抽象性和理解难度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值