设计模式——合成复用原则
文章目录
- 合成复用原则
- 设计原则核心思想
- 合成案例
- 聚合案例
- 继承案例
- 优缺点
合成复用原则
原则是尽量使用合成/聚合的方式,而不是使用继承
设计原则核心思想
- 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
- 针对接口编程,而不是针对实现编程。
- 为了交互对象之间的松耦合设计而努力
合成案例
假设我们有一个汽车类(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 方法,分别输出狗的吠声和猫的喵声。
这个示例展示了如何使用继承来创建一个动物类的继承体系。通过继承,我们可以在派生类中重用基类的属性和方法,并根据需要进行定制化。继承提供了代码的复用和扩展性,但也需要注意继承关系的合理使用,避免过度继承和耦合。
优缺点
与继承关系相比,合成复用原则具有以下优点:
- 更加灵活:通过合成或聚合关系,可以在运行时动态地改变对象的行为,而不需要修改代码。
- 降低耦合性:合成或聚合关系可以减少类之间的依赖关系,降低耦合性,使系统更加灵活和可维护。
- 更好的代码复用:通过合成或聚合关系,可以将现有的类组合在一起,创建新的类来实现代码的复用,避免了继承关系的局限性。
相关文章:
设计模式——合成复用原则
文章目录 合成复用原则设计原则核心思想合成案例聚合案例继承案例优缺点 合成复用原则 原则是尽量使用合成/聚合的方式,而不是使用继承 设计原则核心思想 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。…...
基于OpenCV实战(基础知识一)
目录 简介 1.计算机眼中的图像 2.图片的读取、显示与保存 3.视频的读取与显示 简介 OpenCV是一个流行的开源计算机视觉库,由英特尔公司发起发展。它提供了超过2500个优化算法和许多工具包,可用于灰度、彩色、深度、基于特征和运动跟踪等的图像处理和…...
如何高效的接入第三方接口
作为程序员的我们,经常会接到领导的安排,接入某某的接口,方面我们如何如何, 例如:领导在1号时给作为员工的你说,最近系统需要增加一个新的支付方式,一会和对方技术组建一个群,有什么问题,可以直接在群里说,最近还说,尽快接入,客户等着用,让你在5号前,完成接入工…...
docker pip下载依赖超时或失败问题解决
Docker容器使用pip安装Python库时超时,可能是由于多种原因。以下是一些建议和解决方法: 使用国内镜像源: 如果你位于中国,可以尝试更换到国内的镜像源。例如,可以使用阿里云、腾讯云、清华大学提供的镜像。 你可以在Dockerfile中添…...
python并发编程
一、程序提速的方法 二、python对并发编程的支持 多线程:threading,利用CPU和IO可以同时执行的原理,让CPU不会干巴巴等待IO完成;多进程:multiprocess,利用多核CPU的能力,真正的并行执行任务&am…...
【面试题】:前端怎么实现权限设计及遇到的bug
一.权限的概念 前端权限分为页面权限、按钮权限、API权限。 二.页面权限的实现过程 ①用户登录进去调用获取用户信息接口,后端会给我们返回一个权限标识符 ②在获取到数据之后,我们就要判断用户能访问到哪些页面,我们可以在vuex中permission模块中的action…...
Vue 2 插槽
可以先阅读组件基础-简单了解通过插槽分发内容。 一、插槽定义 插槽将子组件标签间的内容分发到子组件模板的<slot>标签位置。 如果没有<slot>标签,那么该内容将被丢弃。 二、编译作用域 内容在哪个作用域编译,就可以访问哪个作用域的数据…...
Spring 容器启动耗时统计
为了了解 Spring 为什么会启动那么久,于是看了看怎么统计一下加载 Bean 的耗时。 极简版 几行代码搞定。 import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor;import java.util.HashMap; imp…...
1. 优化算法学习
参考文献 1609:An overview of gradient descent optimization algorithms 从 SGD 到 Adam —— 深度学习优化算法概览(一) - 知乎 机器学习札记 - 知乎...
再获荣誉丨通付盾WAAP解决方案获“金鼎奖”优秀金融科技解决方案
今年四月,2023中国国际金融展在首钢会展中心成功落下帷幕。中国国际金融展作为金融开放创新成果的展示、交流、传播平台,历经多年发展,已成为展示中国金融发展成就、宣传金融改革成果、促进金融产业创新和推动金融信息化发展的有效平台。 “金鼎奖”评选…...
【腾讯云 TDSQL-C Serverless 产品测评】“橡皮筋“一样的数据库『MySQL高压篇』
【腾讯云 TDSQL-C Serverless 产品测评】"橡皮筋"一样的数据库 活动介绍服务一览何为TDSQL ?Serverless 似曾相识? 降本增效,不再口号?动手环节 --- "压力"山大实验前瞻稍作简介资源扩缩范围(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 是一个消息传递对象,您可以用来从其他应用组件请求操作。尽管 Intent 可以通过多种方式促进组件之间的通信,但其基本用例主要包括以下三个: 启动 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校验…...
影响交叉导轨运行速度的因素有哪些?
交叉导轨具有精度高,速度快,承载能力大、结构简单等特点,被广泛应用在固晶机、点胶设备、自动化设备、OA机器及其周边机器、测定器、印刷基板开孔机,精密机器,光学测试仪、光学工作台、操纵机构、X 射缐装置等的滑座部…...
List转Map
一、list转map Map<Long, User> maps userList.stream().collect(Collectors.toMap(User::getId,Function.identity())); 看来还是使用JDK 1.8方便一些。 二、另外,转换成map的时候,可能出现key一样的情况,如果不指定一个覆盖规则&…...
ES:一次分片设计问题导致的故障
### 现象: 1. 单节点CPU持续高 2.写入骤降 3.线程池队列积压,但没有reject 4.使用方没有记录日志 ### 排查 1.ES监控 只能看到相应的结果指标,无法反应出原因。 2.ES日志:大量日志打印相关异常(routate等调用栈&a…...
vue 简单实验 自定义组件 综合应用 传参数 循环
1.代码 <script src"https://unpkg.com/vuenext" rel"external nofollow" ></script> <div id"todo-list-app"><ol><!--现在我们为每个 todo-item 提供 todo 对象todo 对象是变量,即其内容可以是动态的。…...
【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 :遍历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.使用实体引…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
