设计模式八股文

news2024/9/25 5:21:59

什么是设计模式?

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

设计模式七大基本原则?

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

责任链模式?

  • 一种行为型设计模式,使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合。
  • 请求沿着链传递,直到有对象处理为止。
  • 分为三个角色:
    • 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;
    }

    @Override
    public 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;
        }

        @Override
        public 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;
        }

        @Override
        public void hand1e(Order order) {
//检查用户余额是否充足.
            if (order.getBalance() >= order.getAmount()) {
//如果余额充足,则将请求传递给下一个处理者.
                next.handle(order); 
            } else {
//如果余额不足,则直接返回错误信息
                throw new RuntimeException("用户 余额不足");
            }
        }
    }

    public class ConfirmOrderHandler implements OrderHandler {
        @Override
        public void handle(Order order) {
//确认订单,更新商品库存和用户余额
            order.confirm();
        }
    }


//客户端代码示例
        CheckOrderHandler checkOrderHandler = new
                CheckOrderHandler();
        CheckStockHandler checkStockHandler = new CheckStockHand1er();
        CheckBalanceHandler checkBalanceHandler = new CheckBalanceHandler();
        ConfirmOrderHandler conf
        irmOrderHandler =new

                ConfirmOrderHand1er();
//将处理器按照一定顺序组成责任链
        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{
            @Override
            public void attack() {
                System.out.println("坦克开炮!");
            }
        }
        
        
        /**
         * 战斗机(具体产品角色)
         * @version 1.0
         * @className Fighter
         * @since 1.0
         **/
        public class Fighter extends Weapon{
            @Override
            public void attack() {
                System.out.println("战斗机投下原子弹!");
            }
        }
        
        
        /**
         * 匕首(具体产品角色)
         * @version 1.0
         * @className Dagger
         * @since 1.0
         **/
        public class Dagger extends Weapon{
            @Override
            public 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{
            @Override
            public Weapon get() {
                return new Gun();
            }
        }
        package com.powernode.factory;
        
        /**
         * 具体工厂角色
         * @author 动力节点
         * @version 1.0
         * @className FighterFactory
         * @since 1.0
         **/
        public class FighterFactory implements WeaponFactory{
            @Override
            public 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{
            @Override
            public void attack() {
                System.out.println("开枪射击!");
            }
        }
        package com.powernode.factory;
        
        /**
         * 具体产品角色
         * @author 动力节点
         * @version 1.0
         * @className Fighter
         * @since 1.0
         **/
        public class Fighter extends Weapon{
            @Override
            public 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("无法生产该武器");
                }
            }
        
            @Override
            public Fruit getFruit(String type) {
                return null;
            }
        }
        
        
        
        public class FruitFactory extends AbstractFactory{
            @Override
            public 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{
            @Override
            public void attack() {
                System.out.println("开枪射击!");
            }
        }
        
        public class Dagger extends Weapon{
            @Override
            public 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;
        }
    
        @Override
        public 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;
        }
    
        @Override
        public 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 {
          @Override
          protected void initialize() {
              System.out.println("Football Game Initialized! Start playing.");
          }
      
          @Override
          protected void startPlay() {
              System.out.println("Football Game Started. Enjoy the game!");
          }
      
          @Override
          protected void endPlay() {
              System.out.println("Football Game Finished!");
          }
      }
      
      // 具体类:篮球游戏
      public class Basketball extends Game {
          @Override
          protected void initialize() {
              System.out.println("Basketball Game Initialized! Start playing.");
          }
      
          @Override
          protected void startPlay() {
              System.out.println("Basketball Game Started. Enjoy the game!");
          }
      
          @Override
          protected 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;
          }
      
          @Override
          public 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;
          }
      
          @Override
          public 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);
          }
      
          @Override
          protected void selectItem() {
              System.out.println("Item selected from online store.");
          }
      
          @Override
          protected void enterShippingDetails() {
              System.out.println("Online store shipping details entered.");
          }
      
          @Override
          protected void sendReceipt() {
              System.out.println("Online store receipt sent to customer.");
          }
      }
      

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

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

相关文章

【mysql】更新操作是如何执行的

现有一张表,建表语句如下: mysql> create table T(ID int primary key, c int);如果要将 ID2 这一行的a字段值加 1,SQL语句会这么写: mysql> update T set c c 1 where ID 2;上面这条sql执行时,分析器会通过词…

springboot发送短信验证码,结合redis 实现限制,验证码有效期2分钟,有效期内禁止再次发送,一天内发送超3次限制

springboot结合redis发送短信验证码,实现限制发送操作 前言(可忽略)实现思路正题效果图示例手机号不符合规则校验图成功发送验证码示例图redis中缓存随机数字验证码,2分钟后失效删除redis缓存图验证码有效期内 返回禁止重复发送图验证码24小时内发送达到3次&#xf…

精通C++ STL(二):string类的模拟实现

目录 string类各函数接口总览 默认成员函数 构造函数 拷贝构造函数 赋值运算符重载函数 析构函数 迭代器相关函数 begin和end 容量和大小相关函数 size和capacity reserve和resize empty 修改字符串相关函数 push_back append operator insert erase clear swap c_str 访…

spring boot 之 结合aop整合日志

AOP 该切面仅用于请求日志记录&#xff0c;若有其他需求&#xff0c;在此基础上扩展即可&#xff0c;不多逼逼&#xff0c;直接上代码。 引入切面依赖 <!-- 切面 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>sp…

云主机选购指南:如何选择适合自己的云主机

一、认识移动云 移动云是中国移动提供的专业云服务品牌&#xff0c;基于移动云计算技术构建。它实现了云网一体化&#xff0c;确保客户享有安全可控的服务。通过充分利用移动云计算能力&#xff0c;打造了N31X资源布局&#xff0c;结合各省级数据中心&#xff0c;通过专线互联…

基于Vue的前端加载中页面动画——弹跳动画Loading组件的设计与实现

基于Vue的前端加载中页面动画——弹跳动画Loading组件的设计与实现 摘要 随着技术的飞速进步&#xff0c;前端开发的复杂性日益提升。传统的开发方式通常将整个系统构建为一个整体&#xff0c;导致即使是微小的改动或功能的增加也可能引起整体逻辑的变动。为了解决这个问题&a…

【蓝桥杯】国赛普及-

题目列表 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) P9420 [蓝桥杯 2023 国 B] 子 2023 / 双子数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<bits/stdc.h> using llunsigned long long; #define int ll const int N2e510; int k0; std::string s; int…

嵌入式UI开发-lvgl+wsl2+vscode系列:1、资料收集以及Windows下WSL2模拟环境运行示例demo

文章目录 一、前言二、资料收集三、Windows下WSL2上编译运行lvgl的demo程序1、lvgl简介2、lvgl特性3、配置要求4、Windows下vscodewsl2模拟环境搭建4.1、安装vscodewsl24.2、下载获取项目&#xff1a;4.3、安装显卡驱动4.4、下载lvgl并编译运行示例demo 四、最后 一、前言 UI界…

Python数据分析-心脏病(随机森林预测分析)

本次案例分析用心脏病数据集来做随机森林模型预测 导入基本的数据分析包 import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import accuracy_score…

云计算-关系型数据库(Relational Database)

关系数据库服务&#xff08;RDS&#xff09;&#xff08;Relational Database Service (RDS)&#xff09; Amazon RDS 可用于在云中设置和运行关系数据库。它支持多种数据库实例类型以及多个数据库引擎&#xff0c;如 Amazon Aurora、PostgreSQL、MySQL、MariaDB、Oracle 数据库…

基于Vue的应届毕业生财务管理系统-计算机毕业设计源码82886

摘 要 随着互联网大趋势的到来&#xff0c;社会的方方面面&#xff0c;各行各业都在考虑利用互联网作为媒介将自己的信息更及时有效地推广出去&#xff0c;而其中最好的方式就是建立网络管理系统&#xff0c;并对其进行信息管理。由于现在网络的发达&#xff0c;应届毕业生财务…

c# sqlite使用

安装包 使用 const string strconn "Data Sourcedata.db"; using (SQLiteConnection conn new SQLiteConnection(strconn)) {conn.Open();var cmd conn.CreateCommand();//创建表cmd.CommandText "create table t1(id int,name varchar(10))";var obj…

二百三十八、Hive——Hive中为每条数据创建唯一ID

一、目的 由于Kafka的JSON中缺少唯一的ID标识字段&#xff0c;因此发现后面的需求中DWD层表需要有一个唯一ID字段&#xff0c;这样才能与数据质量表更好的关联 二、Hive版本 尚硅谷的3.1.2版本 三、Hive创建唯一ID方法 网上的创建唯一ID方法有很多&#xff0c;这里展示一些…

子网划分,交换机原理与配置

子网划分 IP地址 IPv4由32位二进制数组成&#xff0c;一般用点分十进制来表示 IPv4是由32位二进制数组成&#xff0c;分成四组,第组八位。例如:11000000.10101000.00000000.00000010 为了便于配置通常表示成点分十进制形式例如:192.168.0.2 255.255.255.0 IPv6由128位组成&…

HDR视频相关标准-HDR vivid(二)

上文介绍了HDRvivid的一些技术。今天从全局角度来看看HDR视频的处理流程&#xff0c;HDR视频系统&#xff0c;即建立一个比SDR视频更大的色彩/亮度坐标体系&#xff0c;并改变系统的传输函数&#xff0c;以再现更大的色域(WCG)和更高的亮度动态范围。 菁彩 HDR技术的专业术语 …

充电宝哪个牌子好用?充电宝品牌怎么选?充电宝最好的牌子排名

现在市面上的充电宝品牌琳琅满目&#xff0c;但并不是所有的充电宝都安全可靠。据央视的一个报道&#xff0c;市面上有35%充电宝质量是不过关的!充电宝买不对就非常容易出现爆炸的一个情况&#xff0c;所以大家对选充电宝不仅能保障设备的安全。那么&#xff0c;充电宝哪个牌子…

TypeScript学习日志-第三十二天(infer关键字)

infer关键字 一、作用与使用 infer 的作用就是推导泛型参数&#xff0c;infer 声明只能出现在 extends 子语句中&#xff0c;使用如下&#xff1a; 可以看出 已经推导出类型是 User 了 二、协变 infer 的 协变会返回联合类型&#xff0c;如图&#xff1a; 三、逆变 infer…

FusionCharts 隐藏试用图标

1、找到fusioncharts.js文件 2、搜索“raphael-group-” 3、找到此处进行替换黄线部分 将&#xff1a;"a.setAttribute("class","raphael-group-"t)" 替换成"(a.setAttribute("class","raphael-group-"t),a.setAttr…

基于 Wireshark 分析 TCP 协议

一、TCP 协议 TCP&#xff08;Transmission Control Protocol&#xff09;是一种面向连接的、可靠的传输层协议。它在网络通信中扮演着重要的角色&#xff0c;用于保证数据的可靠传输。 TCP协议的特点如下&#xff1a; 1. 面向连接&#xff1a;在通信前需要先建立连接&#x…

学习Uni-app开发小程序Day26

这一章学习的内容细节较多&#xff0c;主要是分为&#xff1a;首次加载减少网络消耗、获取图片的详细信息、图片的评分和避免重复评分、将图片下载到本地并且获取设备的授权 加载图片减少网络消耗 这里突出这个功能&#xff0c;是根据老师视频上的描述&#xff0c;个人觉得很…