大厂求职者必看!如何用简单工厂模式征服面试官?

「面试官」: 您好!今天我们将探讨简单工厂模式。首先,您能解释一下什么是简单工厂模式吗?

「求职者」: 当然,简单工厂模式是一种创建对象的设计模式,「它通过一个单独的工厂类来决定实例化哪一个继承类。这个模式能够解决由接口隔离原则带来的一些问题,如选择合适的类进行实例化」。它能够使软件架构保持松耦合,同时具有良好的扩展性。

「面试官」: 了解了。那么,能否结合代码给我展示一下简单工厂模式是如何实现的?

「求职者」: 当然可以。以计算器程序为例,我们首先定义了一个操作类Operation,它拥有两个受保护的属性numberAnumberB,以及一个用于返回计算结果的getResult方法。

public class Operation {
    protected double numberA = 0;
    protected double numberB = 0;

    public double getResult() {
        double result = 0;
        return result;
    }
    // ...其他getter和setter方法...
}

「面试官」: 那么,对于不同的运算操作,如何处理呢?

「求职者」: 我们可以创建不同的运算类来继承Operation类,并重写getResult方法。例如,对于加法运算,我们有OperationAdd类:

public class OperationAdd extends Operation {
    @Override
    public double getResult() {
        return numberA + numberB;
    }
}

「面试官」: 明白了。接下来,简单工厂类如何选择并创建具体的运算类实例?

「求职者」: 简单工厂类OperationFactory通过一个静态方法createOperate来实现。它根据传入的运算符参数来决定返回哪个具体的Operation子类实例。这是OperationFactory类的实现:

public class OperationFactory {
    public static Operation createOperate(String operate) {
        Operation operation = null;
        switch (operate) {
            case "+":
                operation = new OperationAdd();
                break;
            // ...其他运算符的case...
            default:
                throw new RuntimeException("Unsupported operation");
        }
        return operation;
    }
}

「面试官」: 了解了,那么客户端如何使用这个简单工厂类呢?

「求职者」: 客户端会根据「用户输入的数值和运算符号来获取相应的」Operation对象。然后设置输入的数值,并调用getResult方法来获取计算结果。这是一个控制台程序的例子:

public class CalculatorClient {
    public static void main(String[] args) {
        // ...获取输入的numberA、numberB和operationStr...

        Operation operation = OperationFactory.createOperate(operationStr);
        operation.setNumberA(numberA);
        operation.setNumberB(numberB);
        double result = operation.getResult();

        System.out.println("结果为:" + result);
    }
}

「面试官」: 很好。最后,您能谈谈简单工厂模式的优点和可能的缺点吗?

「求职者」: 简单工厂模式的优点是降低了客户端和具体类之间的耦合度,使得系统更容易扩展。只需添加新的运算类「并在工厂类中加入适当的逻辑即可」。缺点是当产品种类非常多时,工厂类可能会变得很复杂,并且如果增加新的产品,需要修改工厂类,这违反了开闭原则。

「面试官」: 在我们继续之前,你能给出一个实际的场景,说明在什么情况下会选择使用简单工厂模式吗?

「求职者」: 当然。假设我们正在开发一个电商平台,需要处理多种类型的支付方式,如信用卡支付、PayPal、银行转账等。「如果我们直接在代码中硬编码所有支付逻辑,每当添加新的支付方式时」,都需要修改原有代码,这会使代码变得难以维护和扩展。

在这种情况下,我们可以使用简单工厂模式创建一个支付工厂类,它负责根据不同的支付类型返回对应的支付对象。这样,每当我们需要添加新的支付方式时,只需添加一个新的支付类并在工厂类中增加相应的逻辑,而不需要修改任何现有代码。

「面试官」: 非常好。那么能否在这个场景中给出简单工厂模式的代码示例?

「求职者」: 当然可以。这是支付工厂类的代码示例:

public class PaymentFactory {
    public static Payment createPayment(String paymentType) {
        Payment payment = null;
        switch (paymentType) {
            case "CreditCard":
                payment = new CreditCardPayment();
                break;
            case "PayPal":
                payment = new PayPalPayment();
                break;
            case "BankTransfer":
                payment = new BankTransferPayment();
                break;
            // ...其他支付方式...
            default:
                throw new RuntimeException("Unsupported payment method");
        }
        return payment;
    }
}

每个支付方式如信用卡支付、PayPal支付等都会有对应的类,继承自Payment类,并实现具体的支付逻辑。

「面试官」: 能解释一下Payment类和一个具体支付类的实现吗?

「求职者」: 当然。Payment类是一个抽象类,它定义了所有支付方式共有的接口。例如,它可以有一个processPayment方法,用于处理支付。这是Payment类的一个简单实现:

public abstract class Payment {
    public abstract void processPayment(double amount);
}

对于信用卡支付,我们可以有一个CreditCardPayment类,它实现了processPayment方法:

public class CreditCardPayment extends Payment {
    @Override
    public void processPayment(double amount) {
        // 实现信用卡支付逻辑
        System.out.println("Processing credit card payment for amount: " + amount);
    }
}

「面试官」: 很好。你觉得在实际开发中,使用简单工厂模式会遇到哪些实际的挑战?

「求职者」: 实际开发中,最大的挑战可能是工厂类的扩展性问题。当新增很多支付方式时,工厂类可能会变得非常庞大,并且每次添加新的支付方式都需要修改工厂类,这违反了开闭原则。另外,如果支付方式的创建逻辑非常复杂,工厂类的代码也会变得复杂和难以维护。

「面试官」: 为了解决这些挑战,你会推荐使用哪种设计模式呢?

「求职者」: 如果我们想要遵守开闭原则,同时保持工厂类的简洁,「我们可以考虑使用工厂方法模式。在这种模式下,每个支付方式都有一个对应的工厂类,这些工厂类都实现了一个共同的接口」。这样,每当我们需要添加新的支付方式时,只需添加一个新的工厂类而不是修改现有的工厂类,这样就能保持工厂类的稳定和系统的可扩展性。

「面试官」: 很棒的建议。非常感谢今天的分享,这将是一个很有价值的面试。祝好运!

本文使用 markdown.com.cn 排版

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt程序设计-批量读取文本文件并修改保存

本文实例演示Qt中如何批量读取文本文件并修改保存。 创建控制台项目添加如下代码 #include <QCoreApplication> #include <QDirIterator> #include <QTextStream>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);// 设置要处理的目录路…

温湿度传感器SHT21

SHT21是一款基于IIC的温湿度传感器&#xff0c;它的引脚及定义如下&#xff1a; 标准的IIC器件&#xff0c;没有其他多余的引脚&#xff0c;应用框图如下&#xff1a; 温度的测量范围是-40到125℃&#xff0c;湿度测量范围0-100%RH&#xff0c;具体参数及采样精度见下图&#x…

HM_2019在面积不变情况下编辑网格

首先&#xff0c;应该保存其形状&#xff0c;计算他的面积。让面积不变作为一个约束&#xff0c;然后进行网格的形变。

面试官:你知道几种数组扁平化的方法?

面试官&#xff1a;你知道几种数组扁平化的方法&#xff1f; 数组扁平化相信不少掘友在一些面试中被问到过&#xff0c;这在我们日常编程中也是一个常规操作&#xff0c;它需要我们将一个多维数组转化成一个一维数组。当然&#xff0c;我相信很多掘友都能回答上这个问题&#x…

【网站项目】154大学生创新创业平台竞赛管理子系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

uniapp+node.js前后端做帖子模块:分享帖子和分享页面(社区管理平台的小程序)

目录 0前提1.一些准备1.1表帖子表 post 1.2总体思路 2.前端3.后端 &#x1f44d; 点赞&#xff0c;你的认可是我创作的动力&#xff01; ⭐️ 收藏&#xff0c;你的青睐是我努力的方向&#xff01; ✏️ 评论&#xff0c;你的意见是我进步的财富&#xff01; 0前提 温馨提示…

d2-crud-plus 使用小技巧(二)—— 路由跳转查询

需求 项目中要在a.vue界面点击表格中数据&#xff0c;携带参数跳转到b.vue界面&#xff0c;并进行查询。需要在d2-crud-plus框架下实现。 解决方法 使用插槽将要点击的数据添加上点击事件&#xff0c;在点击事件中添加路由跳转&#xff0c;并携带参数。 在目标界面使用对外…

单页面应用的优缺点

单页面应用&#xff08;SPA&#xff0c;Single Page Application&#xff09;是一种特殊的Web应用&#xff0c;其所有页面操作和交互都通过JavaScript、AJAX、HTML5和CSS3等前端技术在浏览器中完成&#xff0c;无需每次请求都重新加载整个页面。这种应用的设计模式在近年来越来…

js中的递归

理解 在函数内部可以调用其他函数,如果这个函数在内部调用了自身,那么这个函数就是递归函数 递归的优点 代码简洁性,递归可以用简介的代码实现复杂的问题逻辑清晰易于理解 递归缺点 调用栈溢出,递归中如何递归层次过深,超过了js引擎的调用栈深度限制,就会导致出现 "最…

GIN与Echo:选择正确Go框架的指南

您是否在Go中构建Web应用&#xff1f;选择正确的框架至关重要&#xff01;GIN和Echo是两个热门选择&#xff0c;每个都有其优势和特点。本指南将详细介绍每个框架的特性、速度、社区热度以及它们各自擅长的项目类型。最后&#xff0c;您将能够为您的下一个Web项目选择完美的框架…

C++11常用知识分享(一)【列表初始化 || 简化声明 || 范围for || 左右值 || 可变参数模板】

目录 一. 列表初始化 1&#xff09;用法 2) initializer_list 小节&#xff1a; 二&#xff0c;简化声明 1) &#xff0c;auto 2) &#xff0c;decltype类 3)&#xff0c;nullptr 三&#xff0c;范围for 四&#xff0c;C11后&#xff0c;STL容器变化 五&#xff0c…

一篇文章教会你如何在IOS真机上完美运行React Native

一篇文章教会你如何在IOS真机上完美运行React Native 项目初始化项目配置可能遇到的问题没有账号也没有Team设备上没有打开开发者模式&#xff0c;也没有信任开发者证书 无线调试 项目初始化 在终端使用**npx react-native init ProjectName**初始化React Native项目。 进入项…

运维随录实战(5)之centos搭建jenkins

一,搭建jenkins准备 下载安装jdk环境 -》版本 jdk11 下载安装maven环境 -》版本 maven 3.8.8 git -》版本 1.8.3.1 yum install git jenkins安装版本:2.414.3 下载地址:https://get.jenkins.io/war-stable/2.414.3/jenkins.war 注:jenkins版本与jdk版本有一定的对应关…

力扣550 游戏玩法分析 IV

目录 题目描述 思路整理 1. 首次登录日期 2. 第二天登录 3. 计算比率 实现思路 完整代码及解释 题目描述 Table: Activity ----------------------- | Column Name | Type | ----------------------- | player_id | int | | device_id | int | | ev…

117.移除链表元素(力扣)

题目描述 代码解决 class Solution { public:ListNode* removeElements(ListNode* head, int val) {//删除头节点while(head!NULL&&head->valval){ListNode*tmphead;headhead->next;delete tmp;}//删除非头节点ListNode*curhead;while(cur!NULL&&cur-&g…

安卓虚拟机ART和Dalvik

目录 一、JVM和Dalvik1.1 基于栈的虚拟机字节码指令执行过程 1.2 基于寄存器的虚拟机 二、ART与Dalvikdex2aotAndroid N的运作方式 三、总结 一、JVM和Dalvik Android应用程序运行在Dalvik/ART虚拟机&#xff0c;并且每一个应用程序对应有一个单独的Dalvik虚拟机实例。 Dalvik…

python入门第十七节常用的高级函数

常用的高级函数 常用的高阶函数filter(function, iterable)map(func, *iterables)reduce(function, iterable[, initial]) 常用的高阶函数 定义&#xff1a;参数或返回值为其他函数的函数 filter(function, iterable) function&#xff1a;函数&#xff08;function 必需能够…

Vue.js 实用技巧:深入理解 Vue.set 方法

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

20 个不同的 Python 函数实例

Python 是一种广泛使用的高级编程语言&#xff0c;其函数是 Python 编程中至关重要的概念之一。函数是一段可以重复使用的代码块&#xff0c;可以接收输入参数并返回输出结果。使用函数能够提高代码的可读性、可维护性和重用性。 基础知识 在 Python 中&#xff0c;函数使用关…

异常值检测-箱线图 头歌代码注释

方法一&#xff1a; import pandas as pd import matplotlib.pyplot as plt from scipy import stats import numpy as npdata pd.read_csv("src/death.csv", index_colUnnamed: 0)data data.dropna(axis1, threshdata.shape[0] * 0.2) data data.dropna(axis0, …