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

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.rhkb.cn/news/181616.html

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

相关文章

POJ-3630电话表(考察字典树)

2023每日刷题&#xff08;二十&#xff09; POJ-3630电话表 题目原地址 输入样例&#xff1a; 2 3 911 97625999 91125426 5 113 12340 123440 12345 98346输出结果&#xff1a; NO YES实现代码 #include<iostream> #include<string> #include<cstring>…

刚入职因为粗心大意,把事情办砸了,十分后悔

刚入职&#xff0c;就踩大坑&#xff0c;相信有很多朋友有我类似的经历。 5年前&#xff0c;我入职一家在线教育公司&#xff0c;新的公司福利非常好&#xff0c;各种零食随便吃&#xff0c;据说还能正点下班&#xff0c;一切都超出我的期望&#xff0c;“可算让我找着神仙公司…

[vmware]vmware虚拟机压缩空间清理空间

vmware中的ubuntu使用如果拷贝文件进去在删除&#xff0c;vmare镜像文件并不会减少日积月累会不断是的真实物理磁盘空间大幅度减少&#xff0c;比如我以前windows操作系统本来只有30GB最后居然占道硬盘200GB&#xff0c;清理方法有2种。 第一种&#xff1a;vmware界面操作 第二…

uniapp自定义权限菜单,动态tabbar

已封装为组件&#xff0c;亲测4个菜单项目可以切换&#xff0c; 以下为示例&#xff0c;根据Storage 中 userType 的 值&#xff0c;判断权限菜单 <template><view class"tab-bar pb10"><view class"tabli" v-for"(tab, index) in ta…

matplotlib从起点出发(10)_Tutorial_10_Layout

使用受约束的绘图干净整洁地将图形合适排列。 受约束的布局会自动调整子图&#xff0c;以便刻度标签、图例和颜色条等装饰不会重叠&#xff0c;同时仍保留用户请求的逻辑布局。 受约束布局类似于“紧密布局”&#xff0c;但它要更灵活。它处理放置在多个轴上的Axes(放置颜色条…

6.Spark共享变量

概述 共享变量 共享变量的工作原理Broadcast VariableAccumulator 共享变量 共享变量的工作原理 通常&#xff0c;当给 Spark 操作的函数(如 mpa 或 reduce) 在 Spark 集群上执行时&#xff0c;函数中的变量单独的拷贝到各个节点上&#xff0c;函数执行时&#xff0c;使用…

zookeeper节点类型

节点类型 持久节点&#xff08;Persistent Nodes&#xff09; 这些是Zookeeper中最常见的一种节点类型&#xff0c;当创建一个持久类型节点时&#xff0c;该值会一直存在zookeeper中&#xff0c;直到被显式删除或被新值覆盖。 临时节点&#xff08;Ephemeral Nodes&#xff…

STM32中微秒延时的实现方式

STM32中微秒延时的实现方式 0.前言一、裸机实现方式二、FreeRTOS实现方式三、定时器实现&#xff08;通用&#xff09;4、总结 0.前言 最近在STM32驱动移植过程中需要用到微秒延时来实现一些外设的时序&#xff0c;由于网上找到的驱动方法良莠不齐&#xff0c;笔者在实现时序过…

【数据结构】败者树的建树与比较过程

文章目录 前置知识归并段 建树过程比较过程疑问为什么比较次数减少了&#xff1f;如果某个归并段的元素一直获胜&#xff0c;没有元素了怎么办&#xff1f;处理方法 1处理方法 2 前置知识 归并段 外部排序算法通常用于处理大规模数据&#xff0c;其中数据量远超过计算机内存的…

修改一下第二次课服务枚举等问题

关于AutoRuns 的总结里面&#xff0c;有个错误&#xff0c;Image hijacks 这个准确的描述应该是镜像劫持 和系统运行相关的image&#xff0c;我们通常指的是二进制镜像文件 Image hijacks镜像劫持 简单来说就是&#xff0c;在注册表中&#xff0c;有部分设置&#xff0c;是规…

产品经理入门学习(五):思维导图 原型设计

参考引用 黑马-产品经理入门基础课程 1. 思维导图的作用和应用场景 什么是思维导图&#xff1f; 思维导图是一种将思维进行可视化的实用工具。具体实现方法是用一个关键词去引发相关想法&#xff0c;再运用图文并茂的技巧把各级主题的关系用相互隶属的层级表现出来&#xff0c;…

Flutter笔记:发布一个模块 scale_design - (移动端)设计师尺寸适配工具

Flutter笔记 发布一个模块scale_design设计师尺寸适配工具与常用组件库 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/a…

容器核心技术-Namespace

一、容器 基于Linux 内核的 Cgroup&#xff0c; Namespace&#xff0c;以及Union FS等技术&#xff0c;对进程进行封装隔离&#xff0c;属于操作系统层面的虚拟化技术&#xff0c;由于隔离的进程独立于宿主和其它的隔离的进程&#xff0c;因此也称其为容器。 1.1 容器主要特性…

中国电子学会主办 第四届ATEC科技精英赛报名启动

11月1日由中国电子学会主办的第四届ATEC科技精英赛&#xff08;ATEC2023&#xff09;正式启动报名。 ATEC科技精英赛是主要面向中国籍计算机等专业在校学生、人工智能及网络安全行业研究者和从业者的一场高水平的智能科技挑战赛&#xff0c;意在贯彻落实党中央、国务院关于推动…

性能优化之懒加载 - 基于观察者模式和单例模式的实现

一、引入 在前端性能优化中&#xff0c;关于图片/视频等内容的懒加载一直都是优化利器。当用户看到对应的视图模块时&#xff0c;才去请求加载对应的图像。 原理也很简单&#xff0c;通过浏览器提供的 IntersectionObserver - Web API 接口参考 | MDN (mozilla.org)&#xff0c…

SpringSecurity全家桶 (二) ——实现原理

1. SpringSecurity的强大之处 当我们并未设置登录页面时&#xff0c;我们只需要导入SpringSecurity的依赖就可以令我们的界面进入保护状态&#xff0c;由下面例子可以凸显出&#xff1a; 随便写个接口 RequestMapping("/hello")public String hello(){return "H…

旧手机搭建linuxcentos

centos服务器搭建termux搭建centos旧手机搭建linux服务器ubuntu旧手机搭建网站旧手机搭建linux debian ubuntu centos 旧手机搭建宝塔搭建 32位Linux搭建宝塔 Linuxdeploy搭建宝塔 旧手机搭建服务器有需要的来 包答疑包售后 Linuxdeploy需要root mobile搭建服务器 脚本/工具

03 矩阵与线性变换

矩阵与线性变换 线性变换如何用数值描述线性变换特殊的线性变换反过来看总结 这是关于3Blue1Brown "线性代数的本质"的学习笔记。 线性变换 如果一个变换具有以下两个性质&#xff0c;我们就称它是线性的&#xff1a; 一是直线在变换后仍然保持为直线二是原点必须…

网安新旅程

网安新旅程 将近四个月没发博客了&#xff0c;今天交代一下最近发生的事情和规划。 TryHackMyOffsecBox QQ交流 君羊&#xff1a;751273347 近期的事情 6月开始我进入htb学院学习CPTS&#xff0c;7月左右我完成了95%左右的内容。7-8月份我基本都在做C#相关的开发&#xff0c…

【KVM】KVM介绍及功能概述

前言 大家好&#xff0c;我是秋意零。 今天介绍的内容是KVM的概述&#xff0c;以及它所支持的基本功能。 &#x1f47f; 简介 &#x1f3e0; 个人主页&#xff1a; 秋意零&#x1f525; 账号&#xff1a;全平台同名&#xff0c; 秋意零 账号创作者、 云社区 创建者&#x1f…