当前位置: 首页 > 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;如何进一步严格挑选玻璃。 简介 玻璃替换方法…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...