Java中的7大设计原则
1、单一职责
一个类尽可能只干一件事情。普通会员、vip会员、黄金会员三个类,各干自己的事。
优点:低耦合、高内聚。
2、开闭原则
对扩展开放,对修改关闭。(继承或多态)
不建议对原来的代码进行修改,可以扩展一个新的类,来实现功能。
对程序进行抽象化设计,设计出抽象类/接口,根据不同的功能来扩展子类。
class CarDemo{public static void main(String[] args) {new CarFactory().carfactory(new Aodi());new CarFactory().carfactory(new DaZhong());}
}class CarFactory{void carfactory(Car car){car.createCar();}
}abstract class Car{public abstract void createCar();
}class Aodi extends Car{@Overridepublic void createCar() {System.out.println("造奥迪汽车");}
}class DaZhong extends Car{@Overridepublic void createCar() {System.out.println("造大众汽车");}
}
3、里氏替换原则
使用父类的地方,都可以替换成子类,程序不会产生任何错误和异常。
子类继承父类后,子类对父类方法进行重写时,需要注意:本来是要用父类中的方法,但是 子类重新修改了功能,可能会导致结果不正确。尽量不要重写父类的方法,可以新增扩展其他的功能。
package com.ffyc.javapro.ooptenet.tenet3;
public class CalculatorDemo{public static void main(String[] args) {System.out.println(new SuperCalculator().sum(5,5,5));}
}
//计算器
class Calculator {//加法public int add(int a,int b){return a+b;}//减法public int sub(int a,int b){return a-b;}
}
//超级计算器子类
class SuperCalculator extends Calculator{//重写了父类加法@Overridepublic int add(int a, int b) {return a+b+5;}//求和方法 子类新增的功能public int sum(int a,int b,int c){//调用add(),但是子类重写了父类方法,此处调用的子类方法发生了变化int result = this.add(a,b);return result+c;}
}
4、依赖倒置
如果有多个同类型时,需要抽取抽象层(抽象类、接口)。上层定义为抽象或接口,底层实现抽象或接口,进行扩展功能。
//反例
public class WorkerDemo{public static void main(String[] args) {new Worker().getMessage(new DingDing());new Worker().getMessage(new WeChat());}
}class Worker {public void getMessage(DingDing ding){System.out.println(ding.sendMessage());}public void getMessage(WeChat weChat){System.out.println(weChat.sendMessage());}
}class DingDing{public String sendMessage(){return "钉钉消息";}
}class WeChat{public String sendMessage(){return "微信消息";}
}
//正例
public class WorkerDemo{public static void main(String[] args) {new Worker().getMessage(new WeChat());}
}class Worker {public void getMessage(Message message){System.out.println(message.sendMessage());}
}interface Message{public String sendMessage();
}class WeChat implements Message{@Overridepublic String sendMessage() {return "微信消息";}
}
class DingDing implements Message{@Overridepublic String sendMessage() {return "钉钉消息";}
}
5、接口隔离
接口功能设计时,尽量减少一个接口中有过多的功能(方法),可以细分为多个接口。不要把所有的功能定义到同一个接口中,不然要实现接口中的所有方法。
6、迪米特原则
也叫最少了解原则,在一个类中,尽量不要直接使用与此类无关的类;只与最好的朋友交谈,不与默认人说话。
反例:
public class Demeter {public static void main(String[] args) {new SchoolManger().printAllEmployee(new CollegeManger());}
}
//学校员工类
class SchoolEmployee{private String id;public void setId(String id){this.id = id;}public String getId(){return id;}
}
//学院员工类
class CollegeEmployee{private String id;public void setId(String id){this.id = id;}public String getId(){return id;}
}//学院员工管理管理类
class CollegeManger{//生成学员所有的员工public List<CollegeEmployee> getCollegeEmployee(){ArrayList<CollegeEmployee> collegeEmployeeArrayList = new ArrayList();for (int i = 0; i <10 ; i++) {CollegeEmployee collegeEmployee = new CollegeEmployee();collegeEmployee.setId("学院员工的id="+i); //添加学院员工collegeEmployeeArrayList.add(collegeEmployee);}return collegeEmployeeArrayList;}}
//学校员工管理类
class SchoolManger {//生成学校的员工public List<SchoolEmployee> getSchoolEmployee() {ArrayList<SchoolEmployee> employeeArrayList = new ArrayList();for (int i = 0; i < 5; i++) {SchoolEmployee employee = new SchoolEmployee();employee.setId("学校的员工id=" + i);employeeArrayList.add(employee);}return employeeArrayList;}//输出学校员工和学院员工信息public void printAllEmployee(CollegeManger collegeManger) {//获取到学校员工List<SchoolEmployee> employeeArrayList = this.getSchoolEmployee();System.out.println("--------学校员工--------");for (SchoolEmployee employee1 : employeeArrayList) {System.out.println(employee1.getId());}System.out.println("--------学院员工--------");List<CollegeEmployee> collegeEmployees = collegeManger.getCollegeEmployee();//SchoolManger中出现CollegeEmployee,此类与SchoolManger并非直接朋友,不合理for (CollegeEmployee collegeEmployee : collegeEmployees) {System.out.println(collegeEmployee.getId());}}
}
正例:
public class Demeter {public static void main(String[] args) {new SchoolManger().printAllEmployee(new CollegeManger());}
}
//学校员工类
class SchoolEmployee{private String id;public void setId(String id){this.id = id;}public String getId(){return id;}
}
//学院员工类
class CollegeEmployee{private String id;public void setId(String id){this.id = id;}public String getId(){return id;}
}//学院员工管理管理类
class CollegeManger{//生成学院所有的员工public List<CollegeEmployee> getCollegeEmployee(){ArrayList<CollegeEmployee> collegeEmployeeArrayList = new ArrayList();for (int i = 0; i <10 ; i++) {CollegeEmployee collegeEmployee = new CollegeEmployee();collegeEmployee.setId("学院员工的id="+i); //添加学院员工collegeEmployeeArrayList.add(collegeEmployee);}return collegeEmployeeArrayList;}public void printCollegeEmployee(){List<CollegeEmployee> collegeEmployee = getCollegeEmployee();for (CollegeEmployee employee : collegeEmployee) {System.out.println("学员员工id="+employee.getId());}}
}
//学校员工管理类
class SchoolManger {//生成学校的员工public List<SchoolEmployee> getSchoolEmployee() {ArrayList<SchoolEmployee> employeeArrayList = new ArrayList();for (int i = 0; i < 5; i++) {SchoolEmployee employee = new SchoolEmployee();employee.setId("学校的员工id=" + i);employeeArrayList.add(employee);}return employeeArrayList;}//输出学校员工和学院员工信息public void printAllEmployee(CollegeManger collegeManger) {//获取到学校员工List<SchoolEmployee> employeeArrayList = this.getSchoolEmployee();System.out.println("--------学校员工--------");for (SchoolEmployee employee1 : employeeArrayList) {System.out.println(employee1.getId());}//CollegeManger与SchoolManger是直接朋友,相互之间访问System.out.println("--------学院员工-----------");collegeManger.printCollegeEmployee();}
}
7、组合/聚合复用原则
如果想在一个类中达到复用别的类中的方法,优先使用关联/依赖,其次才考虑继承。
案例:现在假设有一个A类,里面有两个方法,B类想要复用这两个方法,请问有几种方案?
public class A {public void method01(){}public void method02(){}
}class B{A a;//关联关系。A作为B类的成员变量,尽量避免使用继承public void setA(A a){this.a = a;}public void use(){a.method01();a.method02();}
}class Test{public static void main(String[] args) {A a = new A();B b = new B();b.setA(a);b.use();}
}
public class A {public void method01(){}public void method02(){}
}class B{public void use(A a){//将A作为参数使用,依赖关系a.method01();a.method02();}
}class Test{public static void main(String[] args) {A a = new A();B b = new B();b.use(a);}
}
相关文章:

Java中的7大设计原则
在面向对象的设计过程中,首先需要考虑的是如何同时提高一个软件系统的可维护性和可复用性。这时,遵从面向对象的设计原则,可以在进行设计方案时减少错误设计的产生,从不同的角度提升一个软件结构的设计水平。 1、单一职责 一个类…...

Spring Cloud和Kubernetes + Spring Boot 用哪个?
Spring Cloud和Kubernetes Spring Boot都是用于构建微服务架构的解决方案,它们各有优势和不足,选择哪个更好取决于你的具体需求和上下文。 Spring Cloud是一个基于Spring Boot的微服务开发框架,它提供了一套完整的微服务解决方案࿰…...
web-worker 基本使用
Web Workers 是浏览器中的一项技术,它允许在独立的线程中运行 JavaScript 代码,从而避免主线程阻塞。这对于执行长时间运行的计算、处理大量数据或执行其他 CPU 密集型任务非常有用。下面是一个简单的使用 Web Workers 的示例,包括主线程和工…...
SpringBoot使用@PropertySource读取 properties 配置
SpringBoot使用PropertySource读取 properties 配置 properties配置文件 在resources文件夹下,新建一个文件 property-demo.properties, 示例如下: my.config.test.namewumy.config.test.id123配置的类 PropertySource 指定配置文件。 c…...
100天精通风控建模(原理+Python实现)——第5天:风控建模中数据标准化是什么?
风控模型已在各大银行和公司都实际运用于业务,用于营销和风险控制等。 之前已经阐述了100天精通风控建模(原理+Python实现)——第1天:什么是风控建模? 100天精通风控建模(原理+Python实现)——第2天:风控建模有什么目的? 100天精通风控建模(原理+Python实现…...

find和grep命令的简单使用
find和grep命令的简单使用 一、find例子--不同条件查找 二、grep正则表达式的简单说明例子--简单文本查找例子--结合管道进行查找 一、find find 命令在指定的目录下查找对应的文件。 find [path] [expression]● path 是要查找的目录路径,可以是一个目录或文件名…...
力扣:164. 最大间距(Python3)
题目: 给定一个无序的数组 nums,返回 数组在排序之后,相邻元素之间最大的差值 。如果数组元素个数小于 2,则返回 0 。 您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。 来源:力扣(LeetC…...

游戏平台采集数据
首先,你需要在你的项目中添加Kotlin的网络库,例如OkHttp。你可以在你的build.gradle文件中添加以下依赖: dependencies {implementation com.squareup.okhttp3:okhttp:4.9.0 }然后,你可以使用以下代码来创建一个基本的网络爬虫&a…...
CSS让两个标签在同一行显示并自适应宽度
CSS让两个标签在同一行显示并自适应宽度 示例:svg 和 span 在同一行上并自适应宽度 使用 Flexbox 布局 HTML <div class"flex-container"><svg class"svg-icon" aria-hidden"true"><use :xlink:href"#icon-s…...

Leetcode154. Find Minimum in Rotated Sorted Array II
旋转数组找最小,这次值可以重复 不妨假设你已经做了上一题,题解 上一题的方法1肯定是用不了了,因为不再能完全分成2个不同的部分 所以我们沿着方法2走 如果 > n u m s [ r ] >nums[r] >nums[r],我们依然可以找右半边 …...
【分析思路】测试数据分析思路
测试数据分析思路: 性能数据 对性能测试数据进行分析时,可以从以下几个维度进行比较: 响应时间(Response Time):分析每一天的响应时间数据,可以查看系统在不同时间段的性能表现,是…...

链表的实现(文末附完整代码)
链表的概念及结构 链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 我们在上一篇文章所学习的顺序表是连续存储的 例如: 顺序表就好比火车上的一排座位,是连续的 而链表就好比是火车…...
asp.net core 获取服务实例的几种方式
在ASP.NET Core中,我们可以使用以下几种方式来获取服务: 构造函数注入(Constructor Injection):在需要使用服务的类的构造函数中声明对应的服务类型参数,ASP.NET Core会自动将对应的服务实例注入进来。例如…...

指标体系:洞察变化的原因
一、指标概述 指标体系是指根据运营目标,整理出可以正确和准确反映业务运营特点的多个指标,并根据指标间的联系形成有机组合。 指标体系业务意义极强,所有指标体系都是为特定的业务经营目的而设计的。指标体系的设计应服从于这种目的&#x…...

Dell戴尔灵越Inspiron 7700 AIO一体机电脑原厂预装Windows10系统
链接:https://pan.baidu.com/s/1-slgR9t4Df_eko0Y6xaeyw?pwdmk0p 提取码:mk0p 灵越7700一体机原装出厂系统自带声卡驱动、无线网卡驱动、面部识别等所有驱动、出厂主题壁纸、系统属性专属LOGO标志、Office办公软件、MyDell等预装程序 由于时间关系,…...
系统架构主题之九:软件设计模式及其应用
1 关于设计模式 设计模式是什么?个人理解,其是软件开发中对一些通用问题整理的解决方案,是经过经验总结所提炼的相对较为抽象的,有一定适应性和变化性的“套路”。这里借用了“套路”这个不太好听的词,但目的却是为了…...

Spring IoC注解式开发
2023.11.11 注解的存在主要是为了简化XML的配置。Spring6倡导全注解开发。 负责声明Bean的注解,常见的包括四个: ComponentControllerServiceRepository 通过源码可以发现,Controller、Service、Repository这三个注解都是Component注解的别名…...

智能一体化管网水位监测仪怎么样?
城市排水管网是城市正常运行的关键环节,这是地上和地下通道的连接点,一旦出现问题便会影响城市生命线建设的工程进展。在复杂的地下管道内想要了解水位数据,对于政府部门来讲是一个管理难题。如果可以采取智能产品在其中发挥作用,…...

个人网厅——销户
目录 需求文档 公积金销户类 controller层 service层 service层实现类 1.验证 (个人账户) 2.提交(添加) controller层 service层 service层实现类 3.分页查询 controller层 service层 service层实现类 4. 详情查询…...

通过创建自定义标签来扩展HTML
使用HTML时,例如,使用<b>标记显示粗体文本。 如果需要列表,则对每个列表项使用<ul>标记及其子标记<li> 。 标签由浏览器解释,并与CSS一起确定网页内容的显示方式以及部分内容的行为。 有时,仅使用一…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...

3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...