Java设计模式:工厂模式之简单工厂、工厂方法、抽象工厂(三)

简介: Java设计模式:工厂模式之简单工厂、工厂方法、抽象工厂(三)

一、核心概念

在软件设计中,工厂模式是一种常见的设计模式,它提供了一种创建对象的最佳方式。通过工厂模式,我们可以将对象的创建逻辑与使用逻辑分离,降低代码的耦合度,提高系统的可扩展性和可维护性。

Java中的工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

工厂模式的优点

  1. 解耦:将对象的创建和使用过程分开,使得客户端代码无需知道具体对象的创建过程,只需通过工厂获取对象即可。
  2. 降低代码重复:多个地方需要使用对象时,只需调用工厂方法即可,避免了代码的重复。
  3. 减少错误:由于对象的创建过程由工厂统一管理,因此可以减少因客户端错误创建对象而导致的错误。

Java中工厂模式主要三种形态

  1. 简单工厂模式(又称静态工厂方法):定义一个类来负责其他类的实例化,被创建的实例通常具有共同的父类或接口。客户端只需要传入相应的参数,即可获得所需的对象,而无需知道其具体类名。但是,当系统需要引入新的产品时,可能需要修改工厂类的代码,这违反了开闭原则。
  2. 工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。客户端针对抽象工厂及抽象产品编程,产品的具体工厂和产品由具体工厂子类实现。这样,当系统需要引入新的产品时,只需增加相应的具体工厂和产品类即可,符合开闭原则。
  3. 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。客户端使用一个抽象的工厂接口来创建产品,而具体的工厂类负责生成具体的产品。这样可以将简单工厂模式和工厂方法模式进行整合,使得产品的创建更加灵活和可扩展。

二、简单工厂模式

简单工厂模式是最简单的工厂模式,它通过一个专门的类来负责创建其他类的实例,而不需要明确指定具体将要创建的类。这个专门的类称为“简单工厂类”或“工厂类”。

在Java中,简单工厂模式是一种创建型设计模式,它由一个单独的类(称为工厂类)负责创建其他类的实例,而无需将这些类的实例化逻辑暴露给客户端。

简单工厂模式通常用于创建具有共同父类或接口的对象的场景。

下面是一个简单工厂模式的Java实现示例:

首先,定义一个产品接口或抽象类:

// 产品接口
public interface Product {
    void use();
}

然后,实现具体产品类:

// 具体产品A
public class ConcreteProductA implements Product {
    @Override
    public void use() {
        System.out.println("使用具体产品A");
    }
}

// 具体产品B
public class ConcreteProductB implements Product {
    @Override
    public void use() {
        System.out.println("使用具体产品B");
    }
}

接下来,创建简单工厂类:

// 简单工厂类
public class SimpleFactory {
    // 静态工厂方法,用于创建产品
    public static Product createProduct(String type) {
        if ("A".equals(type)) {
            return new ConcreteProductA();
        } else if ("B".equals(type)) {
            return new ConcreteProductB();
        } else {
            throw new IllegalArgumentException("不支持的产品类型: " + type);
        }
    }
}


最后,客户端代码可以这样使用简单工厂:

public class Client {
    public static void main(String[] args) {
        // 通过简单工厂创建产品A
        Product productA = SimpleFactory.createProduct("A");
        productA.use(); // 输出:使用具体产品A

        // 通过简单工厂创建产品B
        Product productB = SimpleFactory.createProduct("B");
        productB.use(); // 输出:使用具体产品B

        // 尝试创建不存在的产品类型将抛出异常
        // Product productC = SimpleFactory.createProduct("C");
    }
}

SimpleFactory类包含一个静态方法createProduct,它根据传入的类型字符串创建并返回相应的产品实例。客户端代码通过调用这个静态工厂方法来获取产品实例,而无需直接与具体的产品类交互。

优缺点分析

  • 简单工厂模式的优点在于它将对象的创建逻辑集中在一个单独的工厂类中,从而减少了客户端与具体类之间的耦合;
  • 同时简单易懂,易于实现。
  • 然而,它的一个缺点是当需要引入新的产品类型时,可能需要修改工厂类的代码,这违反了开闭原则(即对扩展开放,对修改封闭)
  • 此外,简单工厂模式还可能导致系统结构变得复杂和难以维护。

在实际应用中,如果需要频繁添加新的产品类型,可能会更倾向于使用抽象工厂模式或其他更灵活的工厂模式。

三、工厂方法模式

工厂方法模式是对简单工厂模式的进一步抽象化。它将对象的创建延迟到子类中进行,从而实现了更好的扩展性。在工厂方法模式中,抽象工厂类负责定义创建产品对象的接口,而具体工厂类则负责实现具体的产品创建逻辑。

下面是一个工厂方法模式的Java实现示例:

首先,定义一个产品接口:

// 产品接口
public interface Product {
    void use();
}

然后,实现具体产品类:

// 具体产品A
public class ConcreteProductA implements Product {
    @Override
    public void use() {
        System.out.println("使用具体产品A");
    }
}

// 具体产品B
public class ConcreteProductB implements Product {
    @Override
    public void use() {
        System.out.println("使用具体产品B");
    }
}

接下来,创建抽象工厂类,并定义工厂方法:

// 抽象工厂类
public abstract class Creator {
    // 工厂方法,声明为抽象方法,由子类实现
    public abstract Product factoryMethod();

    // 一个通用的方法,使用工厂方法来创建产品
    public final Product createProduct() {
        Product product = factoryMethod();
        // 这里可以添加一些额外的逻辑,比如初始化产品等
        return product;
    }
}

然后,实现具体的工厂子类:

// 具体工厂子类A,用于创建ConcreteProductA
public class ConcreteCreatorA extends Creator {
    @Override
    public Product factoryMethod() {
        return new ConcreteProductA();
    }
}

// 具体工厂子类B,用于创建ConcreteProductB
public class ConcreteCreatorB extends Creator {
    @Override
    public Product factoryMethod() {
        return new ConcreteProductB();
    }
}

最后,客户端代码可以这样使用工厂方法模式:

public class Client {
    public static void main(String[] args) {
        // 使用具体工厂子类A来创建产品A
        Creator creatorA = new ConcreteCreatorA();
        Product productA = creatorA.createProduct();
        productA.use(); // 输出:使用具体产品A

        // 使用具体工厂子类B来创建产品B
        Creator creatorB = new ConcreteCreatorB();
        Product productB = creatorB.createProduct();
        productB.use(); // 输出:使用具体产品B
    }
}

例子中,Creator是一个抽象工厂类,它声明了一个抽象方法factoryMethod(),这个方法由具体的工厂子类(ConcreteCreatorA和ConcreteCreatorB)来实现。客户端代码通过创建具体工厂类的实例并调用createProduct()方法来创建产品。每个具体工厂类都知道如何创建和返回一种具体的产品。


优缺点分析

工厂方法模式的优点在于它允许系统在不修改具体工厂类的情况下引进新的产品,这符合开闭原则。

此外,它还提供了一种将产品类与客户端代码解耦的机制,因为客户端代码只依赖于抽象产品和抽象工厂,而不是具体实现。

同时,它也降低了代码的耦合度,提高了系统的可扩展性和可维护性。

但是,与简单工厂模式相比,工厂方法模式需要定义更多的类,增加了系统的复杂度。

四、抽象工厂模式

抽象工厂模式是对工厂方法模式的进一步抽象化。它提供了一组用于创建一系列相关或互相依赖对象的接口,而不需要指定它们具体的类。在抽象工厂模式中,抽象工厂类负责定义创建产品家族的接口,而具体工厂类则负责实现具体的产品家族创建逻辑。产品家族是指位于不同产品等级结构中,功能相关联的产品组成的家族。

以下是Java中实现抽象工厂模式的一种方式:

首先,定义产品接口:

// 产品A的接口
public interface ProductA {
    void use();
}

// 产品B的接口
public interface ProductB {
    void use();
}

然后,实现具体产品:

// 具体产品A1
public class ConcreteProductA1 implements ProductA {
    @Override
    public void use() {
        System.out.println("使用具体产品A1");
    }
}

// 具体产品A2
public class ConcreteProductA2 implements ProductA {
    @Override
    public void use() {
        System.out.println("使用具体产品A2");
    }
}

// 具体产品B1
public class ConcreteProductB1 implements ProductB {
    @Override
    public void use() {
        System.out.println("使用具体产品B1");
    }
}

// 具体产品B2
public class ConcreteProductB2 implements ProductB {
    @Override
    public void use() {
        System.out.println("使用具体产品B2");
    }
}

接下来,定义抽象工厂接口:

public interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}

然后,实现具体工厂:

// 具体工厂1,负责创建产品A1和产品B1
public class ConcreteFactory1 implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ConcreteProductA1();
    }

    @Override
    public ProductB createProductB() {
        return new ConcreteProductB1();
    }
}

// 具体工厂2,负责创建产品A2和产品B2
public class ConcreteFactory2 implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ConcreteProductA2();
    }

    @Override
    public ProductB createProductB() {
        return new ConcreteProductB2();
    }
}

最后,客户端代码可以这样使用抽象工厂:

public class Client {
    public static void main(String[] args) {
        // 使用具体工厂1来创建产品
        AbstractFactory factory1 = new ConcreteFactory1();
        ProductA productA1 = factory1.createProductA();
        ProductB productB1 = factory1.createProductB();
        productA1.use(); // 输出:使用具体产品A1
        productB1.use(); // 输出:使用具体产品B1

        // 使用具体工厂2来创建产品
        AbstractFactory factory2 = new ConcreteFactory2();
        ProductA productA2 = factory2.createProductA();
        ProductB productB2 = factory2.createProductB();
        productA2.use(); // 输出:使用具体产品A2
        productB2.use(); // 输出:使用具体产品B2
    }
}

例子中,AbstractFactory接口定义了两个创建产品的方法,createProductA()和createProductB()。ConcreteFactory1和ConcreteFactory2分别实现了这些方法以创建不同的具体产品。客户端代码通过具体的工厂来创建和使用产品,而不需要直接与具体产品类打交道。这种方式提供了更好的灵活性和可扩展性,因为你可以在不修改客户端代码的情况下增加新的工厂和产品。


总结

在实际开发中,抽象工厂模式的实现可能更加复杂和庞大。为了保持代码的清晰和可维护性,我们需要合理地划分产品等级结构和产品家族,并遵循单一职责原则和开闭原则进行设计。同时,在实际应用中,我们可以根据具体需求选择使用简单工厂模式、工厂方法模式或抽象工厂模式中的任意一种或多种组合使用以满足需求。例如,在某些情况下,我们可以将简单工厂模式与工厂方法模式结合使用以简化代码结构并提高灵活性;而在其他情况下,我们可能需要使用抽象工厂模式来处理更复杂的对象创建场景。


相关文章
|
设计模式 Java 数据库连接
【设计模式】【创建型模式】工厂方法模式(Factory Methods)
一、入门 什么是工厂方法模式? 工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它定义了一个用于创建对象的接口,但由子类决定实例化哪个类。工厂方法模式使类的实例化延迟
448 16
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
设计模式 Java 关系型数据库
设计模式:工厂方法模式(Factory Method)
工厂方法模式是一种创建型设计模式,通过将对象的创建延迟到子类实现解耦。其核心是抽象工厂声明工厂方法返回抽象产品,具体工厂重写该方法返回具体产品实例。适用于动态扩展产品类型、复杂创建逻辑和框架设计等场景,如日志记录器、数据库连接池等。优点包括符合开闭原则、解耦客户端与具体产品;缺点是可能增加类数量和复杂度。典型应用如Java集合框架、Spring BeanFactory等。
|
设计模式 关系型数据库
「全网最细 + 实战源码案例」设计模式——工厂方法模式
简单工厂模式是一种创建型设计模式,通过一个工厂类根据传入参数创建不同类型的产品对象,也称“静态工厂方法”模式。其结构包括工厂类、产品接口和具体产品类。适用于创建对象种类较少且调用者无需关心创建细节的场景。优点是封装性强、代码复用性好;缺点是扩展性差,增加新产品时需修改工厂类代码,违反开闭原则。
331 15
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
这篇文章详细解释了工厂模式,包括简单工厂、工厂方法和抽象工厂三种类型。每种模式都通过代码示例展示了其应用场景和实现方法,并比较了它们之间的差异。简单工厂模式通过一个工厂类来创建各种产品;工厂方法模式通过定义一个创建对象的接口,由子类决定实例化哪个类;抽象工厂模式提供一个创建相关或依赖对象家族的接口,而不需要明确指定具体类。
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
|
设计模式 Java
Java 设计模式之谜:工厂模式与抽象工厂模式究竟隐藏着怎样的神奇力量?
【8月更文挑战第30天】在Java编程中,设计模式为常见问题提供了高效解决方案。工厂模式与抽象工厂模式是常用的对象创建型设计模式,能显著提升代码的灵活性、可维护性和可扩展性。工厂模式通过定义创建对象的接口让子类决定实例化哪个类;而抽象工厂模式则进一步提供了一个创建一系列相关或相互依赖对象的接口,无需指定具体类。这种方式使得系统更易于扩展和维护。
242 1
|
设计模式 Java
Java设计模式-工厂方法模式(4)
Java设计模式-工厂方法模式(4)
278 0
|
设计模式 缓存 安全
Java设计模式的单例模式应用场景
Java设计模式的单例模式应用场景
494 4
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
321 4
|
设计模式 存储 负载均衡
【五】设计模式~~~创建型模式~~~单例模式(Java)
文章详细介绍了单例模式(Singleton Pattern),这是一种确保一个类只有一个实例,并提供全局访问点的设计模式。文中通过Windows任务管理器的例子阐述了单例模式的动机,解释了如何通过私有构造函数、静态私有成员变量和公有静态方法实现单例模式。接着,通过负载均衡器的案例展示了单例模式的应用,并讨论了单例模式的优点、缺点以及适用场景。最后,文章还探讨了饿汉式和懒汉式单例的实现方式及其比较。
【五】设计模式~~~创建型模式~~~单例模式(Java)

热门文章

最新文章