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分别实现了这些方法以创建不同的具体产品。客户端代码通过具体的工厂来创建和使用产品,而不需要直接与具体产品类打交道。这种方式提供了更好的灵活性和可扩展性,因为你可以在不修改客户端代码的情况下增加新的工厂和产品。


总结

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


目录
打赏
0
1
2
0
39
分享
相关文章
「全网最细 + 实战源码案例」设计模式——简单工厂模式
简单工厂模式是一种创建型设计模式,通过工厂类根据传入参数创建不同类型的对象,也称“静态工厂方法”模式。其结构包括工厂类、产品接口和具体产品类。优点是封装性强、代码复用性好;缺点是扩展性差,增加新产品时需修改工厂类代码,违反开闭原则。适用于对象种类较少且调用者无需关心创建细节的场景。
57 19
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
62 4
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
125 0
前端必须掌握的设计模式——模板模式
模板模式(Template Pattern)是一种行为型设计模式,父类定义固定流程和步骤顺序,子类通过继承并重写特定方法实现具体步骤。适用于具有固定结构或流程的场景,如组装汽车、包装礼物等。举例来说,公司年会节目征集时,蜘蛛侠定义了歌曲的四个步骤:前奏、主歌、副歌、结尾。金刚狼和绿巨人根据此模板设计各自的表演内容。通过抽象类定义通用逻辑,子类实现个性化行为,从而减少重复代码。模板模式还支持钩子方法,允许跳过某些步骤,增加灵活性。
155 11
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
2月前
|
「全网最细 + 实战源码案例」设计模式——模式扩展(配置工厂)
该设计通过配置文件和反射机制动态选择具体工厂,减少硬编码依赖,提升系统灵活性和扩展性。配置文件解耦、反射创建对象,新增产品族无需修改客户端代码。示例中,`CoffeeFactory`类加载配置文件并使用反射生成咖啡对象,客户端调用时只需指定名称即可获取对应产品实例。
90 40
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
「全网最细 + 实战源码案例」设计模式——生成器模式
生成器模式(Builder Pattern)是一种创建型设计模式,用于分步骤构建复杂对象。它允许用户通过控制对象构造的过程,定制对象的组成部分,而无需直接实例化细节。该模式特别适合构建具有多种配置的复杂对象。其结构包括抽象建造者、具体建造者、指挥者和产品角色。适用于需要创建复杂对象且对象由多个部分组成、构造过程需对外隐藏或分离表示与构造的场景。优点在于更好的控制、代码复用和解耦性;缺点是增加复杂性和不适合简单对象。实现时需定义建造者接口、具体建造者类、指挥者类及产品类。链式调用是常见应用方式之一。
56 12
「全网最细 + 实战源码案例」设计模式——工厂方法模式
简单工厂模式是一种创建型设计模式,通过一个工厂类根据传入参数创建不同类型的产品对象,也称“静态工厂方法”模式。其结构包括工厂类、产品接口和具体产品类。适用于创建对象种类较少且调用者无需关心创建细节的场景。优点是封装性强、代码复用性好;缺点是扩展性差,增加新产品时需修改工厂类代码,违反开闭原则。
52 15

热门文章

最新文章