设计模式八股文

什么是设计模式?

设计模式是软件开发过程中经常遇到的问题的通用解决方案类似于前人总结的经验,遇到相似问题的时候有个参考。

设计模式七大基本原则?

  • 单一职责:一个类应该只作一件事情。将功能分为小的独立的单元。
  • 开放封闭原则:对扩展开放,对修改关闭。
  • 里氏替换原则:任何一个父类出现的地方,都可以用子类替换,而不会导致错误或者异常。
  • 依赖倒置:高层模块不应该依赖于底层,应该依赖于抽象,实现解耦。
  • 接口隔离:一个类不应该强迫它的客户端依赖于它们不需要的方法,接口应该小而专注,不应该包含多余的方法。

责任链模式?

  • 一种行为型设计模式,使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合。
  • 请求沿着链传递,直到有对象处理为止。
  • 分为三个角色:
    • Handler:抽象处理者,定义了一个处理请求的接口或者抽象类,通常会包含一个指向链中下一个处理者的引用。
    • ConcreteHandler:具体处理者,实现抽象处理者的处理方法,如果能处理就处理,不能就转发给下一个。
    • client:客户端,创建处理链,并向链的第一个处理者对象提交请求。
  • 工作流程:
    • 客户端将请求发送给链上的第一个处理者对象
    • 接收到请求后是否能处理
      • 可以就处理
      • 不可以就转发给链上的下一个处理者
    • 过程重复
  • 场景:
    • 过滤器链
    • 日志记录
    • 异常处理
    • 认证授权
  • 优缺点:
    • 降低耦合度
  • 实际举例:
    • 比如在线商店,用户下单的时候需要
      • 检查订单信息是否完整
      • 检查商品库存是否充足
      • 检查用户余额是否充足
      • 确认订单,更新商品库存和用户余额
public interface OrderHandler{void handler(Order order);
}
public class CheckOrderHandler implements OrderHandler {private OrderHandler next;public CheckOrderHandler(OrderHandler next) {this.next = next;}@Overridepublic void hand1e(Order order) {
//检查订单信息是否完整if (order.isInfoComplete()) {
//如果订单信息完整,则将请求传递给下一个处理者next.handle(order);} else {
//如果订单信息不完整,则直接返回错误信息throw new RuntimeException("订 单信息不完整");}}public class CheckStockHandler implements OrderHandler {private OrderHandler next;public CheckStockHandler(OrderHandler next) {this.next = next;}@Overridepublic void hand1e(Order order) {
//检查商品库存是否充足.if (order.getStock() >= order.getQuantity()) {
//如果库存充足,则将请求传递给下一个处理者next.handle(order); } else {
//如果库存不足,则直接返回错误信息throw new RuntimeException(" 商品库存不足");}}}public class CheckBalanceHandler implements OrderHandler {private OrderHandler next;public CheckBalanceHandler(OrderHandler next) {this.next = next;}@Overridepublic void hand1e(Order order) {
//检查用户余额是否充足.if (order.getBalance() >= order.getAmount()) {
//如果余额充足,则将请求传递给下一个处理者.next.handle(order); } else {
//如果余额不足,则直接返回错误信息throw new RuntimeException("用户 余额不足");}}}public class ConfirmOrderHandler implements OrderHandler {@Overridepublic void handle(Order order) {
//确认订单,更新商品库存和用户余额order.confirm();}}
//客户端代码示例CheckOrderHandler checkOrderHandler = newCheckOrderHandler();CheckStockHandler checkStockHandler = new CheckStockHand1er();CheckBalanceHandler checkBalanceHandler = new CheckBalanceHandler();ConfirmOrderHandler confirmOrderHandler =newConfirmOrderHand1er();
//将处理器按照一定顺序组成责任链checkOrderHand1er.setNext(checkStockHandler);checkStockHand1er.setNext(checkBalanceHandler);checkBalanceHand1er.setNext(confirmOrderHandler);// 处理订单Order order = new Order();checkOrderHandler.handle(order);

工厂模式?

  • 创建型设计模式主要创建对现象,而不暴露对象的逻辑给客户端。
  • 简单工厂
    • 简单工厂模式的角色包括三个:

      • 抽象产品 角色

      • public abstract class Weapon {/*** 所有的武器都有攻击行为*/public abstract void attack();
        }
      • 具体产品角色

      • public class Tank extends Weapon{@Overridepublic void attack() {System.out.println("坦克开炮!");}
        }/*** 战斗机(具体产品角色)* @version 1.0* @className Fighter* @since 1.0**/
        public class Fighter extends Weapon{@Overridepublic void attack() {System.out.println("战斗机投下原子弹!");}
        }/*** 匕首(具体产品角色)* @version 1.0* @className Dagger* @since 1.0**/
        public class Dagger extends Weapon{@Overridepublic void attack() {System.out.println("砍他丫的!");}
        }
      • 工厂类 角色

      • public class WeaponFactory {/*** 根据不同的武器类型生产武器* @param weaponType 武器类型* @return 武器对象*/public static Weapon get(String weaponType){if (weaponType == null || weaponType.trim().length() == 0) {return null;}Weapon weapon = null;if ("TANK".equals(weaponType)) {weapon = new Tank();} else if ("FIGHTER".equals(weaponType)) {weapon = new Fighter();} else if ("DAGGER".equals(weaponType)) {weapon = new Dagger();} else {throw new RuntimeException("不支持该武器!");}return weapon;}
        }

        优点:不需要关注对象创建细节,要什么对象直接向工厂要就可以,初步实现了生产和消费的分离。缺点:工厂为上帝类,不能出问题;不符合OCP开闭原则,扩展时需要修改工厂类。

      • spring通过依赖注入和面向接口编程解决

  • 工厂方法
    • 工厂方法模式既保留了简单工厂模式的优点,同时又解决了简单工厂模式的缺点。

      工厂方法模式的角色包括:

      • 抽象工厂角色

      • 
        /*** 武器工厂接口(抽象工厂角色)* @author 动力节点* @version 1.0* @className WeaponFactory* @since 1.0**/
        public interface WeaponFactory {Weapon get();
        }
      • 具体工厂角色

      • /*** 具体工厂角色* @author 动力节点* @version 1.0* @className GunFactory* @since 1.0**/
        public class GunFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Gun();}
        }
        package com.powernode.factory;/*** 具体工厂角色* @author 动力节点* @version 1.0* @className FighterFactory* @since 1.0**/
        public class FighterFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Fighter();}
        }

      • 抽象产品角色

      • /*** 武器类(抽象产品角色)* @author 动力节点* @version 1.0* @className Weapon* @since 1.0**/
        public abstract class Weapon {/*** 所有武器都有攻击行为*/public abstract void attack();
        }
      • 具体产品角色

      • /*** 具体产品角色* @author 动力节点* @version 1.0* @className Gun* @since 1.0**/
        public class Gun extends Weapon{@Overridepublic void attack() {System.out.println("开枪射击!");}
        }
        package com.powernode.factory;/*** 具体产品角色* @author 动力节点* @version 1.0* @className Fighter* @since 1.0**/
        public class Fighter extends Weapon{@Overridepublic void attack() {System.out.println("战斗机发射核弹!");}
        }

        扩展时增加一个产品+工厂,缺点:类爆炸

  • 抽象工厂模式:

    • 抽象工厂中包含4个角色:

      • 抽象工厂角色

      • public abstract class AbstractFactory {public abstract Weapon getWeapon(String type);public abstract Fruit getFruit(String type);
        }
      • 具体工厂角色

      • public class WeaponFactory extends AbstractFactory{public Weapon getWeapon(String type){if (type == null || type.trim().length() == 0) {return null;}if ("Gun".equals(type)) {return new Gun();} else if ("Dagger".equals(type)) {return new Dagger();} else {throw new RuntimeException("无法生产该武器");}}@Overridepublic Fruit getFruit(String type) {return null;}
        }public class FruitFactory extends AbstractFactory{@Overridepublic Weapon getWeapon(String type) {return null;}public Fruit getFruit(String type){if (type == null || type.trim().length() == 0) {return null;}if ("Orange".equals(type)) {return new Orange();} else if ("Apple".equals(type)) {return new Apple();} else {throw new RuntimeException("我家果园不产这种水果");}}
        }
      • 抽象产品角色

      • 具体产品角色

      • public abstract class Weapon {public abstract void attack();
        }
        package com.powernode.product;public class Gun extends Weapon{@Overridepublic void attack() {System.out.println("开枪射击!");}
        }public class Dagger extends Weapon{@Overridepublic void attack() {System.out.println("砍丫的!");}
        }

        优点:能保证一个工厂只使用一个类型的

        • 缺点:不符合OCP、

单例模式?

见另一篇

策略模式和模板设计模式?

  • 策略模式定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。策略模式让算法独立于使用它的客户而变化。
  • // 定义策略接口
    public interface PaymentStrategy {void pay(int amount);
    }// 具体策略类:信用卡支付
    public class CreditCardPaymentStrategy implements PaymentStrategy {private String cardNumber;public CreditCardPaymentStrategy(String cardNumber) {this.cardNumber = cardNumber;}@Overridepublic void pay(int amount) {System.out.println("Paid " + amount + " using Credit Card: " + cardNumber);}
    }// 具体策略类:PayPal支付
    public class PayPalPaymentStrategy implements PaymentStrategy {private String email;public PayPalPaymentStrategy(String email) {this.email = email;}@Overridepublic void pay(int amount) {System.out.println("Paid " + amount + " using PayPal: " + email);}
    }// 环境类:使用策略
    public class ShoppingCart {private PaymentStrategy paymentStrategy;public void setPaymentStrategy(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}public void checkout(int amount) {paymentStrategy.pay(amount);}
    }// 客户端代码
    public class Main {public static void main(String[] args) {ShoppingCart cart = new ShoppingCart();// 使用信用卡支付cart.setPaymentStrategy(new CreditCardPaymentStrategy("1234-5678-9012-3456"));cart.checkout(100);// 使用PayPal支付cart.setPaymentStrategy(new PayPalPaymentStrategy("example@example.com"));cart.checkout(200);}
    }
    

  • 模板方法模式:
    • 模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
    • // 抽象类,定义模板方法和抽象方法
      public abstract class Game {// 模板方法public final void play() {initialize();startPlay();endPlay();}protected abstract void initialize();protected abstract void startPlay();protected abstract void endPlay();
      }// 具体类:足球游戏
      public class Football extends Game {@Overrideprotected void initialize() {System.out.println("Football Game Initialized! Start playing.");}@Overrideprotected void startPlay() {System.out.println("Football Game Started. Enjoy the game!");}@Overrideprotected void endPlay() {System.out.println("Football Game Finished!");}
      }// 具体类:篮球游戏
      public class Basketball extends Game {@Overrideprotected void initialize() {System.out.println("Basketball Game Initialized! Start playing.");}@Overrideprotected void startPlay() {System.out.println("Basketball Game Started. Enjoy the game!");}@Overrideprotected void endPlay() {System.out.println("Basketball Game Finished!");}
      }// 客户端代码
      public class Main {public static void main(String[] args) {Game game = new Football();game.play();game = new Basketball();game.play();}
      }
      
       结合:
    • // 定义支付策略接口
      public interface PaymentStrategy {void pay(int amount);
      }// 具体支付策略类:信用卡支付
      public class CreditCardPaymentStrategy implements PaymentStrategy {private String cardNumber;public CreditCardPaymentStrategy(String cardNumber) {this.cardNumber = cardNumber;}@Overridepublic void pay(int amount) {System.out.println("Paid " + amount + " using Credit Card: " + cardNumber);}
      }// 具体支付策略类:PayPal支付
      public class PayPalPaymentStrategy implements PaymentStrategy {private String email;public PayPalPaymentStrategy(String email) {this.email = email;}@Overridepublic void pay(int amount) {System.out.println("Paid " + amount + " using PayPal: " + email);}
      }
      
      // 抽象类,定义支付流程的模板方法
      public abstract class PaymentProcess {private PaymentStrategy paymentStrategy;public PaymentProcess(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}// 模板方法public final void processPayment(int amount) {selectItem();enterShippingDetails();if (confirmOrder()) {makePayment(amount);}sendReceipt();}protected void selectItem() {System.out.println("Item selected.");}protected void enterShippingDetails() {System.out.println("Shipping details entered.");}protected boolean confirmOrder() {System.out.println("Order confirmed.");return true;}protected void makePayment(int amount) {paymentStrategy.pay(amount);}protected void sendReceipt() {System.out.println("Receipt sent to customer.");}
      }// 具体的支付流程类可以根据需要进行扩展
      public class OnlineStorePaymentProcess extends PaymentProcess {public OnlineStorePaymentProcess(PaymentStrategy paymentStrategy) {super(paymentStrategy);}@Overrideprotected void selectItem() {System.out.println("Item selected from online store.");}@Overrideprotected void enterShippingDetails() {System.out.println("Online store shipping details entered.");}@Overrideprotected void sendReceipt() {System.out.println("Online store receipt sent to customer.");}
      }
      

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

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

相关文章

CTF之Web_python_block_chain

这种题对于我来说只能看大佬的wp(但是这一题是wp都看不懂,只能表达一下我的理解了) (最后有简单方法,前面一种没看懂没关系) 下面这一部分是首页的有用部分 访问/source_code,得到源码: # -*-…

qt post请求 c++ 解压缩文件

目录 qt post请求 c下载代码: 默认下载保存路径: linux qt调用 unzip进行解压缩 pro文件配置: QT network qt post请求 c下载代码: #include "mainwindow.h" #include "ui_mainwindow.h" #include &…

ffmpeg怎么将vtt文件添加到视频中

FFmpeg 是一个非常强大的多媒体框架,可以用来处理音频、视频以及字幕文件。要将 WebVTT(.vtt)字幕文件添加到视频文件中,你可以使用 ffmpeg 的 subtitles 过滤器。以下是基本的命令格式: ffmpeg -i input_video.mp4 -…

VSCode搭建Markdown编辑环境

1. 本文目标2. 准备工作3. 安装插件4. 插件的用法 4.1. Markdown All in One 4.1.1. 快捷键4.1.2. 创建/更新目录4.1.3. 给标题增加序号 4.2. Markdown Table 4.2.1. 格式化表格4.2.2. 插入表格列 4.3. Markdown PDF VSCode是笔者用过的最好用的开发工具,没有之一…

宁夏银川、山东济南、中国最厉害的改名大师的老师颜廷利教授的前沿思想观点

在当代社会,一个响亮的声音穿越了传统的迷雾,它来自东方哲学的殿堂,由一位现代学者颜廷利教授所发出。他的话语,如同一股清泉,在混沌的世界里激荡着思考的波澜:"有‘智’不在年高,无‘智’…

太空几乎没有阻力,飞船理论上能一直加速,为何还说星际旅行很难

太空几乎没有阻力,飞船理论上能一直加速,为何还说星际旅行很难? 答案 现代科学认为,我们的地球诞生于46亿年前,也就是太阳系诞生初期,在太阳系中一共有八大行星,而地球是唯一一颗诞生了生命的…

起保停电路工作原理

一、电路组成 起保停电路由电源保护设备(空气开关)、交流接触器、启动按钮、停止按钮和用电设备组成。 起保停电路的组成部分通常可分为四个部分: 保护部分:(空气开关)在电流或电压超出一定范围时自动切断…

异步获取线程执行结果,JDK中的Future、Netty中的Future和Promise对比

JDK中的Future和Netty中的Future、Promise的关系 三者源头追溯 Netty中的Future与JDK中的Future同名,但是是两个不同的接口。Netty中的Future继承自JDK的Future,而Promise又对Netty中的Future进行了扩展。 JDK中的Future源自JUC并发包: Net…

电商API接口(api商品数据)【电商商品实时数据采集API接口】

众多品牌选择电商API实时数据采集接口进行采购,主要是出于以下几个重要原因: 第一,高效便捷。比价工具通过自动化的方式获取价格信息,避免了繁琐的人工操作,大大节省了时间和精力。 第二,精准比较。API比价…

如何使用ssh将vscode 连接到服务器上,手把手指导

一、背景 我们在开发时,经常是window上安装一个vscode编辑器,去连接一个虚拟机上的linux,这里常用的是SSH协议,了解其中的操作非常必要。 二、SSH协议 SSH(Secure Shell)是一种安全协议,用于…

redis的基本命令

数据库相关操作 Redis默认 16 个数据库,默认使⽤第 0个 select 0 # 切换数据库 dbsize # 查看数据库⼤⼩ flushall # 清除全部库数据 flushdb # 清空当前库数据 key相关的操作 keys * # 查看所有的key exists key # 判断当前key 是否存在。 expire ke…

C#屏蔽基类成员

可以用与积累成员名称相同的成员来屏蔽 要让编译器知道你在故意屏蔽继承的成员,可以用new修饰符。否则程序可以成功编译,但是编译器会警告你隐藏了一个继承的成员 using System;class someClass {public string F1 "Someclass F1";public v…

React18+TypeScript搭建通用中后台项目实战04 封装常用工具函数

接口请求参数类型 修改 src/api/request.ts 核心代码&#xff1a; // GET 请求 // param url 请求地址 // param params 查询参数 // return 返回Promise对象&#xff0c;内部类型是泛型 function get<T>(url: string, params: object): Promise<T> {return req…

YOLOv10 | 手把手教你利用yolov10训练自己数据集(含环境搭建 + 参数解析 + 数据集查找 + 模型训练、推理、导出)

一、前言 本文内含YOLOv10网络结构图 各个创新模块手撕结构图 训练教程 推理教程 参数解析 环境搭建 数据集获取等一些有关YOLOv10的内容&#xff01; 目录 一、 前言 二、整体网络结构图 三、空间-通道分离下采样 3.1 SCDown介绍 3.2 C2fUIB介绍 3.3 PSA介绍 …

微服务下认证授权框架的探讨

前言 市面上关于认证授权的框架已经比较丰富了,大都是关于单体应用的认证授权,在分布式架构下,使用比较多的方案是--<应用网关>,网关里集中认证,将认证通过的请求再转发给代理的服务,这种中心化的方式并不适用于微服务,这里讨论另一种方案--<认证中心>,利用jwt去中…

【数据库基础-mysql详解之索引的魅力(N叉树)】

索引的魅力目录 &#x1f308;索引的概念&#x1f308;使用场景&#x1f308;索引的使用&#x1f31e;&#x1f31e;&#x1f31e;查看MySQL中的默认索引&#x1f31e;&#x1f31e;&#x1f31e;创建索引&#x1f31e;&#x1f31e;&#x1f31e;删除索引 站在索引背后的那个男…

sheng的学习笔记-docker部署Greenplum

目录 docker安装gp数据库 mac版本 搭建gp数据库 连接数据库 windows版本 搭建gp数据库 连接数据库 docker安装gp数据库 mac版本 搭建gp数据库 打开终端&#xff0c;输入代码&#xff0c;查看版本 ocker search greenplum docker pull projectairws/greenplum docker…

Virtual Box安装Ubuntu及设置

Virtual Box安装Ubuntu及设置 本文包含以下内容&#xff1a; 使用Virtual Box安装Ubuntu Desktop。设置虚拟机中的Ubuntu&#xff0c;使之可访问互联网并可通过SSH访问。 Ubuntu Desktop下载 从官网下载&#xff0c;地址为&#xff1a;Download Ubuntu Desktop | Ubuntu U…

HTTP交互导致ECONNABORTED的原因之一

背景&#xff1a; 本次记录的&#xff0c;是一次使用HTTP交互过程中遇到的问题&#xff0c;问题不大&#xff0c;就是给题目上这个报错补充一种可能的解决方案。 程序大致流程&#xff1a; 1. 设备向服务器A请求信息 2. 拿到回复记录下回复内容中的数据包下载地址等信息 3…

games 101 作业4

games 101 作业4 题目题解作业答案 题目 Bzier 曲线是一种用于计算机图形学的参数曲线。在本次作业中&#xff0c;你需要实 现 de Casteljau 算法来绘制由 4 个控制点表示的 Bzier 曲线 (当你正确实现该 算法时&#xff0c;你可以支持绘制由更多点来控制的 Bzier 曲线)。 你需…