当前位置: 首页 > news >正文

设计模式——合成复用原则

文章目录

  • 合成复用原则
  • 设计原则核心思想
  • 合成案例
  • 聚合案例
  • 继承案例
  • 优缺点

合成复用原则

原则是尽量使用合成/聚合的方式,而不是使用继承

设计原则核心思想

  1. 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
  2. 针对接口编程,而不是针对实现编程。
  3. 为了交互对象之间的松耦合设计而努力

合成案例

假设我们有一个汽车类(Car),其中包含引擎类(Engine)。下面是使用合成的代码描述:

public class Demo1 {public static void main(String[] args) {Car car = new Car("V8");car.startCar();car.stopCar();}
}// 引擎类
class Engine {private String type;public Engine(String type) {this.type = type;}public void start() {System.out.println("Engine started");}public void stop() {System.out.println("Engine stopped");}
}// 汽车类
class Car {private Engine engine; // 使用合成关系,将引擎组合到汽车中public Car(String engineType) {engine = new Engine(engineType); // 在构造函数中创建引擎对象}public void startCar() {engine.start(); // 调用引擎对象的启动方法}public void stopCar() {engine.stop(); // 调用引擎对象的停止方法}
}

在上面的代码中,我在汽车类中添加了一个静态的main方法。在main方法中,我创建了一辆汽车对象,并指定了引擎类型为"V8"。然后,我调用了汽车对象的启动方法和停止方法,以展示汽车的功能。

您可以运行这个Java程序,看到在控制台输出的结果,显示汽车的启动和停止过程。
这个示例展示了如何在汽车类中使用合成关系,将引擎对象组合到汽车中,并通过main方法来演示汽车的使用

聚合案例

public class Demo2 {public static void main(String[] args) {School school = new School(); // 创建一个学校对象// 创建学生对象Student student1 = new Student("Alice");Student student2 = new Student("Bob");Student student3 = new Student("Charlie");// 将学生对象添加到学校中school.addStudent(student1);school.addStudent(student2);school.addStudent(student3);// 显示学校中的学生school.displayStudents();}
}//学生类
class Student {private String name;public Student(String name) {this.name = name;}public String getName() {return name;}
}//学校类
class School {private List<Student> students; // 使用聚合关系,将学生聚合到学校中public School() {students = new ArrayList<>(); // 在构造函数中创建学生列表对象}public void addStudent(Student student) {students.add(student); // 将学生对象添加到学生列表中}public void displayStudents() {for (Student student : students) {System.out.println(student.getName());}}
}

在上面的代码中,学校类(School)使用聚合关系,将学生对象(Student)聚合到学校中。学校类通过添加学生对象到学生列表中,并提供了显示学生的方法。

学生类(Student)是一个简单的类,表示学生。它有一个姓名属性和获取姓名的方法。
通过使用聚合关系,我们可以实现学校类的代码复用和灵活性。学校类通过聚合学生对象来管理学生。这种设计方式避免了继承关系的局限性,使系统更加灵活和可维护。

在main方法中,我创建了一个学校对象,并创建了几个学生对象。然后,我将学生对象添加到学校中,并调用学校对象的显示学生方法,以展示学校中的学生信息。

这个示例展示了如何在学校类中使用聚合关系,将学生对象聚合到学校中,并通过main方法来演示学校的学生管理。

继承案例

class Animal {private String name;public Animal(String name) {this.name = name;}public void makeSound() {System.out.println("The animal makes a sound.");}
}class Dog extends Animal {public Dog(String name) {super(name);}@Overridepublic void makeSound() {System.out.println("The dog barks.");}
}class Cat extends Animal {public Cat(String name) {super(name);}@Overridepublic void makeSound() {System.out.println("The cat meows.");}
}public class Main {public static void main(String[] args) {Animal animal1 = new Dog("Buddy");Animal animal2 = new Cat("Whiskers");animal1.makeSound(); // Output: The dog barks.animal2.makeSound(); // Output: The cat meows.}
}

在上面的代码中,Animal 类是一个基类,它有一个私有的 name 属性和一个 makeSound 方法。Dog 类和 Cat 类都继承自 Animal 类,并重写了 makeSound 方法,以实现各自的特定声音。

在 main 方法中,我们创建了一个 Dog 对象和一个 Cat 对象,并将它们赋值给 Animal 类型的变量。然后,我们调用这些对象的 makeSound 方法,分别输出狗的吠声和猫的喵声。

这个示例展示了如何使用继承来创建一个动物类的继承体系。通过继承,我们可以在派生类中重用基类的属性和方法,并根据需要进行定制化。继承提供了代码的复用和扩展性,但也需要注意继承关系的合理使用,避免过度继承和耦合。

优缺点

与继承关系相比,合成复用原则具有以下优点:

  • 更加灵活:通过合成或聚合关系,可以在运行时动态地改变对象的行为,而不需要修改代码。
  • 降低耦合性:合成或聚合关系可以减少类之间的依赖关系,降低耦合性,使系统更加灵活和可维护。
  • 更好的代码复用:通过合成或聚合关系,可以将现有的类组合在一起,创建新的类来实现代码的复用,避免了继承关系的局限性。

相关文章:

设计模式——合成复用原则

文章目录 合成复用原则设计原则核心思想合成案例聚合案例继承案例优缺点 合成复用原则 原则是尽量使用合成/聚合的方式&#xff0c;而不是使用继承 设计原则核心思想 找出应用中可能需要变化之处&#xff0c;把它们独立出来&#xff0c;不要和那些不需要变化的代码混在一起。…...

基于OpenCV实战(基础知识一)

目录 简介 1.计算机眼中的图像 2.图片的读取、显示与保存 3.视频的读取与显示 简介 OpenCV是一个流行的开源计算机视觉库&#xff0c;由英特尔公司发起发展。它提供了超过2500个优化算法和许多工具包&#xff0c;可用于灰度、彩色、深度、基于特征和运动跟踪等的图像处理和…...

如何高效的接入第三方接口

作为程序员的我们,经常会接到领导的安排,接入某某的接口,方面我们如何如何, 例如:领导在1号时给作为员工的你说,最近系统需要增加一个新的支付方式,一会和对方技术组建一个群,有什么问题,可以直接在群里说,最近还说,尽快接入,客户等着用,让你在5号前,完成接入工…...

docker pip下载依赖超时或失败问题解决

Docker容器使用pip安装Python库时超时&#xff0c;可能是由于多种原因。以下是一些建议和解决方法&#xff1a; 使用国内镜像源: 如果你位于中国&#xff0c;可以尝试更换到国内的镜像源。例如&#xff0c;可以使用阿里云、腾讯云、清华大学提供的镜像。 你可以在Dockerfile中添…...

python并发编程

一、程序提速的方法 二、python对并发编程的支持 多线程&#xff1a;threading&#xff0c;利用CPU和IO可以同时执行的原理&#xff0c;让CPU不会干巴巴等待IO完成&#xff1b;多进程&#xff1a;multiprocess&#xff0c;利用多核CPU的能力&#xff0c;真正的并行执行任务&am…...

【面试题】:前端怎么实现权限设计及遇到的bug

一.权限的概念 前端权限分为页面权限、按钮权限、API权限。 二.页面权限的实现过程 ①用户登录进去调用获取用户信息接口&#xff0c;后端会给我们返回一个权限标识符 ②在获取到数据之后,我们就要判断用户能访问到哪些页面,我们可以在vuex中permission模块中的action…...

Vue 2 插槽

可以先阅读组件基础-简单了解通过插槽分发内容。 一、插槽定义 插槽将子组件标签间的内容分发到子组件模板的<slot>标签位置。 如果没有<slot>标签&#xff0c;那么该内容将被丢弃。 二、编译作用域 内容在哪个作用域编译&#xff0c;就可以访问哪个作用域的数据…...

Spring 容器启动耗时统计

为了了解 Spring 为什么会启动那么久&#xff0c;于是看了看怎么统计一下加载 Bean 的耗时。 极简版 几行代码搞定。 import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor;import java.util.HashMap; imp…...

1. 优化算法学习

参考文献 1609&#xff1a;An overview of gradient descent optimization algorithms 从 SGD 到 Adam —— 深度学习优化算法概览(一) - 知乎 机器学习札记 - 知乎...

再获荣誉丨通付盾WAAP解决方案获“金鼎奖”优秀金融科技解决方案

今年四月&#xff0c;2023中国国际金融展在首钢会展中心成功落下帷幕。中国国际金融展作为金融开放创新成果的展示、交流、传播平台&#xff0c;历经多年发展,已成为展示中国金融发展成就、宣传金融改革成果、促进金融产业创新和推动金融信息化发展的有效平台。 “金鼎奖”评选…...

【腾讯云 TDSQL-C Serverless 产品测评】“橡皮筋“一样的数据库『MySQL高压篇』

【腾讯云 TDSQL-C Serverless 产品测评】"橡皮筋"一样的数据库 活动介绍服务一览何为TDSQL &#xff1f;Serverless 似曾相识&#xff1f; 降本增效&#xff0c;不再口号&#xff1f;动手环节 --- "压力"山大实验前瞻稍作简介资源扩缩范围&#xff08;CCU&…...

python http文件上传

server端代码 import os import cgi from http.server import SimpleHTTPRequestHandler, HTTPServer# 服务器地址和端口 host = 0.0.0.0 port = 8080# 处理文件上传的请求 class FileUploadHandler(SimpleHTTPRequestHandler):def do_POST(self):# 解析多部分表单数据form = …...

Android学习之路(9) Intent

Intent 是一个消息传递对象&#xff0c;您可以用来从其他应用组件请求操作。尽管 Intent 可以通过多种方式促进组件之间的通信&#xff0c;但其基本用例主要包括以下三个&#xff1a; 启动 Activity Activity 表示应用中的一个屏幕。通过将 Intent 传递给 startActivity()&…...

vue项目配置git提交规范

vue项目配置git提交规范 一、背景介绍二、husky、lint-staged、commitlint/cli1.husky2.lint-staged3.commitlint/cli 三、具体使用1.安装依赖2.运行初始化脚本3.在package.json中配置lint-staged4.根目录新增 commitlint.config.js 4.提交测试1.提示信息格式错误时2.eslint校验…...

影响交叉导轨运行速度的因素有哪些?

交叉导轨具有精度高&#xff0c;速度快&#xff0c;承载能力大、结构简单等特点&#xff0c;被广泛应用在固晶机、点胶设备、自动化设备、OA机器及其周边机器、测定器、印刷基板开孔机&#xff0c;精密机器&#xff0c;光学测试仪、光学工作台、操纵机构、X 射缐装置等的滑座部…...

List转Map

一、list转map Map<Long, User> maps userList.stream().collect(Collectors.toMap(User::getId,Function.identity())); 看来还是使用JDK 1.8方便一些。 二、另外&#xff0c;转换成map的时候&#xff0c;可能出现key一样的情况&#xff0c;如果不指定一个覆盖规则&…...

ES:一次分片设计问题导致的故障

### 现象&#xff1a; 1. 单节点CPU持续高 2.写入骤降 3.线程池队列积压&#xff0c;但没有reject 4.使用方没有记录日志 ### 排查 1.ES监控 只能看到相应的结果指标&#xff0c;无法反应出原因。 2.ES日志&#xff1a;大量日志打印相关异常&#xff08;routate等调用栈&a…...

vue 简单实验 自定义组件 综合应用 传参数 循环

1.代码 <script src"https://unpkg.com/vuenext" rel"external nofollow" ></script> <div id"todo-list-app"><ol><!--现在我们为每个 todo-item 提供 todo 对象todo 对象是变量&#xff0c;即其内容可以是动态的。…...

【OpenCV实战】2.OpenCV基本数据类型实战

OpenCV基本数据类型实战 〇、实战内容1 OpenCV helloworld1.1 文件结构类型1.2 CMakeList.txt1.3 Helloworld 2. Image的基本操作3. OpenCV 基本数据类型4. 读取图片的像素 & 遍历图片4.1 获取制定像素4.2 遍历图片 5. 图片反色5.1 方法1 &#xff1a;遍历5.2 方法2 &#…...

MyBatis进阶:告别SQL注入!MyBatis分页与特殊字符的正确使用方式

目录 引言 一、使用正确的方式实现分页 1.1.什么是分页 1.2.MyBatis中的分页实现方式 1.3.避免SQL注入的技巧 二、特殊字符的正确使用方式 2.1.什么是特殊字符 2.2.特殊字符在SQL查询中的作用 2.3.如何避免特殊字符引起的问题 2.3.1.使用CDATA区段 2.3.2.使用实体引…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...