【面试专题】设计模式篇①

1.工厂设计模式

工厂设计模式是一种创建型模式,它提供了一种创建对象的接口,但具体创建的对象类型可以在运行时决定。工厂设计模式主要解决的是创建对象的灵活性问题。

工厂设计模式主要包括简单工厂模式、工厂方法模式和抽象工厂模式三种。

  1. 简单工厂模式:通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。这种模式属于类的创新型模式,又叫静态工厂方法模式。简单工厂模式严重违背了“开闭原则”,难以拓展。
  2. 工厂方法模式:定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口。这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
  3. 抽象工厂模式:是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。

简单工厂模式:

//抽象产品
interface Product {void doSomething();
}//具体产品1
class ConcreteProduct1 implements Product {@Overridepublic void doSomething() {System.out.println("具体产品1");}
}//具体产品2
class ConcreteProduct2 implements Product {@Overridepublic void doSomething() {System.out.println("具体产品2");}
}//工厂类
class Factory{public static Product createProduct(int type) {switch (type) {case 1:return new ConcreteProduct1();case 2:return new ConcreteProduct2();default:return null;}}
}//测试类
public class Test {public static void main(String[] args) {Factory.createProduct(1).doSomething();//输出具体产品1Factory.createProduct(2).doSomething();//输出具体产品2}
}

工厂方法模式:

//抽象产品
interface Product{void doSomething();
}//具体产品1
class ConcreteProduct1 implements Product{@Overridepublic void doSomething() {System.out.println("具体产品1");}
}//具体产品2
class ConcreteProduct2 implements Product{@Overridepublic void doSomething() {System.out.println("具体产品2");}
}//抽象工厂
interface Factory {Product createProduct();
}//具体工厂1
class ConcreteFactory1 implements Factory{@Overridepublic Product createProduct() {return new ConcreteProduct1();}
}//具体工厂2
class ConcreteFactory2 implements Factory{@Overridepublic Product createProduct() {return new ConcreteProduct2();}
}//测试类
public class Test {public static void main(String[] args) {Factory factory1 = new ConcreteFactory1();factory1.createProduct().doSomething(); //输出具体产品1Factory factory2 = new ConcreteFactory2();factory2.createProduct().doSomething(); //输出具体产品2}
}

抽象工厂模式:

//抽象产品A
interface ProductA{void doSomething();
}//具体产品A1
class ConcreteProductA1 implements ProductA{@Overridepublic void doSomething() {System.out.println("具体产品A1");}
}//具体产品A2
class ConcreteProductA2 implements ProductA{@Overridepublic void doSomething() {System.out.println("具体产品A2");}
}//抽象产品B
interface ProductB{void doSomething();
}//具体产品B1
class ConcreteProductB1 implements ProductB{@Overridepublic void doSomething() {System.out.println("具体产品B1");}
}//具体产品B2
class ConcreteProductB2 implements ProductB{@Overridepublic void doSomething() {System.out.println("具体产品B2");}
}//抽象工厂
interface AbstractFactory{ProductA createProductA();ProductB createProductB();
}//具体工厂1
class ConcreteFactory1 implements AbstractFactory{@Overridepublic ProductA createProductA() {return new ConcreteProductA1();}@Overridepublic ProductB createProductB() {return new ConcreteProductB1();}
}//具体工厂2
class ConcreteFactory2 implements AbstractFactory{@Overridepublic ProductA createProductA() {return new ConcreteProductA2();}@Overridepublic ProductB createProductB() {return new ConcreteProductB2();}
}//测试类
public class Test {public static void main(String[] args) {AbstractFactory factory1 = new ConcreteFactory1();factory1.createProductA().doSomething(); //输出具体产品A1factory1.createProductB().doSomething(); //输出具体产品B1AbstractFactory factory2 = new ConcreteFactory2();factory2.createProductA().doSomething(); //输出具体产品A2factory2.createProductB().doSomething(); //输出具体产品B2}
}

2.策略模式

策略模式是一种行为型设计模式,它允许在运行时选择算法的行为。在Java中,可以通过接口和抽象类来实现策略模式。以下是一个简单的示例,展示应该如何使用Java编写策略模式。

首先,定义一个接口,该接口将定义策略算法的方法。

public interface Strategy {int execute(int num1, int num2);
}

接下来,创建实现该接口的不同策略类。

public class Add implements Strategy {public int execute(int num1, int num2) {return num1 + num2;}
}public class Subtract implements Strategy {public int execute(int num1, int num2) {return num1 - num2;}
}public class Multiply implements Strategy {public int execute(int num1, int num2) {return num1 * num2;}
}

然后,在主程序中,创建一个Context类,该类使用指定的策略执行算法。

public class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}public int executeStrategy(int num1, int num2) {return strategy.execute(num1, num2);}
}

最后,实例化不同的策略并将它们传递给Context类。

public class StrategyPatternExample {public static void main(String[] args) {Context context = new Context(new Add());System.out.println("10 + 5 = " + context.executeStrategy(10, 5));context = new Context(new Subtract());System.out.println("10 - 5 = " + context.executeStrategy(10, 5));context = new Context(new Multiply());System.out.println("10 * 5 = " + context.executeStrategy(10, 5));}
}

输出:

10 + 5 = 15
10 - 5 = 5
10 * 5 = 50

这个例子演示了如何实现策略模式,它允许在运行时选择算法的行为。

3.策略模式+工厂模式 实现登录

工厂方法模式是一种创建型模式,它将对象的创建委托给工厂类,由工厂类负责创建具体的对象实例。而策略模式是一种行为型模式,它定义了一系列算法,并将每个算法封装起来,使它们可以互换。

通过工厂方法模式,我们可以根据输入的参数,创建出对应的策略对象,然后通过策略对象来实现登录功能。具体实现如下:

1.创建策略接口,定义登录方法。

public interface LoginStrategy {boolean login(String username, String password);
}

2.创建具体的策略实现类,实现登录方法。

public class EmailLoginStrategy implements LoginStrategy {@Overridepublic boolean login(String username, String password) {// 基于邮箱的登录逻辑return true;}
}public class PhoneLoginStrategy implements LoginStrategy {@Overridepublic boolean login(String username, String password) {// 基于手机号的登录逻辑return true;}
}public class UsernameLoginStrategy implements LoginStrategy {@Overridepublic boolean login(String username, String password) {// 基于用户名的登录逻辑return true;}
}

3.创建工厂接口,定义创建策略对象的方法。

public interface LoginStrategyFactory {LoginStrategy createLoginStrategy(String type);
}

4.创建具体的工厂实现类,根据输入的参数创建对应的策略对象。

public class LoginStrategyFactoryImpl implements LoginStrategyFactory {@Overridepublic LoginStrategy createLoginStrategy(String type) {switch (type) {case "email":return new EmailLoginStrategy();case "phone":return new PhoneLoginStrategy();case "username":return new UsernameLoginStrategy();default:return null;}}
}

5.最终的登录类中,调用工厂方法来创建对应的策略对象,并调用登录方法。

public class Login {public boolean login(String type, String username, String password) {LoginStrategyFactory factory = new LoginStrategyFactoryImpl();LoginStrategy strategy = factory.createLoginStrategy(type);return strategy.login(username, password);}
}

这样,我们就可以根据输入的参数,动态地创建出对应的策略对象来实现登录功能。而且当需要增加新的登录方式时,只需要添加新的策略类和工厂方法即可。

4.责任链模式

责任链模式可以用于将多个处理请求的对象连接起来,形成一条处理链,将请求沿着这条链传递,直到有对象能够处理该请求为止,从而实现请求的处理和解耦的目的。下面以一个简单的示例说明如何在Java中实现责任链设计模式。

abstract class Handler {protected Handler handler;void setNext(Handler handler){this.handler = handler;}public abstract void process(OrderInfo order);}

import java.math.BigDecimal;public class OrderInfo {private String  productId;private String userId;private BigDecimal amount;public String getProductId() {return productId;}public void setProductId(String productId) {this.productId = productId;}public String getUserId() {return userId;}public void setUserId(String userId) {this.userId = userId;}public BigDecimal getAmount() {return amount;}public void setAmount(BigDecimal amount) {this.amount = amount;}
}
public class OrderValidition extends Handler {@Overridepublic void process(OrderInfo order) {System.out.println("OrderValidition--------");handler.process(order);}
}
public class OrderFill extends Handler{@Overridepublic void process(OrderInfo order) {System.out.println("OrderFill----");handler.process(order);}
}
public class OderAmountCalcuate extends Handler {@Overridepublic void process(OrderInfo order) {System.out.println("OderAmountCalcuate----");handler.process(order);}
}
public class OderCreate extends Handler {@Overridepublic void process(OrderInfo order) {System.out.println("OderCreate ----");}
}
public class Client {public static void main(String[] args) {OrderValidition orderValidition = new OrderValidition();OrderFill orderFill = new OrderFill();OderAmountCalcuate oderAmountCalcuate = new OderAmountCalcuate();OderCreate oderCreate = new OderCreate();orderValidition.setNext(orderFill);orderFill.setNext(oderAmountCalcuate);oderAmountCalcuate.setNext(oderCreate);orderValidition.process(new OrderInfo());}
}
OrderValidition--------
OrderFill----
OderAmountCalcuate----
OderCreate ----

5.单例模式

推荐视频:【单例模式】猛男因不懂单例模式,被面试官无情嘲讽_哔哩哔哩_bilibili

单例模式是一种创建型设计模式,用于确保类只有一个实例存在,并提供一个全局访问点。它的主要思想是,一个类只允许创建一个对象(或实例),并提供一个访问该对象的全局访问点。

单例模式的应用场景包括:

  1. 全局唯一的配置管理器。

  2. 全局唯一的状态管理器。

  3. 数据库连接池。

  4. 多线程池。

  5. 全局唯一的日志记录器。

  6. 具有特殊限制或唯一性要求的资源管理器。

单例模式的实现方式有多种,包括饿汉式单例、懒汉式单例、双重校验锁单例、静态内部类单例等。其中,饿汉式和懒汉式是最基础的两种实现方式。

1.饿汉式单例模式

饿汉式单例模式在类加载时即创建一个实例,不存在线程安全问题,但会影响性能,因为即使不需要使用该实例,也会一直占用内存。

public class Singleton {// 静态实例,类加载时即创建private static Singleton instance = new Singleton();// 私有构造方法,防止外部创建实例private Singleton() {}// 全局访问方法public static Singleton getInstance() {return instance;}
}

2.懒汉式单例模式

懒汉式单例模式在第一次访问实例时才创建,但存在线程安全问题,需要进行加锁处理。

public class Singleton {// 私有静态实例,延迟加载private static Singleton instance = null;// 私有构造方法,防止外部创建实例private Singleton() {}// 全局访问方法,加锁保证线程安全public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
3.双重校验锁单例

双重校验锁单例是一种常用的单例模式实现方式,它既保证了线程安全性,又提高了效率,下面是Java实现双重校验锁单例的代码:

public class Singleton {// volatile修饰的变量在多线程环境下保证可见性和有序性private volatile static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {// 双重校验锁,第一个if判断为了避免不必要的同步,第二个if保证同步情况下只有一个instance被创建if (instance == null) {instance = new Singleton();}}}return instance;}
}

上述代码中,instance变量使用了volatile关键字修饰,保证在多线程环境下对instance的读写操作都是可见的,避免出现线程A修改了instance变量值而线程B不可见的情况。

getInstance()方法中,第一个if判断为了避免多个线程同时进入synchronized代码块,进而造成系统资源的浪费。第二个if保证了在同步代码块中,只有一个instance被创建,避免线程安全问题的发生。

总之,使用双重校验锁单例可以保证线程安全性和效率,是一种常用的单例模式实现方式。

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

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

相关文章

如何使用 SwiftUI 中新地图框架 MapKit

文章目录 前言MapKit 弃用项MapContentBuilder(iOS 17)地图交互地图样式地图控件地图相机位置总结 前言 了解 iOS 17 中的 MapKit 后,我们会发现 Apple 引入了更适合 SwiftUI 的 API。 MapKit 弃用项 一旦将你的 App 目标更新到 iOS 17&am…

宠物医院服务预约小程序的效果如何

随着养宠家庭增多及对爱宠的照顾加深,除了食品、服饰外,宠物医院近些年也迎来了较高发展,部分城市甚至聚集着众多品牌,以单店或多店品牌的方式拓展市场。 对宠物医院来说,一般都是拓展同市客户,或者多门店…

OpenFeign 的超时重试机制以及底层实现原理

目录 1. 什么是 OpenFeign? 2. OpenFeign 的功能升级 3. OpenFeign 内置的超时重试机制 3.1 配置超时重试 3.2 覆盖 Retryer 对象 4. 自定义超时重试机制 4.1 为什么需要自定义超时重试机制 4.2 如何自定义超时重试机制 5. OpenFeign 超时重试的底层原理 5…

【蓝桥杯】2023省赛H题

考察知识点:双向链表,小根堆 完整代码在文章末尾 题目 【问题描述】 给定一个长度为 N 的整数数列: A1,A2,...,AN。你要重复以下操作 K 次 :…

下载安装各种版本的Vscode以及解决VScode官网下载慢的问题

下载指定版本 在Vscode官网 Vscode官网更新子页 这里的左侧栏点击其中一个会跳转到某个版本,或者在官网子页 https://code.visualstudio.com/updates的后面跟上需要的版本号即可完成目标版本下载页面的跳转 选择Linux里的ARM包不会自动下载而是跳转到另一个页面 …

【大模型应用开发教程】04_大模型开发整体流程 基于个人知识库的问答助手 项目流程架构解析

大模型开发整体流程 & 基于个人知识库的问答助手 项目流程架构解析 一、大模型开发整体流程1. 何为大模型开发定义核心点核心能力 2. 大模型开发的整体流程1. 设计2. 架构搭建3. Prompt Engineering4. 验证迭代5. 前后端搭建 二、项目流程简析步骤一:项目规划与…

Sync Folders Pro(文件夹数据同步工具)

Sync Folders Pro for Mac 是一款功能强大的文件夹同步工具,旨在帮助用户在 Mac 计算机和移动设备之间创建双向同步。这款软件支持各种文件系统和设备,如 iPhone,iPad,iPod,Android 等。通过这款软件,用户可…

【Spring Security】Spring Security 认证过程源码分析

项目启动 我们在前面有了解到可以在application.yml中配置用户名密码,那么可以猜想:肯定是在项目启动的时候加载的,我们通过鼠标点击 进入SecurityProperties,我们在User中的getName上打断点,这样项目启动的时候就可以走到这里 之后我们通过点击:Drop Frame可以往回走进…

基于白冠鸡算法的无人机航迹规划-附代码

基于白冠鸡算法的无人机航迹规划 文章目录 基于白冠鸡算法的无人机航迹规划1.白冠鸡搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要:本文主要介绍利用白冠鸡算法来优化无人机航迹规划。 1.白冠鸡…

Python爬取读书网的图片链接和书名并保存在数据库中

一个比较基础且常见的爬虫,写下来用于记录和巩固相关知识。 一、前置条件 本项目采用scrapy框架进行爬取,需要提前安装 pip install scrapy# 国内镜像 pip install scrapy -i https://pypi.douban.com/simple 由于需要保存数据到数据库,因…

安达发|APS生产排程解决五金制造企业的需求

在五金制造行业中,生产排程一直是一个非常重要的环节。然而,由于五金行业的特点和痛点,传统的生产排程方法往往难以满足企业的需求。本文将针对五金行业的痛点,探讨如何利用APS生产排程解决这些问题。 首先,我们需要了…

JAVA毕业设计109—基于Java+Springboot+Vue的宿舍管理系统(源码+数据库)

基于JavaSpringbootVue的宿舍管理系统(源码数据库)109 一、系统介绍 本系统前后端分离 本系统分为学生、宿管、超级管理员三种角色 1、用户: 登录、我的宿舍、申请调宿、报修申请、水电费管理、卫生检查、个人信息修改。 2、宿管: 登录、用户管理…

为机器学习算法准备数据(Machine Learning 研习之八)

本文还是同样建立在前两篇的基础之上的! 属性组合实验 希望前面的部分能让您了解探索数据并获得洞察力的几种方法。您发现了一些数据怪癖,您可能希望在将数据提供给机器学习算法之前对其进行清理,并且发现了属性之间有趣的相关性&#xff0c…

谈一谈SQLite、MySQL、PostgreSQL三大数据库

每一份付出,必将有一份收货,就像这个小小的果实,时间到了,也就会开花结果… 三大数据库概述 SQLite、MySQL 和 PostgreSQL 都是流行的关系型数据库管理系统(RDBMS),但它们在功能、适用场景和性…

Leetcode刷题详解——全排列

1. 题目链接:46. 全排列 2. 题目描述: 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1: 输入:nums [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],…

pcigo图床插件的简单开发

1.前言: 如果想写一个图床并且投入使用,那么,接入picgo一定是一个不错的选择。picgo有着windows,mac,linux等多个客户端版本。实用且方便。 2. 开发的准备: 2.0. 需要安装一个node node这里我就不详细说…

网络攻击的威胁仍在上升、企业该如何解决

近十年来,网络攻击的频率和规模不断增加,对网站和在线资产构成了严重威胁。解决网站被攻击的问题需要采用多层次的安全策略,其中CDN(内容分发网络)的防护角度发挥了关键作用。本文将通过通俗易懂的方式从CDN的角度分析…

3.线性神经网络-3GPT版

#pic_center R 1 R_1 R1​ R 2 R^2 R2 目录 知识框架No.1 线性回归基础优化算法一、线性回归1、买房案例2、买房模型简化3、线性模型4、神经网络5、损失函数6、训练数据7、参数学习8、显示解9、总结 二、 基础优化算法1、梯度下降2、学习率3、小批量随机梯度下降4、批量大小5、…

jetsonTX2 nx配置yolov5和D435I相机,完整步骤

转载一篇问题解决博客:问题解决 一、烧录系统 使用SDK烧录 二、安装archiconda3 JETSON TX2 NX的架构是aarch64,与win10,linxu不同,所以不能安装Anaconda,这里安装对应的archiconda。 1. 安装 wget https://github.com/Archiconda/build-tools/rel…

ACM MM 2023 | 清华、华为联合提出MISSRec:兴趣感知的多模态序列推荐预训练

©PaperWeekly 原创 作者 | 王锦鹏 单位 | 清华大学深圳国际研究生院 研究方向 | 多模态检索、推荐系统 序列推荐是一种主流的推荐范式,目的是从用户的历史行为中推测用户偏好,并为之推荐感兴趣的物品。现有的大部分模型都是基于 ID 和类目等信息做…