001-从零学习设计模式-设计原则

写在最前

文档地址:Wiki - Gitee.com

设计模式

推荐浏览:软件设计模式

  • 代表了代码的最佳实践,被有经验的开发人员所使用;

  • 设计模式是很多被反复使用并知晓的,主要是对代码和经验的总结;

  • 使用设计模式是为了重用代码,让代码更容易被他人理解,保证代码的可靠性;

  • 对接口编程而不是对实现变成;

  • 有限使用对象组合而不是继承关系;

设计原则

设计模式的六大设计(第七点为后增)原则通常是指的面向对象设计原则,也被称为SOLID原则。这六大设计原则分别是:

  1. 单一职责原则(Single Responsibility Principle,SRP):

    • 一个类应该只有一个引起变化的原因。这意味着一个类应该只有一个责任,只关注一个功能领域;

    • 降低程序的复杂度,提高程序可维护性,降低了变更所带来的风险;

  2. 开放/封闭原则(Open/Closed Principle,OCP):

    • 软件实体(类、模块、函数等)应该是可扩展的,但不可修改的。即,对于新增功能应通过扩展而不是修改现有代码来实现;

    • 使用抽象进行构建,使用实现扩展细节,面向抽象编程;

    • 提高软件系统的可复用性和可维护性;

  3. 里氏替换原则(Liskov Substitution Principle,LSP):

    • 所有引用基类的地方必须能够透明地使用其子类的对象,即子类可以替代基类而不影响程序的正确性;

    • 里氏替换原则是继承复用的基石,对开闭原则的补充;

    • 子类可以实现父类的抽象方法,但是不能覆盖原有父类的方法,子类中可以增加自己特有的方法;

    • 可以增加程序的健壮性;

  4. 接口隔离原则(Interface Segregation Principle,ISP):

    • 一个类对于它的客户端应该只暴露它们需要的方法,而不应该强迫客户端使用它们不需要的方法。接口应该是客户端特定的,而不是通用的;

    • 尽量细化接口,接口中的方法尽量少;

    • 符合低耦合的设计思想,提高了可扩展性和可维护性;

  5. 依赖倒置原则(Dependency Inversion Principle,DIP):

    • 高层模块不应该依赖于低层模块,而是两者都应该依赖于抽象。抽象不应该依赖于具体实现,而具体实现应该依赖于抽象;

    • 依赖倒置原则是开闭原则的基础,针对接口进行编程;

    • 可以减少类之间的耦合行,提高系统稳定性,提高代码可读性和可维护性;

    • 降低修改程序所造成的风险;

  6. 迪米特法则(Law of Demeter,LoD):

    • 一个对象应该对其他对象有最少的了解,即一个对象不应该直接调用另一个对象内部的方法,而应该通过一些中介者来进行间接调用;

    • 为了降低类与类之间的耦合关系;

    • 强调只和朋友交流,不和陌生人说话。朋友指的是成员变量或方法中输入输出的参数;

  7. 合成复用原则(Composite Reuse Principle,CRP):

    • 尽量使用对象组合,聚合的方式,而不是使用继承关系达到软件复用的目的;

    • 可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少;

这些设计原则共同为面向对象设计提供了指导方针,有助于创建更灵活、可维护和可扩展的代码。在应用这些原则时,设计模式通常被用来实现这些原则的具体设计方案。

单一职责原则

1.定义人类接口

人类都具有吃饭、睡觉的行为

public interface Human {/*** 吃饭*/void eat();
​/*** 睡觉*/void sleep();
}

2.定义程序员抽象类

程序员都需要工作

public abstract class Programmer implements Human {/*** 程序员都需要工作*/abstract void work();
}

3.Java程序员

具备Java编写能力

public class JavaProgrammer extends Programmer {@Overridepublic void eat() {System.out.println("Java程序员在吃饭");}
​@Overridepublic void sleep() {System.out.println("Java程序员在睡觉");}
​@Overridevoid work() {System.out.println("Java程序员在工作");}
​/*** Java程序员其他行为*/void codeJava() {System.out.println("Java程序员在写Java代码");}
}

4.测试

public class Test {public static void main(String[] args) {JavaProgrammer javaProgrammer = new JavaProgrammer();javaProgrammer.codeJava();javaProgrammer.eat();javaProgrammer.work();javaProgrammer.sleep();}
}

开放/封闭原则

1.定义人类接口

人类都具有吃饭、睡觉的行为

public interface Human {/*** 吃饭*/void eat();
​/*** 睡觉*/void sleep();
}

2.学生实现人类接口

学生都具有学习的行为

public class Student implements Human {@Overridepublic void eat() {System.out.println("学生在吃饭");}
​@Overridepublic void sleep() {System.out.println("学生在睡觉");}
​public void study() {System.out.println("学生在学习");}
}

3.增加高中生

满足开闭原则,增加高中生,但不修改学生类。

public class HighSchoolStudent extends Student {@Overridepublic void eat() {System.out.println("高中生在吃饭");}
​@Overridepublic void sleep() {System.out.println("高中生在睡觉");}
​@Overridepublic void study() {System.out.println("高中生在学习");}
​/*** 扩展高中生独有的属性或行为*/public void doSomeThing() {System.out.println("高中生在谈恋爱");}
}

4.测试

public class Test {public static void main(String[] args) {Student student = new Student();student.eat();student.sleep();student.study();
​// 不修改学生类(对修改关闭),增加高中生(对扩展开发)HighSchoolStudent highSchoolStudent = new HighSchoolStudent();highSchoolStudent.eat();highSchoolStudent.sleep();highSchoolStudent.study();highSchoolStudent.doSomeThing();}
}

里氏替换原则

1.定义老鼠类

public class Mouse {void burrow() {System.out.println("老鼠会打洞。。。");}
}

2.定义仓鼠类继承老鼠

public class Hamster extends Mouse {// 子类可以不修改父类的方法,只是继承并使用 (老鼠天生会打洞)
}

3.定义玩具鼠类继承老鼠

public class ToyMouse extends Mouse {@Overridevoid burrow() {// 它可以覆盖 burrow 方法,但不应该修改已经存在的行为System.out.println("我是玩具鼠,我不会打洞,我会上天");}
}

4.测试

public class Test {public static void main(String[] args) {Hamster hamster = new Hamster();// 老鼠生的会打洞hamster.burrow();
​ToyMouse toyMouse = new ToyMouse();// 老鼠生的不会打洞,会上天,就违背了该原则toyMouse.burrow();}
}

接口隔离原则

1.定义人类接口

public interface Human {}

2.人类行为拆分接口,进行接口隔离

吃饭

public interface EatAction extends Human {void eat();
}

睡觉

public interface SleepAction extends Human {void sleep();
}

3.学生具备吃饭、睡觉的行为

public class Student implements EatAction, SleepAction {@Overridepublic void eat() {System.out.println("学生在吃饭");}
​@Overridepublic void sleep() {System.out.println("学生在睡觉");}
}

4.测试

public class Test {public static void main(String[] args) {Student student = new Student();
​student.eat();student.sleep();}
}

依赖倒置原则

1.定义人类接口

人类都具有吃饭、睡觉的行为

public interface Human {/*** 吃饭*/void eat();
​/*** 睡觉*/void sleep();
}

2.定义程序员抽象类

public abstract class Programmer implements Human {
​@Overridepublic void eat() {System.out.println("程序员在吃饭");}
​@Overridepublic void sleep() {System.out.println("程序员在睡觉");}
​/*** 程序员都需要工作*/abstract void work();
}

定义Java程序员、测试程序员

Java程序员

public class JavaProgrammer extends Programmer {@Overridepublic void eat() {System.out.println("Java程序员在吃饭");}
​@Overridepublic void sleep() {System.out.println("Java程序员在睡觉");}
​@Overridevoid work() {System.out.println("Java程序员在工作");}
}

测试程序员

public class TestProgrammer extends Programmer {@Overridepublic void eat() {System.out.println("测试程序员在吃饭");}
​@Overridepublic void sleep() {System.out.println("测试程序员在睡觉");}
​@Overridevoid work() {System.out.println("测试程序员在工作");}
}

4.测试

public class Test {public static void main(String[] args) {JavaProgrammer javaProgrammer = new JavaProgrammer();javaProgrammer.eat();javaProgrammer.work();javaProgrammer.sleep();
​TestProgrammer testProgrammer = new TestProgrammer();testProgrammer.work();}
}

迪米特法则

1.定义人类接口

public interface Human {}

2.定义管理层接口并实现

public interface Manager extends Human {}

公司老板

public class Boss implements Manager {public void meet(TeamLeader teamLeader) {System.out.println("老板开会,发布任务");teamLeader.assignTasks();}
}

团队领导

public class TeamLeader implements Manager {
​private Programmer programmer;
​public void setProgrammer(Programmer programmer) {this.programmer = programmer;}
​public void assignTasks() {System.out.println("团队领导给研发分配任务");
​this.programmer.work();}
}

3.定义程序员接口并实现

public abstract class Programmer implements Human {/*** 程序员都需要工作*/abstract void work();
}

Java程序员

public class JavaProgrammer extends Programmer {
​@Overridevoid work() {System.out.println("Java程序员完成Java代码开发");}
}

4.测试

public class Test {public static void main(String[] args) {// 老板准备发布任务Boss boss = new Boss();
​// 找到项目经理TeamLeader teamLeader = new TeamLeader();
​// 项目经理拉上手底下研发JavaProgrammer javaProgrammer = new JavaProgrammer();teamLeader.setProgrammer(javaProgrammer);
​// 老板发布任务boss.meet(teamLeader);}
}

合成复用原则

1.定义汽车引擎

public class Engine {void start() {System.out.println("发动机正在启动");}
}

2.定义汽车

public class Car {private Engine engine;
​Car(Engine engine) {this.engine = engine;}
​void start() {engine.start();System.out.println("汽车正在启动");}
}

3.测试

public class Test {public static void main(String[] args) {// 在传统的继承方式下,可能会让Car继承自Engine,但这样的设计可能导致不必要的耦合,违反了合成复用原则。Engine engine = new Engine();// 使用合成复用原则通过组合来实现复用。Car car = new Car(engine);car.start();}
}

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

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

相关文章

Vue 3 安装和引用指南

Vue 3 安装和引用指南 Vue 3 是一个流行的前端JavaScript框架,用于构建用户界面和单页应用程序。本文将指导您如何安装和开始使用 Vue 3。 安装 Vue 3 使用 npm 或 yarn 安装 如果您已经安装了 Node.js,可以通过 npm 或 yarn 来安装 Vue 3。 使用 npm 安装 npm install…

web布局——说清楚fixed布局

极限省流 想要fixed做导航页面:指定清楚top、left、right、bottom,没指定清楚布局位置就会采用默认的方式: 0)父元素的padding:fixed元素相对位移 1)同级元素是fixed元素:覆盖 2&#xff09…

智能化时代的企业网络,需要“以体验为中心”的建网理念

不久前,著名咨询公司Gartner发布了2024年的《企业有线无线局域网基础设施魔力象限》报告,华为再次入选“领导者”象限。 从2006年开始,Gartner选择以“魔力象限”的形式评估各个市场的技术和服务提供商,通过统一的评估准则&#…

MyLisp项目日志:函数

文章目录 函数函数类型Lambda函数运行环境函数调用可变参数优化函数定义方式柯里化 函数 我们想让用户可以定义自己的函数,而不仅仅是使用我们提供的内建函数 那我们要提供这样的功能就要首先就得提供一个内置函数,可以使用户通过这个函数创建自定义的…

尾矿库在线安全监测:提升矿山安全水平

在矿山安全领域,尾矿库的安全管理尤为关键。尾矿库作为矿山生产链条的重要环节,其稳定性不仅关系到生产活动的持续进行,更直接影响着周边环境和人民群众的生命财产安全。因此,尾矿库的安全监测显得尤为重要。近年来,随…

【Leetcode每日一题】 动态规划 - 不同路径(难度⭐⭐)(46)

1. 题目解析 题目链接:62. 不同路径 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 想要解决这个问题,我们得像个侦探一样,一步步地追踪路径,找出所有可能的走法。接下…

2024年妈妈杯数学建模思路A题B题C题D题思路分享

文章目录 1 赛题思路2 比赛日期和时间3 组织机构4 建模常见问题类型4.1 分类问题4.2 优化问题4.3 预测问题4.4 评价问题 5 建模资料 1 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 2 比赛日期和时间 报名截止时间:2024…

JavaEE:网络原理——协议(网络层+数据链路层)

网络层:IP协议 IP协议报头 其中取值只有两种,分别是4和6,分别对应IPv4和IPv6 IP报头,单位是4个字节,可变长 type of service,表示当前IP协议所处的工作模式 实际上只有四位是有效的。而且这4为是彼此冲突…

GEE实践应用|热岛效应(一)地表温度计算

目录 1.学习目标 2.理论介绍 3.从MODIS获得地表温度 4.从Landsat卫星获得地表温度 1.学习目标 ①了解如何使用GEE计算地表温度 2.理论介绍 城市化涉及用建筑物、道路和停车场等建筑结构取代自然景观。这种土地覆盖的改变也改变了土地表面的特性。这些变化的范围从表面反射和…

SpringBoot Redis的使用

官方文档: 官方文档:Spring Data Redis :: Spring Data Redis 和jedis一样,SpringBoot Redis 也可以让我在Java代码中使用redis,同样也是通过引入maven依赖的形式。 加速访问github: 使用steam可以免费加速访问github Spring…

汇编实现分页和异常处理

汇编实现分页和异常处理。 .386pStackSeg segment page db 400h dup (0) StackSeg endsStackSeg3 segment page db 400h dup (0) StackSeg3 endsInfoSeg segment page ShowPos dd 0b8000h szEnterProtect db Now Enter Paging Protect Mode …

【微服务】Sentinel(流量控制)

文章目录 1.基本介绍1.Sentinel是什么2.Sentinel主要特性3.Sentinel核心功能1.流量控制2.熔断降级3.消息削峰填谷 4.Sentinel两个组成部分 2.Sentinel控制台显示1.需求分析2.下载3.运行1.进入cmd2.输入java -jar sentinel-dashboard-1.8.0.jar3.查看默认端口8080 4.访问1.账号和…

【八股】泛型

泛型存在的意义&#xff1f; 为了使相同的代码适用于多种数据类型&#xff0c;也就是代码复用。 参数类型上下限限制 <?> 无限制 <? extends E> 声明了类型的上界&#xff0c;表示参数类型可以是他或他的子类。 <? super E> 声明了类型的下界&#xf…

C++多线程:创建多个线程与数据共享安全问题(四)

1、创建多个线程 多线程的调度由操作系统负责&#xff0c;线程执行的先后没有严格的顺序完全看操作系统和CPU的心情。 #include <iostream> #include <vector> #include <thread>void thread_print(int num) {std::cout << "线程编号 " &…

go、rust去掉了继承

为什么go、rust去掉了继承&#xff1f;只要你阅读过很多Java开源系统的源代码就明白。尤其是调试时&#xff0c;一层一层的进入基类&#xff0c;痛苦万分。一个类的功能只看它自己&#xff0c;是不知道有那些功能的&#xff0c;因为它老子、它爷爷的功能都是起作用的。在很多开…

Kali-Linux汉化教程

Kali Linux汉化教程如下&#xff1a; 打开终端。输入命令 sudo dpkg-reconfigure locales 并回车。在出现的界面中&#xff0c;使用空格键选中想要的语言选项&#xff0c;包括 en_US.UTF-8、zh_CN.GBK 和 zh_CN.UTF-8。选中 zh_CN.UTF-8 作为默认语言。按 “Tab” 键切换到 “…

视频无水印爬虫采集工具|抖音视频批量下载软件|可导出视频分享链接

全新视频无水印爬虫采集工具&#xff0c;助力您快速获取所需视频&#xff01; 视频无水印爬虫采集工具&#xff0c;为用户提供了强大的视频采集和下载功能。它可以批量提取关键词相关的视频&#xff0c;同时支持单独视频的提取和下载&#xff0c;操作简便&#xff0c;使用方便。…

大模型RAG性能提升路径

大模型相关目录 大模型&#xff0c;包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容 从0起步&#xff0c;扬帆起航。 大模型应用向开发路径&#xff1a;AI代理工作流大模型应用开发实用开源项目汇总大模…

数字兆欧表操作规程你知道多少?南电电力来告诉你!

一、数字兆欧表操作规程   数字兆欧表是一种现代化电子仪表&#xff0c;用于测量电气设备的绝缘电阻。其操作规程的目的是确保测量结果的准确性&#xff0c;并保证操作人员的安全。以下是主要的操作规程&#xff1a;   1.安全操作&#xff0c;断电与放电&#xff1a;在测量…