设计模式|工厂模式

文章目录

      • 1. 工厂模式的三种实现
      • 2. 简单工厂模式和工厂方法模式示例
      • 3. 抽象工厂模式示例
      • 4. 工厂模式与多态的关系
      • 5. 工程模式与策略模式的关系
      • 6. 面试中可能遇到的问题
        • 6.1 **工厂模式的概念是什么?**
        • 6.2 **工厂模式解决了什么问题?**
        • 6.3 **工厂模式的优点是什么?**
        • 6.4 **工厂模式有哪些不同的实现方式?**
        • 6.5 **举例说明简单工厂模式、工厂方法模式和抽象工厂模式的实现吗?**
        • 6.6 **工厂模式在什么场景下使用比较合适?**
        • 6.7 **使用工厂模式有什么优点?它解决了哪些问题?**
        • 6.8 **工厂模式有什么缺点?在什么情况下不适合使用?**
        • 6.9 **能否举例说明工厂模式在实际项目中的应用场景?**
        • 6.10 **工厂模式和抽象工厂模式有什么区别?**
        • 6.11 **工厂模式和建造者模式有什么区别?它们在解决问题时有何异同?**
        • 6.12 **工厂模式和单例模式之间有什么关系?它们之间有何联系?**
        • 6.13 **在你之前的项目中是否使用过工厂模式?能否分享一些具体的应用经验?**
        • 6.14 **能够列举一些知名的框架或库中使用了工厂模式的例子吗?**
        • 6.15 **工厂模式是如何符合设计原则的?它与哪些设计原则相关?**
      • 附录 demo

在这里插入图片描述
工厂模式是一种常见的设计模式,在Java开发中被广泛应用。它属于创建型设计模式,旨在提供一种封装对象创建过程的方法,使得客户端代码可以与具体创建对象的过程解耦。

1. 工厂模式的三种实现

在Java中,工厂模式通常有三种实现方式:简单工厂模式、工厂方法模式和抽象工厂模式。

  • 简单工厂模式(Simple Factory Pattern)
    • 简单工厂模式通过一个工厂类来创建对象,客户端通过传递不同的参数给工厂类,工厂类根据参数的不同来创建不同的对象实例。
    • 优点是客户端代码简单,隐藏了具体对象的创建细节。
    • 缺点是当需要添加新的产品时,需要修改工厂类的代码,违反了开闭原则。
  • 工厂方法模式(Factory Method Pattern)
    • 工厂方法模式将对象的创建延迟到子类中去实现,即定义一个创建对象的接口,但让子类决定实例化哪个类。
    • 客户端通过调用工厂方法来创建对象,具体的实例化过程由子类负责。
    • 这样可以解决简单工厂模式中的缺点,使得系统更具灵活性和可扩展性。
  • 抽象工厂模式(Abstract Factory Pattern)
    • 抽象工厂模式提供一个接口用于创建一系列相关或依赖对象的家族,而不需要指定具体的类。
    • 与工厂方法模式相比,抽象工厂模式是针对多个产品等级结构的,可以创建不同产品族的全部产品。
    • 这种模式适用于需要在运行时切换不同产品族的场景,但增加新的产品族往往不太容易。

2. 简单工厂模式和工厂方法模式示例

// 简单工厂模式示例
class SimpleFactory {
    public static Product createProduct(String type) {
        if (type.equals("A")) {
            return new ConcreteProductA();
        } else if (type.equals("B")) {
            return new ConcreteProductB();
        } else {
            return null;
        }
    }
}

interface Product {
    void doSomething();
}

class ConcreteProductA implements Product {
    public void doSomething() {
        System.out.println("Product A");
    }
}

class ConcreteProductB implements Product {
    public void doSomething() {
        System.out.println("Product B");
    }
}

// 工厂方法模式示例
interface Factory {
    Product createProduct();
}

class ConcreteFactoryA implements Factory {
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

class ConcreteFactoryB implements Factory {
    public Product createProduct() {
        return new ConcreteProductB();
    }
}

public class Main {
    public static void main(String[] args) {
        // 简单工厂模式示例
        Product productA = SimpleFactory.createProduct("A");
        productA.doSomething();

        // 工厂方法模式示例
        Factory factoryA = new ConcreteFactoryA();
        Product productB = factoryA.createProduct();
        productB.doSomething();
    }
}

以上示例中,简单工厂模式中的 SimpleFactory 负责创建具体产品对象,而工厂方法模式中的 Factory 接口定义了创建产品的方法,具体的产品创建由不同的具体工厂类实现。

3. 抽象工厂模式示例

// 抽象工厂模式示例
interface AbstractFactory {
    AbstractProductA createProductA();
    AbstractProductB createProductB();
}

interface AbstractProductA {
    void doSomething();
}

interface AbstractProductB {
    void doSomething();
}

class ConcreteFactory1 implements AbstractFactory {
    public AbstractProductA createProductA() {
        return new ConcreteProductA1();
    }

    public AbstractProductB createProductB() {
        return new ConcreteProductB1();
    }
}

class ConcreteFactory2 implements AbstractFactory {
    public AbstractProductA createProductA() {
        return new ConcreteProductA2();
    }

    public AbstractProductB createProductB() {
        return new ConcreteProductB2();
    }
}

class ConcreteProductA1 implements AbstractProductA {
    public void doSomething() {
        System.out.println("Product A1");
    }
}

class ConcreteProductA2 implements AbstractProductA {
    public void doSomething() {
        System.out.println("Product A2");
    }
}

class ConcreteProductB1 implements AbstractProductB {
    public void doSomething() {
        System.out.println("Product B1");
    }
}

class ConcreteProductB2 implements AbstractProductB {
    public void doSomething() {
        System.out.println("Product B2");
    }
}

public class Main {
    public static void main(String[] args) {
        AbstractFactory factory1 = new ConcreteFactory1();
        AbstractProductA productA1 = factory1.createProductA();
        AbstractProductB productB1 = factory1.createProductB();

        productA1.doSomething();
        productB1.doSomething();

        AbstractFactory factory2 = new ConcreteFactory2();
        AbstractProductA productA2 = factory2.createProductA();
        AbstractProductB productB2 = factory2.createProductB();

        productA2.doSomething();
        productB2.doSomething();
    }
}
  • 在这个示例中,AbstractFactory 是抽象工厂接口,定义了创建一组相关产品的方法。
  • ConcreteFactory1ConcreteFactory2 是具体工厂类,分别实现了抽象工厂接口,用于创建一组特定的产品。
  • AbstractProductAAbstractProductB 是抽象产品接口,分别定义了产品 A 和产品 B 的方法。
  • ConcreteProductA1ConcreteProductA2ConcreteProductB1ConcreteProductB2 是具体产品类,分别实现了抽象产品接口,用于提供具体的产品功能。
  • Main 类中,通过创建不同的具体工厂对象来获取不同的产品族,然后调用产品的方法来实现具体的功能。

4. 工厂模式与多态的关系

工厂模式与多态之间有着密切的关系,因为工厂模式往往利用了多态的特性来实现对象的创建和使用。
多态是面向对象编程中的一个重要概念,它允许不同的对象对同一个消息作出不同的响应。在Java中,多态性可以通过继承和接口实现,其中子类或实现了接口的类可以覆写父类或接口中的方法,实现方法的多态性。
工厂模式利用多态性来实现创建对象的过程,具体来说:

  • 工厂方法模式
    • 工厂方法模式中,工厂类定义了一个创建产品的抽象方法,具体的产品创建延迟到具体的子类工厂中去实现。
    • 这里的多态性体现在客户端通过调用工厂方法来创建对象,而不需要关心具体的实现类是哪个,具体的实例化过程由子类负责,从而达到了解耦的目的。
  • 抽象工厂模式
    • 抽象工厂模式中,抽象工厂定义了创建一系列相关或依赖对象的接口,具体的产品族创建由具体的工厂类去实现。
    • 这里的多态性体现在客户端针对抽象工厂编程,而不需要关心具体的工厂类是哪个,具体的工厂类根据客户端的选择来创建不同的产品族。

总的来说,工厂模式通过利用多态性,将对象的创建过程和客户端代码解耦,提高了代码的灵活性和可维护性。在使用工厂模式时,客户端通常面向工厂接口或抽象工厂类编程,从而利用多态性来实现不同产品的创建和使用。

5. 工程模式与策略模式的关系

工厂模式(Factory Pattern)和策略模式(Strategy Pattern)是两种不同类型的设计模式,它们解决了不同的问题,但有时候也可以结合使用,互相配合,以达到更好的设计效果。

  • 工厂模式:
    • 工厂模式旨在提供一种封装对象创建过程的方法,使得客户端代码可以与具体创建对象的过程解耦。
    • 工厂模式根据需要实例化的对象类型,通过工厂类来创建对象,客户端只需要与工厂接口或抽象工厂类交互,而不需要直接与具体产品类交互。
    • 工厂模式通常用于创建对象的场景,比如创建数据库连接、日志记录器等。
  • 策略模式:
    • 策略模式旨在定义一系列算法,并将每个算法封装起来,使它们可以互相替换,从而使算法的变化独立于使用算法的客户端。
    • 策略模式通过定义一个接口或抽象类来封装算法族,然后通过具体的策略类来实现具体的算法,客户端可以根据需要选择不同的策略来使用。
    • 策略模式通常用于算法的变化频繁、需要在运行时动态选择算法或者需要将算法与客户端解耦的场景。

虽然工厂模式和策略模式解决了不同的问题,但在某些情况下它们可以结合使用:

  • 策略模式的工厂:在策略模式中,具体的策略类通常由客户端根据需要进行选择,而这个选择过程也可以由工厂模式来完成。工厂类可以根据某些条件或者策略来实例化具体的策略对象,从而使客户端更加灵活地选择策略。
  • 工厂模式中的策略:在工厂模式中,工厂类可以被视为一种策略的实现,根据客户端的需求选择合适的工厂来创建对象,这样客户端就可以在不同的情况下使用不同的创建策略。

综上所述,工厂模式和策略模式虽然解决了不同的问题,但在一些情况下可以结合使用,以满足更复杂的设计需求。

6. 面试中可能遇到的问题

与工厂模式相关的问题可能涉及到工厂模式的概念、使用场景、实现方式以及与其他设计模式的比较等方面。以下是一些可能会被问及的问题

6.1 工厂模式的概念是什么?
  • 工厂模式是一种创建型设计模式,它提供了一种封装对象创建过程的方法,使得客户端代码可以与具体创建对象的过程解耦。
  • 其核心思想是通过工厂类来创建对象,而不是直接在客户端代码中通过 new 操作符实例化对象。
6.2 工厂模式解决了什么问题?
  • 工厂模式解决了客户端代码与具体对象创建过程之间的耦合问题。它使得客户端不需要知道对象的具体创建细节,只需要通过工厂类来获取所需的对象实例。
6.3 工厂模式的优点是什么?
  • 解耦客户端和具体类的实现,降低了代码的依赖性;
  • 提供了一种统一的接口来创建对象,使得客户端代码更加灵活和可维护;
  • 可以隐藏对象创建的细节,对客户端代码进行了抽象。
6.4 工厂模式有哪些不同的实现方式?

工厂模式有三种主要的实现方式:

  • 简单工厂模式、工厂方法模式和抽象工厂模式。
    • 简单工厂模式通过一个工厂类来创建对象;
    • 工厂方法模式将对象的创建延迟到具体的子类中去实现;
    • 而抽象工厂模式提供一个接口用于创建一系列相关或依赖对象的家族,而不需要指定具体的类。
6.5 举例说明简单工厂模式、工厂方法模式和抽象工厂模式的实现吗?
  • 简单工厂模式示例:一个汽车制造工厂(CarFactory)生产不同型号的汽车(例如:奥迪、宝马、奔驰)。
  • 工厂方法模式示例:一个汽车制造工厂(CarFactory)接口定义了生产汽车的抽象方法,具体的汽车制造工厂(例如:奥迪工厂、宝马工厂、奔驰工厂)继承该接口,并实现了具体的汽车生产方法。
  • 抽象工厂模式示例:一个汽车配件制造工厂(CarPartsFactory)接口定义了生产汽车零件的抽象方法,具体的汽车配件制造工厂(例如:德国工厂、日本工厂)继承该接口,并实现了具体的汽车零件生产方法。
6.6 工厂模式在什么场景下使用比较合适?
  • 工厂模式适用于需要根据不同条件创建不同类型对象的场景,以及对象的创建过程比较复杂、需要隐藏创建细节的场景。
  • 它特别适用于需要创建一系列相关对象或对象族的情况。
6.7 使用工厂模式有什么优点?它解决了哪些问题?
  • 工厂模式的优点包括:解耦、灵活性和可维护性。
  • 它将对象的创建过程集中在一个地方,使得客户端代码更加简洁、灵活,并且易于扩展和维护。
6.8 工厂模式有什么缺点?在什么情况下不适合使用?
  • 工厂模式的缺点是如果产品种类过多,会导致工厂类代码过于复杂;
  • 并且在简单工厂模式在添加新产品时,需要修改工厂类,违反了开闭原则。不适合在产品种类频繁变化的场景中使用。
6.9 能否举例说明工厂模式在实际项目中的应用场景?
  • 工厂模式在实际项目中有许多应用场景,例如在数据库访问框架中,通过工厂模式来创建不同类型的数据库连接对象;在日志记录框架中,通过工厂模式来创建不同类型的日志记录器对象等。
6.10 工厂模式和抽象工厂模式有什么区别?
  • 工厂模式关注于创建单个对象,它提供了一个统一的接口来创建对象;
  • 而抽象工厂模式关注于创建一系列相关或依赖对象的家族,它提供了一个接口来创建不同类型对象的多个系列;
  • 它们适用于不同的场景,工厂模式适用于创建单个对象,而抽象工厂模式适用于创建多个相关对象的家族。
6.11 工厂模式和建造者模式有什么区别?它们在解决问题时有何异同?
  • 区别:
    • 工厂模式用于创建单个对象,它将对象的创建过程封装在一个工厂类中,客户端只需要关注工厂类即可获取所需的对象实例。
    • 建造者模式用于创建复杂对象,将一个复杂对象的构建过程分解为多个简单的步骤,由具体的建造者类负责实现这些步骤,并通过指挥者来组织这些步骤的执行,最终构建出复杂对象。
  • 异同:
    • 相同点:都是创建型设计模式,都涉及对象的创建过程,都可以帮助解决对象的创建过程与客户端代码的解耦问题。
    • 不同点:工厂模式关注于创建单个对象,而建造者模式关注于创建复杂对象,涉及对象构建过程的复杂性和组合方式。
6.12 工厂模式和单例模式之间有什么关系?它们之间有何联系?
  • 工厂模式和单例模式是两种不同类型的设计模式,它们解决了不同的问题,没有直接的关系。
  • 工厂模式是用于创建对象的一种模式,它可以帮助将对象的创建过程与客户端代码解耦。
  • 单例模式是一种创建型设计模式,用于确保一个类只有一个实例,并提供一个全局访问点来访问该实例。
6.13 在你之前的项目中是否使用过工厂模式?能否分享一些具体的应用经验?
  • 是的,我在之前的项目中使用过工厂模式。一个具体的应用场景是在一个电商平台项目中,我们使用工厂模式来创建不同类型的支付方式对象。根据用户选择的支付方式(例如支付宝、微信、银行卡等),工厂类负责创建相应的支付对象,并将其提供给订单处理模块使用。
6.14 能够列举一些知名的框架或库中使用了工厂模式的例子吗?
  • 一些知名的框架或库中使用了工厂模式,
    • 例如 Java 中的 JDBC(Java Database Connectivity) API,它使用工厂模式来创建数据库连接对象;
    • Spring Framework 中的 BeanFactory 和 ApplicationContext 使用工厂模式来创建和管理对象实例;
    • Android 中的 LayoutInflater 使用工厂模式来创建 View 对象等。
6.15 工厂模式是如何符合设计原则的?它与哪些设计原则相关?
  • 工厂模式符合开闭原则(Open Closed Principle)和单一职责原则(Single Responsibility Principle)。
    • 工厂模式使得系统对扩展开放,对修改关闭,当需要添加新的产品时,只需要添加相应的具体产品类和对应的工厂类,而无需修改客户端代码。
    • 工厂模式将对象的创建过程封装在一个单独的类中,实现了对象的创建和使用的分离,符合单一职责原则。

这些问题和答案可以帮助你更好地理解工厂模式,并在面试中给出清晰、准确的回答。

附录 demo

// 电脑接口
interface Computer {
    void display();
}

// 具体产品类:台式电脑
class DesktopComputer implements Computer {
    @Override
    public void display() {
        System.out.println("This is a desktop computer.");
    }
}

// 具体产品类:笔记本电脑
class LaptopComputer implements Computer {
    @Override
    public void display() {
        System.out.println("This is a laptop computer.");
    }
}

// 抽象工厂类:电脑工厂
abstract class ComputerFactory {
    public abstract Computer createComputer();
}

// 具体工厂类:台式电脑工厂
class DesktopComputerFactory extends ComputerFactory {
    @Override
    public Computer createComputer() {
        return new DesktopComputer();
    }
}

// 具体工厂类:笔记本电脑工厂
class LaptopComputerFactory extends ComputerFactory {
    @Override
    public Computer createComputer() {
        return new LaptopComputer();
    }
}

public class Main {
    public static void main(String[] args) {
        // 创建台式电脑
        ComputerFactory desktopFactory = new DesktopComputerFactory();
        Computer desktop = desktopFactory.createComputer();
        desktop.display();

        // 创建笔记本电脑
        ComputerFactory laptopFactory = new LaptopComputerFactory();
        Computer laptop = laptopFactory.createComputer();
        laptop.display();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/484085.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Objective -- C】—— GCD(1)(Grand Central Dispatch)

【Objective -- C】—— GCD(1)(Grand Central Dispatch) GCD1. 什么是GCD2.多线程编程线程多线程的理解多线程的优点 3.任务和队列任务同步执行和异步执行 队列串行队列和并发队列 GCD的API1.Dispatch QueueDispatch Queue的分类…

客户管理系统功能大揭秘!助您了解其核心作用!

早在2019年,中国已经快速迈向服务经济时代 客户管理一直是各行业管理者关心的话题,在数字化时代,如何做好客户管理?很多人说可以尝试客户管理系统,那么今天大家就一窥客户管理系统的庐山真面目。 一、什么是客户管理系…

复试编程练习题(from 牛客网)

考试时候可能没有VS,但codeblocks是必备的。 下面总结一些常用的快捷键。 CtrlEnter:光标移至行尾ShiftEnter:光标跳到下一行CtrlD:直接复制粘贴当前行CtrlL:删除当前行F9:buildrun。CtrlShiftC:注释掉当…

网络安全实训Day9

写在前面 访问控制和防火墙桌面端安全检测与防御 网络安全实训-网络安全技术 网络安全概述 访问控制 定义:通过定义策略和规则来限制哪些流量能经过防火墙,哪些流量不能通过。本质是包过滤 可以匹配的元素 IP协议版本 源区域和目的区域 源IP地址和目…

【C++那些事儿】C++模板编程入门:构建可重用组件的利器

📷 江池俊:个人主页 🔥 个人专栏:✅C那些事儿 ✅Linux技术宝典 🌅 此去关山万里,定不负云起之望 文章目录 1. 泛型编程2. 函数模板2.1 函数模板概念2.1 函数模板格式2.3 函数模板的原理2.4 函数模板的实…

基于python+vue成都旅游网flask-django-php-nodejs

本篇论文对成都旅游网的需求分析、功能设计、系统设计进行了较为详尽的阐述,并对系统的整体设计进行了阐述,并对各功能的实现和主要功能进行了说明,并附上了相应的操作界面图。 语言:Python 框架:django/flask 软件版本…

select , poll, epoll思维导图

目录 1. 总的框架结构 2. select 3. poll 4. epoll 1. 总的框架结构 2. select

【C语言】自定义类型

1、内存对齐(必考) 1.1结构体内存对齐 结构体的对齐规则: 1. 第一个成员在与结构体变量偏移量为0的地址处。 2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 对齐数 编译器默认的一个对齐数 与 该成员大…

为什么算法渐进复杂度中对数的底数总为2

在分析各种算法时,经常看到(O(\log_2n))或(O(n\log_2n))这样的渐进复杂度。不知有没有同学困惑过,为什么算法的渐进复杂度中的对数都是以2为底?为什么没有见过(O(n\log_3n))这样的渐进复杂度?本文解释这个问题。 三分式归并排序的…

Obsidian+PicGo+Gitee搭建免费图床

之前使用PicGoGitee配合Typora,后来因为换电脑Typora管理笔记不方便,换到Obsidian笔记,此处记录重新搭建图床的坑与经验。 主要参考# picGogitee搭建Obsidian图床,实现高效写作! 1 下载安装PicGo 下载链接https://mo…

ASM四部曲之一:什么是ASM

文章目录 前言什么是.class文件什么是ASM概述作用域模型基于ASM的程序架构 ASM库结构 前言 本文翻译自ASM官方文档。 什么是.class文件 Java字节码文件(.class)是Java编译器编译Java源文件(.java)产生的目标文件。它是一种8位字…

【Linux】vim配置及安装方法

注 安装方法在文章最后 配置文件的位置 在目录 /etc/ 下面,有个名为vimrc的文件,这是系统中公共的vim配置文件,对所有用户都有效。而在每个用户的主目录下,都可以自己建立私有的配置文件,命名为“.vimrc”。例如&…

Docker搭建LNMP环境实战(03):VMware安装CentOS

Docker搭建LNMP环境实战(03):VMware安装CentOS 1、创建新的虚拟机,选择CentOS7镜像文件,并启动安装 启动VMware,创建新的虚拟机 图1 选择典型安装即可 选用最大最全的CentOS镜像文件:CentOS-7…

遥感原理与应用—绪论

一、关于基本概念与对应的英文 遥感:Remote Sensing 遥测:Telemetry,对被测物体某些运动参数和性质进行远距离测量的技术,分为接触测量与非接触测量,对于RS的概念,遥测探测的目标显得狭隘了一些&#xff…

Machine Learning - Logistic Regression

目录 一、Activation Function Why introduce activation functions? There are several commonly used activation functions: 二、Sigmoid: 三、Logistic Regression Model: 四、Implementation of logistic regression: 五、Decis…

GNU Radio创建Zadoff-Chu序列python OOT块

文章目录 前言一、ZC序列是什么?二、创建自定义的 OOT 块三、相关文件四、测试1、grc 图2、运行结果①、时域图②、时域幅值模图③、IQ 曲线 前言 本文实现在 GNU Radio 中创建 Zadoff-Chu 序列 python OOT 块,仅做代码调试记录。 一、ZC序列是什么&…

java 实现发送邮件功能

今天分享一篇 java 发送 QQ 邮件的功能 环境&#xff1a; jdk 1.8 springboot 2.6.3 maven 3.9.6 邮件功能依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId>&…

C语言分支和循环

目录 一.分支 一.if 二.if else 三.if else嵌套 四.else if 五.switch语句 二.循环 一.while (do while&#xff09;break : 二.for函数&#xff1a; 三.goto语句: 四.猜数字: 一.分支 一.if if要条件为真才执行为假不执行而且if只能执行后面第一条如果要执行多条就…

Windows下同时安装多个版本的JDK并配置环境变量

说明&#xff1a;这里安装的JDK版本为1.8和17 JDK下载 官方地址: https://www.oracle.com/java/ 我这里下载的是exe安装包 安装这里就不阐述了&#xff0c;安装方法都是一样的。 系统环境变量配置 1、首先新建JDK1.8和17的JAVA_HOME&#xff0c;他们的变量名区分开&#xff…

MySQL进阶——索引

索引 索引概述 索引结构 索引分类 索引语法 SQL性能分析 索引使用 索引设计原则 概述 介绍 索引&#xff08;Index&#xff09;是帮助MySQL高效获取数据的数据结构&#xff08;有序&#xff09;。 在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结…