Java面向对象七大原则以及设计模式单例模式和工厂模式简单工厂模式
面向对象的七大原则(OOP)
1,开闭原则:
对扩展开发,对修改关闭
2.里氏替换原则:
继承必须确保超类所拥有的子类的性质在子类中仍然成立
3.依赖倒置原则:
面向接口编程,不要面向实现编程,降低程序之间的耦合性
4.单一职责原则:
控制类的粒度大小,将对象解耦,提高其内聚性
5.接口隔离原则:
要为各个类创建他们专用的接口
6.迪米特法则:
只于你的直接朋友交谈,不跟陌生人交谈
7.合成复用法则:
尽量先使用组合或者聚合等关联来实现,其次才考虑使用集成关系来实现
单例模式
饿汉模式
public class Hunger{private Hunger(){}private final static Hunger HUNGER_SINGLTON = new Hunger();public static Hunger getInstrente(){return HUNGER_SINGLTON;}
}
懒汉模式
第一种,不考虑安全的问题
public class LayzeMan{private static LayzMan LAYZE_MAN;private LayzeMan(){System.out.println(Thread.currentThread().getName()+"ok");}public static LayzeMan getInstrence(){if(LAYZE_MAN == null){LATZE_MAN = new LayzeMan();}return LAYZE_MAN;}
}
/**
该单例模式在使用普通创建对象时,可以实现对象的单例
还存在两个问题
- 使用多线程可以破坏该单例模式
- 使用反射可以破坏该单例模式
解决多线程破坏单例模式的方法
public class Layze{private volatile static Layze lay;private Layze(){}/**三重检测锁 DCL模式**/public static Layze getInstance(){if(lay == null){synchorized(Layze.class){if(lzy == null){lay = new Layze(); }}}}
}
此时使用多线程破坏单例模式的问题已经可以解决
解决反射破坏单例模式的问题
public calss LayzeMan{private static volatile LayzeMan layze;private LayzeMan(){synchorized(LayzeMan.class){if(layze !=null){throw new RuntimeException("不要试图使用反射去破坏我的单例模式");}}}public static LayzeMan getInstrence(){if(layze == null){synchorized(LayzeMan.class){if(layze == null){layze = new LayzeMan();}}}return layze;}
}
class test{public static void main(String[] args){LayzeMan layzeMan = LayzeMan.getInstrence();Constructor<LazyPJie> declaredConstructor = LazyPJie.class.getDeclaredConstructor(null);declaredConstructor.setAccessible(true);LazyPJie lazyPJie1 = declaredConstructor.newInstance();System.out.println(lazyPJie);System.out.println(lazyPJie1);}
}
此时会报错
Exception in thread "main" java.lang.reflect.InvocationTargetExceptionat java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)at com.itcast.designMode.single.Test01.main(LazyPJie.java:41)
Caused by: java.lang.RuntimeException: 不要试图使用反射破坏单例模式
此时还会有一个问题:就是在类中判断对象是否为空时,判断了有没有第一个对象用普通方式去创建对象的时候,这个时候使用反射的时候就会报出异常,但是,此时如果两个对象都使用反射去创建就会出问题,单例模式就会又被破坏
代码如下
public static void main(String[] args) throws Exception {/* LazyPJie lazyPJie = LazyPJie.getInstance();*/Constructor<LazyPJie> declaredConstructor = LazyPJie.class.getDeclaredConstructor(null);declaredConstructor.setAccessible(true);LazyPJie lazyPJie1 = declaredConstructor.newInstance();LazyPJie lazyPJie = declaredConstructor.newInstance();System.out.println(lazyPJie);System.out.println(lazyPJie1);}
解决完全使用反射破坏单例模式
public calss LayzeMan{private static volatile LayzeMan layze;private static boolean flag = flase;private LayzeMan(){synchorized(LayzeMan.class){if(!flag){flag = ture;}else{throw new RuntimeException("不要试图使用反射去破坏我的单例模式");}}}public static LayzeMan getInstrence(){if(layze == null){synchorized(LayzeMan.class){if(layze == null){layze = new LayzeMan();}}}return layze;}
}
class test{public static void main(String[] args) throws Exception {/* LazyPJie lazyPJie = LazyPJie.getInstance();*/Constructor<LazyPJie> declaredConstructor = LazyPJie.class.getDeclaredConstructor(null);declaredConstructor.setAccessible(true);LazyPJie lazyPJie1 = declaredConstructor.newInstance();LazyPJie lazyPJie = declaredConstructor.newInstance();System.out.println(lazyPJie);System.out.println(lazyPJie1);}
}
枚举(天然的单例模式)
package com.itcast.designMode.single;/*** author:hlc* date:2023/9/18*/
public enum EnumClass {ENUM_CLASS;public EnumClass getEnumClass(){return ENUM_CLASS;}
}
class Test03{public static void main(String[] args) {EnumClass enumClass = EnumClass.ENUM_CLASS;}
}
静态内部类
package com.itcast.designMode.single;/*** author:hlc* date:2023/9/18*/
public class Holder {/*** 静态内部类实现单例模式*/private Holder(){}public static Holder getInstance(){return InnerClass.HOLDER;}public static class InnerClass{private static final Holder HOLDER = new Holder();}
}
工厂模式
- 实现了创建者和调用者的分离
- 满足原则
- 开闭原则
- 依赖倒转原则
- 迪米特法则
实例化对象不使用new,而是使用方法
简单工厂模式
package com.itcast.designMode.factory;public interface Car {void name();
}
package com.itcast.designMode.factory;/*** author:hlc* date:2023/9/18*/
public class Tesila implements Car{@Overridepublic void name() {System.out.println("特斯拉");}
}package com.itcast.designMode.factory;/*** author:hlc* date:2023/9/18*/
public class WuLing implements Car{@Overridepublic void name() {System.out.println("五菱");}
}
package com.itcast.designMode.factory;/*** author:hlc* date:2023/9/18*/
public class CarFactory {public static Car getCar(String name){if (name.equals("五菱")){return new WuLing();}else if (name.equals("特斯拉")){return new Tesila();}else {return null;}}
}
public static void main(String[] args) {Car car = CarFactory.getCar("五菱");Car car1 = CarFactory.getCar("特斯拉");car1.name();car.name();}
相关文章:
Java面向对象七大原则以及设计模式单例模式和工厂模式简单工厂模式
面向对象的七大原则(OOP) 1,开闭原则: 对扩展开发,对修改关闭 2.里氏替换原则: 继承必须确保超类所拥有的子类的性质在子类中仍然成立 3.依赖倒置原则: 面向接口编程,不要面向实现编程&am…...

Linux 遍历目录(cd 命令)
Linux 遍历目录(cd 命令) 文章目录 Linux 遍历目录(cd 命令)一、cd 命令二、绝对文件路径三、相对文件路径 一、cd 命令 在 Linux 文件系统上,可以使用 cd 命令将 shell 会话切换到另一个目录。cd 命令的格式也很简单…...

整合Nginx实现反向代理
针对后端启动多个服务,接口需要统一请求路径时,可以使用nginx进行请求地址反向代理。 1.下载: nginx 2.下载完成后解压,找到配置文件nginx.conf(在解压文件的conf目录中),在http中增加以下示例代码&#x…...
Linux:IP转INT详解
一、IP地址介绍 IP地址(Internet Protocol Address)是指互联网协议地址,是所有连接到网络设备的唯一标识符。IP地址由32位二进制数表示,通常以四段十进制数(每个数值范围为0-255)表示,例如192.1…...

43.MQ—RabbitMQ
目录 一、MQ—RabbitMQ。 (1)同步调用与异步调用。 (1.1)同步调用。 (1.2)异步调用。 (2)MQ之间的区别。 (3)RabbitMQ学习。 (3.1…...
Leetcode154. 寻找旋转排序数组中的最小值(存在重复元素)
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums [0,1,4,4,5,6,7] 在变化后可能得到:…...
docker查看镜像的latest对应的具体版本
查询容器镜像时,TAG只显示latest,而不是显示具体的版本号 docker images # 显示内容 REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 605c77e624dd 20 months ago 141MB redis latest 7614ae945…...

RabbitMQ深入 —— 死信队列
前言 前面荔枝梳理了RabbitMQ中的普通队列、交换机以及相关的知识,在这篇文章中荔枝将会梳理RabbitMQ的一个重要的队列 —— 死信队列,主要了解消息流转到死信队列的三种的方式以及相应的实现demo。希望能帮助到有需要的小伙伴~~~ 文章目录 前言 死信队…...
【React + Umi】自定义离开页面拦截弹框事件
在 react umi 中对离开页面的行为进行自定义弹窗拦截控制。以下为可选的方案分析。 wrapper 首先,因为项目框架是 umi,最先想到了 umi 路由的 wrapper 装饰器,但仔细一想又不太对, wrapper 争对于跳转到某个特定页面的前置行为…...

S1FD40A180H-ASEMI快恢复二极管S1FD40A180H
编辑:ll S1FD40A180H-ASEMI快恢复二极管S1FD40A180H 型号:S1FD40A180H 品牌:ASEMI 封装:TO-247 特性:大功率、快恢复二极管 正向电流:40A 反向耐压:1800V 恢复时间:<300n…...

网络编程 day1
1->x.mind网络编程基础 2->简述字节序的概念,并用共用体(联合体)的方式计算本机的字节序 1.字节序是指不同类型的CPU主机,内存存储多字节整数序列的方式 2.小端字节序:低序字节存储在低地址上 3.大端字节序&a…...

《深入PostgreSQL的存储引擎:原理与性能》
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🐅🐾猫头虎建议程序员必备技术栈一览表📖: 🛠️ 全栈技术 Full Stack: 📚…...

python开发之个微群聊机器人的开发
简要描述: 退出群聊 请求URL: http://域名地址/quitChatRoom 请求方式: POST 请求头Headers: Content-Type:application/jsonAuthorization:login接口返回 参数: 参数名必选类型说明wI…...

【Redis7】--4.事务、管道、发布和订阅
文章目录 事务1.Redis事务2.Redis事务特性3.Redis事务命令3.1MULTI3.2EXEC3.3DISCARD3.4WATCH3.5UNWATCH 4.不保证原子性4.1"全体连坐"4.2"冤头债主" 5.事务执行流程 管道1.pipeline的使用2.pipeline小总结 发布和订阅1.常用命令1.1SUBSCRIBE1.2PUBLISH1.3…...
【Vue】el 和 data短小精湛的细节!
hello,我是小索奇,精心制作的Vue教程持续更新哈,花费了大量的时间和精力,总结拓展了很多疑难点,想要学习&巩固&避坑就一起学习叭~ el 与 data 的两种写法 el共有2种写法 el表达式主要用来在模板中展示数据,它…...

前端screenfull实现界面全屏展示功能
还是先引入依赖 我们要先执行 npm config set registry https://registry.npmjs.org/将本地npm registry地址设置为官方的npm registry地址 不然这个东西安装会有点问题 然后我们执行命令安装 npm install screenfull安装完之后 我们终端执行一下 npm config delete registr…...
Dockerfile 制作常用命令总结
1.FROM( from ) : FROM : from 表示选择一个镜像作为基础镜像(在一个Dockerfile 中可以使用多条from,来构建多个镜像) 2.ENV : 用来在镜像创建出的容器中声明环境变量,如: ENV PYTHONIOENCODINGutf-8 …...

uniapp项目实践总结(十七)实现滚动触底加载
导语:在日测的开发过程中,经常会碰到页面需要渲染大量数据的情况,这时候就需要用到滚动加载功能,下面总结一下方法。 目录 原理分析实战演练案例展示 原理分析 使用scrolltolower事件来监听滚动到底部,然后加载下一…...

SAP入门到放弃系列之QM质量检验流程概述
目录 一、流程概述二、操作步骤概述2.1 主数据维护2.2 业务操作 一、流程概述 质量检验流程-Inspection Process Flow,通常由于预先设定的一些规则条件自动触发或者手工触发,例如库存地之间的调拨、生产完工入库检验、采购入库的检验、客户交货前检验等等。另外还有…...

Ansys Zemax | 光学系统设计中如何使用玻璃替换方法来优化玻璃
在光学系统中选择最优玻璃材料时,Conrady d-D以及模型玻璃等传统的玻璃选择方法提供的帮助有限。本文介绍了如何使用玻璃替换方法进行直接玻璃优化,以及在考虑玻璃的可用性、成本及耐候性等因素时,如何进一步严格挑选玻璃。 简介 玻璃替换方法…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...

rknn toolkit2搭建和推理
安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 ,不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源(最常用) conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...