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

1.工厂设计模式

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

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

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

简单工厂模式:

//抽象产品
interface Product {
    void doSomething();
}
 
//具体产品1
class ConcreteProduct1 implements Product {
    @Override
    public void doSomething() {
        System.out.println("具体产品1");
    }
}
 
//具体产品2
class ConcreteProduct2 implements Product {
    @Override
    public 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();//输出具体产品1
        Factory.createProduct(2).doSomething();//输出具体产品2
    }
}

工厂方法模式:

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

抽象工厂模式:

//抽象产品A
interface ProductA{
    void doSomething();
}
 
//具体产品A1
class ConcreteProductA1 implements ProductA{
    @Override
    public void doSomething() {
        System.out.println("具体产品A1");
    }
}
 
//具体产品A2
class ConcreteProductA2 implements ProductA{
    @Override
    public void doSomething() {
        System.out.println("具体产品A2");
    }
}
 
//抽象产品B
interface ProductB{
    void doSomething();
}
 
//具体产品B1
class ConcreteProductB1 implements ProductB{
    @Override
    public void doSomething() {
        System.out.println("具体产品B1");
    }
}
 
//具体产品B2
class ConcreteProductB2 implements ProductB{
    @Override
    public void doSomething() {
        System.out.println("具体产品B2");
    }
}
 
//抽象工厂
interface AbstractFactory{
    ProductA createProductA();
    ProductB createProductB();
}
 
//具体工厂1
class ConcreteFactory1 implements AbstractFactory{
    @Override
    public ProductA createProductA() {
        return new ConcreteProductA1();
    }
    @Override
    public ProductB createProductB() {
        return new ConcreteProductB1();
    }
}
 
//具体工厂2
class ConcreteFactory2 implements AbstractFactory{
    @Override
    public ProductA createProductA() {
        return new ConcreteProductA2();
    }
    @Override
    public ProductB createProductB() {
        return new ConcreteProductB2();
    }
}
 
//测试类
public class Test {
    public static void main(String[] args) {
        AbstractFactory factory1 = new ConcreteFactory1();
        factory1.createProductA().doSomething(); //输出具体产品A1
        factory1.createProductB().doSomething(); //输出具体产品B1
        AbstractFactory factory2 = new ConcreteFactory2();
        factory2.createProductA().doSomething(); //输出具体产品A2
        factory2.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 {
    @Override
    public boolean login(String username, String password) {
        // 基于邮箱的登录逻辑
        return true;
    }
}

public class PhoneLoginStrategy implements LoginStrategy {
    @Override
    public boolean login(String username, String password) {
        // 基于手机号的登录逻辑
        return true;
    }
}

public class UsernameLoginStrategy implements LoginStrategy {
    @Override
    public boolean login(String username, String password) {
        // 基于用户名的登录逻辑
        return true;
    }
}

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

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

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

public class LoginStrategyFactoryImpl implements LoginStrategyFactory {
    @Override
    public 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 {

    @Override
    public void process(OrderInfo order) {
        System.out.println("OrderValidition--------");
        handler.process(order);
    }
}
public class OrderFill extends Handler{
    @Override
    public void process(OrderInfo order) {
        System.out.println("OrderFill----");
        handler.process(order);
    }
}
public class OderAmountCalcuate extends Handler {
    @Override
    public void process(OrderInfo order) {
        System.out.println("OderAmountCalcuate----");
        handler.process(order);
    }
}
public class OderCreate extends Handler {

    @Override
    public 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被创建,避免线程安全问题的发生。

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

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

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

相关文章

深度学习之基于YoloV5的道路地面缺陷检测系统(UI界面)

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、道路地面缺陷检测系统四. 总结 一项目简介 基于YoloV5的道路地面缺陷检测系统利用深度学习中的目标检测算法,特别是YoloV5算法&am…

antd Cascader级联菜单无法赋值回显问题

说起来太丢人了,自己还拿官网例子在这里调试半天,最后发现是一个特别小儿科的问题哈哈 Cascader级联数据是服务端返回然后自己处理过的,使用了cascader的fileNames属性重置字段名,最后发现服务端回传的数据无法赋值回显在组件上&…

vscode设置保存后,自动格式化代码

第一步:打开setting.json文件 第二步:在setting.json中加入以下代码 "editor.formatOnType": true, "editor.formatOnSave": true, "editor.formatOnPaste": true

开发小程序需要多少钱?

随着移动互联网的快速发展,小程序已经成为了企业、个人创业者获取用户、提升品牌影响力的重要工具。然而,对于许多初次接触小程序的人来说,开发小程序需要多少钱,是他们最关心的问题。 首先我们需要明确的是,开发小程…

算法题:870. 优势洗牌

该算法是临时想出来的,Java代码的实现在时间上不占优,之后有时间要优化一下,目前就是给大家提供一下思路。 解题思路:田忌赛马的思想 贪心法。 Step1. 对两个数组进行排序。 Step2. 同时遍历排序后的nums2和nums1,将…

C++初阶(八)类和对象

📘北尘_:个人主页 🌎个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 文章目录 一、Static成员1、Static概念2、Static特性3、试题 二、友元1、友元的类型2、友元函数3、 友元…

nexus搭建npm私有镜像

假设有一个nexus服务,地址为: http://10.10.33.50:8081/ 创建存储空间 登录后创建存储空间,选择存储类型为File,并设置空间名称为 npm-private 创建仓库类型 2.1 创建hosted类型仓库 创建一个名为 npm-hosted 的本地类型仓库 2.…

毅速丨3D打印在零件修复上潜力巨大

随着科技的飞速发展,3D打印技术逐渐渗透到各个领域,在零件修复方面,3D打印也展现出巨大的潜力和优势。 3D打印技术是一种基于数字模型文件的制造技术,采用逐层堆积材料的方式来制造物体。它具有制造复杂形状零件的能力&#xff0c…

【2024最新】HBuilder X3.1.22【安装】零基础入门到精通,看完这一篇就够了【附安装链接】

软件下载 软件:HBuilder X版本:3.1.22语言:简体中文大小:278.95M安装环境:Win11/Win10/Win8/Win7硬件要求:CPU2.0GHz 内存4G(或更高)下载通道①百度网盘丨下载链接:https://pan.bai…

HNU程序设计 练习四-数组(强化)

1.快速公交BRT 【问题描述】 在城市里,快速公交(BRT)线路为一条直线,在其线路上有 n 个交叉路口,在每个路口都有一个交通信号灯,在红灯与绿灯之间周期性循环。 在绿灯亮起持续 g 秒的期间,允许…

【C++】类和对象(中)之拷贝构造与运算符、操作符重载

👀樊梓慕:个人主页 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》 🌝每一个不曾起舞的日子,都是对生命的辜负 前言 我们继续学习默认成员函数,本篇文…

线扫相机DALSA-相机平场矫正详细步骤

在相机视野下铺放白色亚克力板或纯白纸,采集图像。打开曲线图。 选择 Line Profile 模式。调节好相应所需的曝光时间、光源、增益和镜头光圈,让白平衡纸显示出来的灰度值大概在 150-200 左右。 在Calibration Algorithm 中将显示的数值设置好。 先暗场…

jbase实现业务脚本化

经过晚上和早上的努力,终于补上框架最后一块了,业务脚本侦听变化后自动编译jar包和调用,实现维护成本低,开发效率高的框架的基本体系。 实现自动编译jar包的类 package appcode;import org.w3c.dom.Document; import org.w3c.do…

无感刷新 token

文章目录 背景基本思路需解决的问题请求进入死循环标记刷新 token 请求避免请求拦截覆盖 refresh token并发刷新 token 完整代码注意:拦截器注册顺序另一种方案:事件驱动刷新 前景提要: ts 简易封装 axios,统一 API 实现在 confi…

海康Visionmaster调试脚本:对脚本进行调试的方法

第一步,在脚本模块中使用导出工程功能,将模块中的代码导出 第二步,找到导出的工程,并打开 第三步,生成解决方案,设置断点,点击 VS 菜单调试中的附加到进程,选择 ShellModuleManage…

计算虚拟化1——CPU虚拟化

目录 vCPU的概念 vCPU和CPU的关系 CPU的Ring级别 CPU虚拟化技术 软件辅助全虚拟化 半虚拟化 硬件辅助虚拟化 计算资源的虚拟化可以分为CPU虚拟化、内存虚拟化、I/O虚拟化三个方面 CPU虚拟化:多个虚拟机共享CPU资源,对虚拟机中的敏感指令进行截获…

EntherNet IP通讯学习

# 哎 最近接触ENIP通讯,但是觉得这玩意真的挺复杂的,主要是资料太少了。 好像大家都在保密一样。 1、学习这个通讯一定是因为实际工作中有用到,所以这个时候你一定有一个PLC做了从站。 OK,那下面继续学习吧! 首先先上…

数智赋能!麒麟信安参展全球智慧城市大会

10月31日至11月2日,为期三天的2023全球智慧城市大会长沙在湖南国际会展中心举办,大会已连续举办12届,是目前全球规模最大、专注于城市和社会智慧化发展及转型的主题展会。长沙市委常委、常务副市长彭华松宣布开幕,全球智慧城市大会…

TypeScript 第一站概念篇

前言 🔮 好长一段时间没有写文章了,原因是经历了一次工作变动,加入了一个有一定规模的开发团队,前端算上我有四个人,很欣慰,体验一下团队配合的感觉,在我之上有一个组长,比我年长四…

Mozilla Firefox 119 现已可供下载

Mozilla Firefox 119 开源网络浏览器现在可以下载了,是时候先看看它的新功能和改进了。 Firefox 119 改进了 Firefox View 功能,现在可以提供更多内容,如最近关闭的标签页和浏览历史,你可以按日期或网站排序,还支持查…