【设计模式】六大原则-下

news2024/12/23 0:21:51

❓首先什么是设计模式?

😵相信刚上大学的你和我一样,在学习这门课的时候根本不了解这些设计原则和模式有什么用处,反而不如隔壁的C++更有意思,至少还能弹出一个小黑框,给我个hello world。

✨ 如何你和我一样也是这么想,那接下来咱们以贴合生活实际的方式来看看设计模式到底有什么神奇的地方

😄更多有趣的设计模式讲解都在设计模式👍专栏,欢迎来看看🎉🎉🎉。

【设计模式】六大原则-下

  • 六大原则-下
    • 单一职责
    • 接口隔离原则
    • 合成复用原则
  • 总结

新来的小伙伴你可能会注意到,这咋直接六大原则下了,上呢?

别着急,这里有一个传送门,大家可以看看上半部分的内容。
🆒传送门🆒 【设计模式】六大原则-上

接下来咱们一起看看另外三个原则

六大原则-下

单一职责

每个类应该只有一个引起它变化的原因,即一个类只负责一项职责。

哦吼,熟悉的感觉,还是这么抽象!

在这里插入图片描述

害,咱们一起看看这是啥意思

相信大家读完之后就知道这条原则说的是啥,就是一个类只负责一项功能,但有一个问题,为啥一个类只负责一个功能呢?

举个例子哈,现在我们做了一个图书管理系统,然后有一个类,负责订单的处理,如下所示

public class OrderManager {
    // 创建订单
    public void createOrder(Order order) {
        // 创建订单的逻辑
        System.out.println("Order created: " + order.getId());
    }

    // 取消订单
    public void cancelOrder(Order order) {
        // 取消订单的逻辑
        System.out.println("Order canceled: " + order.getId());
    }

    // 计算订单总价
    public double calculateTotal(Order order) {
        double total = 0.0;
        for (OrderItem item : order.getItems()) {
            total += item.getPrice() * item.getQuantity();
        }
        // 假设税费是总价的10%
        total += total * 0.1;
        return total;
    }

    // 生成订单报表
    public void generateOrderReport(Order order) {
        // 生成订单报表的逻辑
        System.out.println("Order Report for Order ID: " + order.getId());
        System.out.println("Total Price: " + calculateTotal(order));
    }

    // 持久化订单
    public void saveOrder(Order order) {
        // 保存订单的逻辑
        System.out.println("Order saved to database: " + order.getId());
    }
}


这样有啥问题吗

  • 首先,这个代码太复杂了,我们现在还没有加上具体的处理流程,整个代码已经非常长了,理解起来非常困难。
  • 其次,修改存在风险。我们可以看到generateOrderReport调用了calculateTotal方法,如果以后我们因为其他的需求进行了改动,例如打折促销修改了计算总价的方式,generateOrderReport极有可能出现问题。

那怎么做呢?

就可以按照单一职责原则进行修改,修改起来非常简单,就是直接为每一个方法创建一个类即可,如下

public class OrderCalculator {
    public double calculateTotal(Order order) {
        double total = 0.0;
        for (OrderItem item : order.getItems()) {
            total += item.getPrice() * item.getQuantity();
        }
        // 假设税费是总价的10%
        total += total * 0.1;
        return total;
    }
}

public class OrderReportGenerator {
    private final OrderCalculator calculator;

    public OrderReportGenerator(OrderCalculator calculator) {
        this.calculator = calculator;
    }

    public void generateOrderReport(Order order) {
        // 生成订单报表的逻辑
        System.out.println("Order Report for Order ID: " + order.getId());
        System.out.println("Total Price: " + calculator.calculateTotal(order));
    }
}

现在,我们可以很轻松的搞清楚这个类是干什么的,可读性增强了。

并且,上面我们提到的如果打折怎么办?

我们完全可以为OrderCalculator添加一个接口,这样如果有新的结算策略的时候,增加一个实现类就好了。

**看到这,是不是有点熟悉,这是不是就是所谓的对修改封闭,对扩展开放,开闭原则。**代码如下

public interface CalculatorInterface {
    public double calculateTotal(Order order);
}


public class OrderCalculator implements  CalculatorInterface {
    public double calculateTotal(Order order) {
        double total = 0.0;
        for (OrderItem item : order.getItems()) {
            total += item.getPrice() * item.getQuantity();
        }
        // 假设税费是总价的10%
        total += total * 0.1;
        return total;
    }
}



public class DiscountCalculator implements  CalculatorInterface {
    public double calculateTotal(Order order) {
        double total = 0.0;
        //  打折操作
        return total;
    }
}

接口隔离原则

不应该强迫客户依赖它们不使用的方法。应该将臃肿的接口分解为更小、更具体的接口,这样客户只需知道它们感兴趣的方法即可。

这个是啥意思呢?

大白话翻译一下就是,我们设计的接口的功能应该尽可能细粒,不要让一个接口实现的功能太大,尽量细化一点。

例如,我们现在写一个包饺子的接口,如下所示

public interface MakeDumpling {
    void cook();
}

public class MakeDumplingImpl implements MakeDumpling {
    @Override
    public void cook() {
        System.out.println("调馅");
        System.out.println("擀面皮");
        System.out.println("包饺子");
        System.out.println("下锅");
    }
}

整体实现的还是很简单的哈,但现在有一个问题,我想要包包子,你就会发现,我们需要新定义一个接口,并且需要把调馅,擀面皮和下锅这些重复的操作代码再写一遍。

看到这,不知道你有没有意识到为什么要遵守接口隔离原则。

那我们怎么改呢

public interface interface1 {
//  擀面皮
    void rollTheDough();
}


public interface interface1 {
    //  调饺子馅
    void mixDumplingFilling();
}

这样是不是就把功能更细化了一点,我们就可以提高代码的复用性了。

合成复用原则

尽量使用对象组合而不是继承来实现代码复用。组合可以在运行时选择或改变行为,使得系统更具灵活性。

这个比较简单一点,其实读过就明白了。很符合我们的认知哈。先看看比较官方的解释

合成复用原则是一种重要的设计原则,旨在通过组合或聚合关系来实现代码的复用,而非过度依赖继承关系。该原则强调优先使用对象组合来达到复用的目的,从而降低类与类之间的耦合度,提高系统的灵活性和可维护性

太官方了有点看不懂,咱来点通俗解释。

为啥能降低耦合呢?

咱们想一下这样一个场景,你设计的系统中大部分类都继承了一个父类。但是现在由于业务变化,父类对一个方法的参数进行了修改,那好嘛,所有子类都要改,这是不是有点难受

那为啥能提高灵活性呢

想一下这样的场景,B类继承了A类,并使用了A的operate方法,但是现在出现了一个问题,C类也提供一个operate方法,并且我需要动态选择使用A或则C的方法,那继承很明显不行,那没办法,整不了。但如果使用组合的方式呢,我们可以动态的选择A或C的方法,灵活性就大大提升了。

总结

六大原则就全部介绍完了。

在这里插入图片描述

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

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

相关文章

【python报错】‘XXX‘ object is not callable

‘XXX‘ object is not callable----这个报错通常是因为在代码中某一个变量的名字和函数的名字重复导致的,此时需要确定名称使用是否正确,如果重复则需要修改其中一个名字;如果名字没有问题,那就要看表达式写的对不对,…

使用 Lombok 遇到一个问题

起因是换了一个电脑,重新从服务器上拉了一个项目。项目是由maven构建的,在控制台中使用mvn命令编译项目时,没有任何问题,编译成功。如下图: 可是idea里面的源码,却标红了,如下: 错误…

猫咪掉毛很烦恼,希喂、小米哪个牌子的宠物空气净化器更好用?

随着养宠物人群变多,现在打着宠物专用旗号的空气净化器也越来越多,但是很多空气净化器对宠物的效果,真的是只有宣传上和宠物有关,实际设计和效果上和宠物毫无关系。需要大家擦亮眼睛,多做功课,才能不被那些…

如何在前端测试中,在F12中加入token

不止是token,cookie中其他的数据也都可以这样 首先打开F12,然后找到Application或者应用程序 然后找到cookie里面双击这里,输入token或者其他数据就可以了,后面输值。

网络安全术语全解析:筑牢数字防线的必备知识

在当今数字化时代,网络安全成为了至关重要的议题。了解网络安全术语是构建安全网络环境的基础,本文将为你详细介绍一系列常见的网络安全术语。 一、攻击相关术语 1. 恶意软件(Malware) 恶意软件是指在计算机系统上执行恶意任务…

操作系统简介:存储管理

存储管理 1. 基本概念2. 存储管理方案2.1 分区存储管理2.2 分页存储管理2.3 分段存储管理2.4 虚拟存储管理页面置换算法 存储器管理的对象是主存储器(主存、内存)。存储管理的主要功能包括 分配和回收主存空间、提高主存的利用率、扩充主存、对主存信息实现有效保护。 1. 基本…

【机器学习】探索机器学习在旅游业的革新之旅

📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀目录 🔍1. 引言📒2. 机器学习在旅游需求分析中的应用🌞用户行为数据分析🌙旅客偏好预测模型⭐…

【Spring】为什么不建议使用@Autowired

【Spring】为什么不建议使用Autowired 开篇词:干货篇:1.知识回顾2.Autowired和其他注入方式的对比1.Autowired 注入(字段注入)2.构造器注入3.Setter 方法注入 3.为什么spring官方不推荐使用1. 违反封装原则2. 依赖关系不明确3. 难…

yolo V8训练 长条状目标

1、说明 目标数据集合中有很多长条状图片&#xff0c;如果直接Resize 会严重拉伸&#xff0c;因此采用把长条图像裁剪成2段&#xff0c;然后将裁剪后的2段图片拼接在一起。 2、代码 2.1 C 代码 &#xff08;部署&#xff0c;模型推理时C &#xff09; #include <stdio.h…

讯飞星火极速超拟人交互技术:语音端到端,8 月底开放;昆仑万维发布 AI 短剧平台 SkyReels丨RTE 开发者日报

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE&#xff08;Real-Time Engagement&#xff09; 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「…

Linux驱动开发基础(中断)

所学来自百问网 目录 1. 嵌入式中断系统 2. 中断处理流程 3. 异常向量表 4. Linux系统对中断的处理 4.1 ARM 处理器程序运行的过程 4.2 保护现场 5. Linux 系统对中断处理的演进 5.1 硬件中断和软件中断 5.2 中断拆分(上半部和下半部) 5.2.1 tasklet 5.2.2 工作队列…

iPad协议08算法新版

iPad协议是一种模拟iPad端微信的人工操作&#xff0c;并与微信服务器进行通信的协议。该协议涉及到一些关键点&#xff0c;包括PB协议、mmtls、07加密算法、rqt算法、aes加密、rsa加密等。只要理解了这些关键点&#xff0c;就可以模拟官方微信的所有功能&#xff0c;并且还可以…

基于STM32开发的智能家用能源管理系统

目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 系统初始化能源监测与数据处理能源管理与控制Wi-Fi通信与远程监控应用场景 家庭能源使用优化智能电力监控常见问题及解决方案 常见问题解决方案结论 1. 引言 随着能源需求的不断增长和环境保…

redis随笔记

缓存穿透。key不存在。恶意攻击、代码问题。加布隆过滤器&#xff0c;或者为空就返回。 缓存失效&#xff08;击穿&#xff09;。key刚好过期。缓存时间随机数。 缓存雪崩。缓存层宕机&#xff0c;一下子袭击数据库。缓存高可用、限流熔断、提前演练。 布隆过滤器就是一个key…

文档透明加密软件是什么?有哪些功能?一文给您详解!

文档透明加密软件是一种在不影响用户正常操作习惯的前提下&#xff0c;自动对电子文档进行加密和解密的技术解决方案。 其核心特点在于“透明性”&#xff0c;即用户在打开、编辑或保存文档时&#xff0c;无需进行任何额外的加密或解密操作&#xff0c;这些过程均在系统后台自…

【深度学习】【多模态】使用MiniCPM-V 2.6进行图片OCR

文章目录 ocr评价ocr 下载项目:https://huggingface.co/openbmb/MiniCPM-V-2_6 准备一个图片’test.jpg’。 将下面的python中的目录地址换成MiniCPM-V-2_6项目所在地址。然后执行: # test.py import torch from PIL import Image from transformers import AutoModel, Aut…

网络主播被正式认定为国家新职业

网络主播这一职业正式获得国家认可&#xff0c;标志着这一工作已成为一项正当且受认可的职业&#xff0c;而不再只是灵活就业的选项。近日&#xff0c;人力资源和社会保障部公布了新增的19个新职业信息&#xff0c;其中包括网络主播。对于从事直播行业的人来说&#xff0c;这是…

zabbix实战-磁盘空间告警

1.创建监控项 选择&#xff1a;键值&#xff1a;vfs.fs.size[fs,<mode>] 。 直接写 vfs.fs.size[fs,<mode>]是不出数据的。我们要写具体的值 &#xff1a;vfs.fs.size[/,free] &#xff0c;这个表示查看根的剩余空间。 2.创建图形 为磁盘剩余空间监控项创建图形&am…

cdn刷新预热

1、访问 cdn 控制台的 刷新预热 页面&#xff0c;填写需要刷新预热的url地址 阿里云&#xff1a; 腾讯云&#xff1a; 2、通过调用cdn的api接口刷新预热 阿里云&#xff1a; 调用RefreshObjectCaches-刷新缓存_CDN(CDN)-阿里云帮助中心 调用PushObjectCache-预热URL_CDN(CD…

前端宝典九:React Native从入门到精通实战

本文主要介绍 React Native新旧框架对比React与React Native区别React Native性能优化 其中第3点React Native性能优化的拆包分包&#xff0c;是项目实战中使用过的&#xff0c;在这里整理分享&#xff0c;如果没有用过的小伙伴会觉得晦涩难懂&#xff0c;建议按照在实际项目…