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

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;}
}
/**

该单例模式在使用普通创建对象时,可以实现对象的单例

还存在两个问题

  1. 使用多线程可以破坏该单例模式
  2. 使用反射可以破坏该单例模式

解决多线程破坏单例模式的方法

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();}
}

工厂模式

  1. 实现了创建者和调用者的分离
  2. 满足原则
    1. 开闭原则
    2. 依赖倒转原则
    3. 迪米特法则

实例化对象不使用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面向对象七大原则以及设计模式单例模式和工厂模式简单工厂模式

面向对象的七大原则&#xff08;OOP&#xff09; 1,开闭原则&#xff1a; 对扩展开发&#xff0c;对修改关闭 2.里氏替换原则&#xff1a; 继承必须确保超类所拥有的子类的性质在子类中仍然成立 3.依赖倒置原则&#xff1a; 面向接口编程&#xff0c;不要面向实现编程&am…...

Linux 遍历目录(cd 命令)

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

整合Nginx实现反向代理

针对后端启动多个服务&#xff0c;接口需要统一请求路径时&#xff0c;可以使用nginx进行请求地址反向代理。 1.下载: nginx 2.下载完成后解压&#xff0c;找到配置文件nginx.conf&#xff08;在解压文件的conf目录中&#xff09;&#xff0c;在http中增加以下示例代码&#x…...

Linux:IP转INT详解

一、IP地址介绍 IP地址&#xff08;Internet Protocol Address&#xff09;是指互联网协议地址&#xff0c;是所有连接到网络设备的唯一标识符。IP地址由32位二进制数表示&#xff0c;通常以四段十进制数&#xff08;每个数值范围为0-255&#xff09;表示&#xff0c;例如192.1…...

43.MQ—RabbitMQ

目录 一、MQ—RabbitMQ。 &#xff08;1&#xff09;同步调用与异步调用。 &#xff08;1.1&#xff09;同步调用。 &#xff08;1.2&#xff09;异步调用。 &#xff08;2&#xff09;MQ之间的区别。 &#xff08;3&#xff09;RabbitMQ学习。 &#xff08;3.1&#xf…...

Leetcode154. 寻找旋转排序数组中的最小值(存在重复元素)

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 已知一个长度为 n 的数组&#xff0c;预先按照升序排列&#xff0c;经由 1 到 n 次 旋转 后&#xff0c;得到输入数组。例如&#xff0c;原数组 nums [0,1,4,4,5,6,7] 在变化后可能得到&#xff1a;…...

docker查看镜像的latest对应的具体版本

查询容器镜像时&#xff0c;TAG只显示latest&#xff0c;而不是显示具体的版本号 docker images # 显示内容 REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 605c77e624dd 20 months ago 141MB redis latest 7614ae945…...

RabbitMQ深入 —— 死信队列

前言 前面荔枝梳理了RabbitMQ中的普通队列、交换机以及相关的知识&#xff0c;在这篇文章中荔枝将会梳理RabbitMQ的一个重要的队列 —— 死信队列&#xff0c;主要了解消息流转到死信队列的三种的方式以及相应的实现demo。希望能帮助到有需要的小伙伴~~~ 文章目录 前言 死信队…...

【React + Umi】自定义离开页面拦截弹框事件

在 react umi 中对离开页面的行为进行自定义弹窗拦截控制。以下为可选的方案分析。 wrapper 首先&#xff0c;因为项目框架是 umi&#xff0c;最先想到了 umi 路由的 wrapper 装饰器&#xff0c;但仔细一想又不太对&#xff0c; wrapper 争对于跳转到某个特定页面的前置行为…...

S1FD40A180H-ASEMI快恢复二极管S1FD40A180H

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

网络编程 day1

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

《深入PostgreSQL的存储引擎:原理与性能》

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f405;&#x1f43e;猫头虎建议程序员必备技术栈一览表&#x1f4d6;&#xff1a; &#x1f6e0;️ 全栈技术 Full Stack: &#x1f4da…...

python开发之个微群聊机器人的开发

简要描述&#xff1a; 退出群聊 请求URL&#xff1a; http://域名地址/quitChatRoom 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明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&#xff0c;我是小索奇&#xff0c;精心制作的Vue教程持续更新哈&#xff0c;花费了大量的时间和精力&#xff0c;总结拓展了很多疑难点&#xff0c;想要学习&巩固&避坑就一起学习叭~ 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 表示选择一个镜像作为基础镜像&#xff08;在一个Dockerfile 中可以使用多条from&#xff0c;来构建多个镜像&#xff09; 2.ENV &#xff1a; 用来在镜像创建出的容器中声明环境变量&#xff0c;如&#xff1a; ENV PYTHONIOENCODINGutf-8 …...

uniapp项目实践总结(十七)实现滚动触底加载

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

SAP入门到放弃系列之QM质量检验流程概述

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

Ansys Zemax | 光学系统设计中如何使用玻璃替换方法来优化玻璃

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

springboot基础--实现默认登录页面

1、搭建项目 依赖中 多加入thymeleaf依赖 <dependencies><!--thymeleaf的依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!--we…...

TDesign WXS语法

目录 一、输出函数返回值如何获取&#xff1f; 二、WXS语法 三、WXS案例 一、输出函数返回值如何获取&#xff1f; 写在js的方法中 wxml中{{方法名()}}输出&#xff1a; 发现不显示&#xff1f;&#xff1f; 所以不能使用这种方式&#xff01;&#xff01; 二、WXS语法 1.…...

Iterator设计模式

目录 1、示例 1.1 Aggregate接口 1.2 Iterator接口 1.3 Book类 1.4 BookShelf类 1.6 BookShelfIterator 类 1.7 Main类 2、解释Iterator模式中的角色 2.1 Iterator模式的存在意义 2.2 抽象类和接口 2.3 Aggregate 和 Iterator的对应 2.4 容易弄错"下一个"…...

ROS 入门

目录 简介 ROS诞生背景 ROS的设计目标 ROS与ROS2 安装ROS 1.配置ubuntu的软件和更新 2.设置安装源 3.设置key 4.安装 5.配置环境变量 安装可能出现的问题 安装构建依赖 卸载 ROS架构 1.设计者 2.维护者 3. 立足系统架构: ROS 可以划分为三层 ROS通信机制 话…...

第四章 Linux网络编程

ARP 协议 ARP 协议&#xff08;Address Resolution Protocol&#xff09;通过 IP 地址查找对应的 MAC 地址。 当一个主机需要发送数据给另一个主机时&#xff0c;它首先会检查本地的 ARP 缓存表&#xff08;ARP cache&#xff09;中是否存在目标主机的 MAC 地址。如果存在&…...

无涯教程-JavaScript - OFFSET函数

描述 OFFSET函数返回对范围的引用,该范围是一个单元格或单元格范围中指定的行数和列数。 返回的引用可以是单个单元格或单元格范围。您可以指定要返回的行数和列数。 语法 OFFSET (reference, rows, cols, [height], [width]) 争论 Argument描述Required/OptionalReferenc…...

rust切片

切片类型写为[T]。 切片是序列的一个片段。 它是动态大小类型&#xff0c;所以要使用切片类型&#xff0c;就必须使用它的指针类型。引用是最常用的指针类型。 [T; n]能隐式转换成[T]。 一、定义切片 &#xff08;一&#xff09;不可变切片 &[T]&#xff0c;共享切片&…...

2023/9/18 -- C++/QT

作业 完善登录框 点击登录按钮后&#xff0c;判断账号&#xff08;admin&#xff09;和密码&#xff08;123456&#xff09;是否一致&#xff0c;如果匹配失败&#xff0c;则弹出错误对话框&#xff0c;文本内容“账号密码不匹配&#xff0c;是否重新登录”&#xff0c;给定两…...

vue柱状图+折线图组合

<template><div id"main" style"width: 100%;height: 500px; padding-top: .6rem"></div> </template>data() {return {weekData: ["1周","2周","3周","4周","5周","6周&…...

js中如何实现一个简单的防抖函数?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 防抖函数⭐ 使用示例⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏…...

做网站站长/惠州关键词排名提升

build命令简述 在Golang中&#xff0c;build过程主要由go build执行。它完成了源码的编译与可执行文件的生成。 go build接收参数为.go文件或目录&#xff0c;默认情况下编译当前目录下所有.go文件。在main包下执行会生成相应的可执行文件&#xff0c;在非main包下&#xff0…...

那网站做问答/百度网址是多少

经常使用JBuilder开发工具的人都知道&#xff0c;在JBuilder中开发Swing应用程序是比较方便的&#xff0c;虽然比不上曾经红遍一时的Visual Basic&#xff0c;但开发界面的工作确实被大大简化了。 JBuilder2007版本已经发布了&#xff0c;当我第一时间知道JBuilder2007发布…...

泉州定制网站建设/百度搜索网站

接到客户那边的问题&#xff0c;说电脑不时的会出现一些自动弹出的IE浏览器&#xff0c;都是些广告信息。估计是客户电脑的浏览器被劫持了。通过客户发过来的截图信息&#xff0c;会出现一个scandisk.exe的错误报告&#xff0c;估计问题就出在这里。网上查询了一下这个流氓软件…...

asp.net网站发布到虚拟主机/重庆网站seo搜索引擎优化

在传统的Web开发之外的领域&#xff0c;Python开发人员的就业机会越来越多&#xff0c;无论你是初学者还是大神&#xff0c;现在正是投入到Python学习的好时机。一个IBM的博客文章报道了如今在数据科学和机械领域的主要语言&#xff0c;我们以此绘制了DataScienceCentral的数据…...

临沂制作网站多少钱/武汉网站seo推广公司

10. 总结<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />本节将会对前面给出的算法和系统做一个总结&#xff0c;并为乐观复制系统的设计者和用户给出一些建议。10.1 对比乐观复制策略<?xml:namespace prefix v ns "…...

专门做店铺转让的网站/竞价推广账户竞价托管收费

经过几个实验,我来到了一个令人满意的解决方案,这也保留了顶部可见项目的细滚动位置.事实上,需要保存和恢复三个不同的信息&#xff1a;列表状态(例如哪些组被展开),第一个可视项目的索引以及它的微滚动位置.不幸的是,似乎只有第一个被可扩展列表视图的onSaveInstanceState方法…...