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

设计原则、工厂、单例模式

什么是设计模式

简单来说,设计模式就是很多程序员经过相当长的一段时间的代码实践、踩坑所总结出来的一套解决方案,这个解决方案能让我们少写一些屎山代码,能让我们写出来的代码写出来更加优雅,更加可靠。所以设计模式的好处是显而易见的。
当然,设计模式不仅仅能够让我们写出更好的代码,他还有些好处,

  • 我们在读框架、中间件源码的时候,我们会设计模式,就能够更好的去理清源码的整个逻辑,读起来也会轻松不少。
  • 面试的时候,设计模式还是问的比较多的,所以呢,设计模式学得好,工作少不了。

七大设计原则

  • 单一职责原则 Single ResponsibilityPrinciple

一个类应该只有一个发生变化的原因,否则类应该被拆分;

用我们自己的话来说就是:一个类只负责一项职责、只做一件事情;也就是说要做到代码功能的原子性;比如说我们在
做项目的时候,用户模块里就只处理用户相关的业务,商品服务里就只处理商品相关的业务,这样他们就不会互相影响
了,就解耦开来了。

  • 开闭原则 Open Closed Principle

对扩展开放、对修改关闭

意思就是我们写代码的时候,尽量在已有的代码上做扩展,比如说新增模块,新增方法,而不是去修改别人已经写好的代码。 这个估计大家感受很深刻,写代码最痛苦的事情,就是在别人的代码上做迭代了。当然这个原则上是尽量要这样,实际工作中,如果你的需求只要在别人的代码上改动非常少的代码就能实现,那我们也可以不要遵守这个原则了。

  • 里氏替换原则 Liskov SubstitutionPrinciple

子类对象是可以替换程序中父类对象出现的任何地方,并且保证原来的程序逻辑不变以及运行正确

换句话说,就是子类可以扩展父类的功能,但不能去改变父类原有的功能。

  • 接口隔离原则 Interface Segregation Principle

写代码的时候,接口不要写得太臃肿了,我们需要把接口拆分得更小,更专用。

  • 依赖倒置原则 Dependency Inversion Principle

设计代码结构时,高层模块不应依赖低层模块,两者都应该依赖抽象,抽象不应依赖细节,细节应该依赖抽象。

  • KISS 原则 keep it simple and stupid

保持它的简单和愚蠢。

也就是说我们的代码尽量要写得简单,不要为了炫技来写很多花里胡哨的代码,比如说,一个代码只要几个if else就能解
决了,而且后期几乎不可能再去升级,那这种代码其实就没必要用什么设计模式去做了,这样倒是搞得代码更加复杂
了。所以,咱们写代码,尽量不要用同事不懂的技术来写代码,也不要去重复造轮子,尽量用目前市面上比较成熟的开
源库,也不要做过度优化,把一些简单的代码弄得花里胡哨的。

  • YAGNI 原则 you ain’t gonna need it

你不需要它。

就是不要去做一些过度设计,比如说公司只用得到MySQL,你为了以后能够支持海量数据,直接把hadoop那套体系搬过来了,各种技术都引入进来,那是完全没有必要的。

  • DRY 原则 don’t repeat your code

不要写重复的代码。

  • 迪米特法则 law of demeter

他的核心主旨就是一个对象应该对其他对象保持最少的了解,也就是多个类之间尽量不要直接去依赖,如果你非要依赖,那也只能依赖必要的接口。其实也就是为了减少类和类之间的耦合,每个类越独立越好。这个其实就是我们正常开发中用到的策略,直接依赖接口,而不是依赖实现类。

设计模式分类

  1. 创建型(5种;处理对象的创建过程;工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式)
  2. 结构型(7种;处理类或者对象的组合;适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模 式、享元模式)
  3. 行为型(11种;对类或对象怎样交互和怎样分配职责进行描述;策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式)

对应到我们的编码开发过程,其实是一个有先后顺序的递进过程,我们来看一下:

  1. 首先,我们要去实现某个功能,肯定会要创建对象是吧,所以像:单例、工厂、建造者、原型都属于怎样去很好的创建对象,主要目的在于将对象的创建与使用分离;
  2. 然后,对象创建好了之后,就应该去考虑对象之间关系,如何更好的继承、依赖、组合,那么就衍生了很多结构型的模式,比如:门面、适配器、代理、装饰、组合、享元这些;
  3. 最后,前面2步做完了,就到了具体实现,怎样更好的达到目的,使行为更加清晰、效率更高,就是行为型模型 要做的事情,比如:策略,责任链、迭代器等等;

工厂模式

工厂(Factory),顾名思义,创建对象实例的生产工厂,以前我们创建对象都是 new Xxx(),如果我们使用工厂模式 的话,就可以用它来替代 new 操作,创建实例(对象);所以当你理解了工厂模式后,以后去 new 对象时就可以考 虑还能使用工厂模式达到一样的目的;虽然这样做,可能需要多做一些工作,但会给你系统带来更大的可扩展性和尽 量少的修改量(主要是 降低耦合);

工厂模式分为 3 种,包括:简单工厂模式、工厂方法模式、抽象工厂模式,接下来,我们逐一来看;

  • 简单工厂模式

简单工厂模式不属于 GOF 的 23 种经典设计模式,严格来说它应该属于一种编程习惯,这个简单工厂模式只是工厂方法模式的一种特例,所以工厂模式实际上只有工厂方法模式和抽象工厂模式。

简单工厂核心逻辑其实就是这样,将一堆 if else 判断从业务代码中剥离出来,然后塞到一个工厂类中,通过这个工厂来生产出我们想要的产品。这样我们在业务中就不需要关心这种逻辑了,一切都由工厂给我提供,就像你去买一个手机一样,你根本不用关心这个手机是怎么通过流水线生产出来的,就像我们这个代码里,也不用去关心这个上传服务实例是怎么生成的。

  • 工厂方法模式

工厂方法,核心思想是:将对象的创建逻辑下沉到子类里面(创建多个子工厂来创建对象)。

这种方式如果再要增加第三方上传服务时,就不需要修改工厂类的代码了,每个第三方服务都会有一个工厂,这样就解决了简单工厂模式的缺点,不过要相应地增加工厂类;工厂方法模式是简单工厂模式的进一步抽象,运用了多态性、克服了简单工厂模式的缺点。

  • 优点:获取对象时只需要知道具体工厂的名称,就可以得到对应的对象,无须知道具体创建过程;在系统增加新的类 时只需要添加对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;

  • 缺点:每增加一个类就要增加一个对应的具体工厂类,增加了系统的复杂度;

  • 抽象工厂模式

抽象工厂模式,直接通过案例分析:

  1. 定义了两个接口:ThirdPartyPush 和ThirdPartySMS,它们分别代表了第三方推送和短信服务。
  2. 创建了两个具体的类TencentThirdPartyPush 和TencentThirdPartySMS,它们实现了 ThirdPartyPush和 ThirdPartySMS 接口,分别表示腾讯的推送短信服务。
  3. 创建了另外两个具体的类,AliThirdPartyPush 和AliThirdPartySMS,它们也实现了 ThirdPartyPush 和ThirdPartySMS 接口,分别表示阿里的推送和短信服务。
  4. 定义了一个抽象工厂类 ThirdPartyTotalFactory,它包含两个抽象方法 createPusher 和 createSmser,用于创建不同厂商的推送服务和短信服务。
  5. 创建了具体的工厂类 AliFactory 和 TencentFactory,它们分别继承了 ThirdPartyTotalFactory 并实现了工厂类的抽象方法。AliFactory 用于创建阿里厂商的推送和短信服务,而 TencentFactory 用于创建腾讯厂商的推送和短信服务。使用抽象工厂模式创建不同厂商的推送和短信服务,并通过工厂方法将它们与具体的厂商实现解耦。这有助于现松耦合和易维护的代码结构。
public interface ThirdPartyPush {String push();
}
public interface ThirdPartySMS {String send();
}
public class TencentThirdPartyPush implements ThirdPartyPush {@Overridepublic String push() {return "腾讯推送";}
}
public class TencentThirdPartySMS implements ThirdPartySMS {@Overridepublic String send() {return "腾讯短信发送";}
}
public class AliThirdPartyPush implements ThirdPartyPush {@Overridepublic String push() {return "阿里推送";}
}
public class AliThirdPartySMS implements ThirdPartySMS {@Overridepublic String send() {return "阿里短信发送";}
}
public abstract class ThirdPartyTotalFactory {abstract ThirdPartyPush createPusher();abstract ThirdPartySMS createSmser();
}
public class AliFactory extends ThirdPartyTotalFactory {@OverrideThirdPartyPush createPusher() {return new AliThirdPartyPush();
}@OverrideThirdPartySMS createSmser() {return new AliThirdPartySMS();}
}
public class TencentFactory extends ThirdPartyTotalFactory {@OverrideThirdPartyPush createPusher() {return new TencentThirdPartyPush();
}@OverrideThirdPartySMS createSmser() {return new TencentThirdPartySMS();}
}

单例设计模式(Singleton Design Pattern)

理解起来非常简单。就是不管在任何情况下,一个类只能有一个对象。

  • 饿汉式

这种方式在类加载的时候就把服务实例初始化好了,所以这一步其实是线程安全的,不会说在多线程的环境下创建出很多个实例了。这种方式在对象类加载的时候就实例化了,所以其实有可能会造成一个问题,就是内存浪费,因为你不确定这个对象会不会使用,所以就会有一个懒汉式的模式,这个模式可以让我们在需要发短信的时候才创建这个实例对象,而不是一开始类加载的时候就创建。但是这个问题其实也不是问题,因为我们在项目中写代码,一定是有我们自己的考量的。当写了一个发送短信的服务
后,不可能说这个服务以后都不会调用的。而且,假设这种实例占用内存太多,那我们最好是能够在启动的时候就创建好,这样假如说有OOM的这种问题,我们也能及时发现,就是有问题我们要及时暴露出来,不要等到项目上线了才暴露出问题来,那样就很严重了。

public class SendSmsServiceHungrySingleton {
private static final SendSmsServiceHungrySingleton instance = newSendSmsServiceHungrySingleton();
private SendSmsServiceHungrySingleton() {}public static SendSmsServiceHungrySingleton getInstance() {return instance;}public String sendSms() {System.out.println("发送短信");return "OK";}
}
  • 懒汉式

饿汉式是比较饥饿,它立马就要拿到这个对象实例;懒汉,就是比较懒,它要等到调用的时候才创建对象实例。 这里就是直接在 getInstance 方法里面判断一下,这个实例有没有初始化,没有的话,我就初始化一下,已经初始化了就直接返回。

public class PushServiceLazySingleton {private static PushServiceLazySingleton instance;private PushServiceLazySingleton() {}public static PushServiceLazySingleton getInstance() {if(instance == null) {instance = new PushServiceLazySingleton();}return instance;}
}

这种方式实现起来还是比较简单的,代码逻辑很清晰。但是,这种方式其实在多线程的环境下是有问题的,它完全没办法保证我的项目里只会创建一个instance对象。

  1. 双重检查锁
    所以,我们引入一个新的解决方案,就是双重检查锁。这个锁什么意思,我们看代码就清楚了。
public class PushServiceLazyDoubleCheckSingleton {private static PushServiceLazyDoubleCheckSingleton instance;private PushServiceLazyDoubleCheckSingleton() {}public static PushServiceLazyDoubleCheckSingleton getInstance() {// 1. 第一次检查 instance 是否已经实例化if(instance == null) {synchronized(PushServiceLazyDoubleCheckSingleton.class) {// 2. 第二次检查 instance 是否已经实例化if(instance == null) {instance = new PushServiceLazyDoubleCheckSingleton();}}}return instance;}
}

这种情况下,其实还是有问题的,在一些极端的场景下,可能会有一个指令重排的问题。

  1. 静态内部类

还可以采用静态内部类的方式同样也是利用了类的加载机制,它与饿汉模式不同的是,它是在内部类里面去创建对象实例。这样的话,只要应用中不使用内部类,JVM就不会去加载这个单例类,也就不会创建单例对象,从而实现懒汉式的延迟加载。也就是说这种方式可以同时保证延迟加载和线程安全。

public class LazyStaticInnerClassSingleton {private LazyStaticInnerClassSingleton(){//解决反射破坏,因为反射可以调用私有的构造器if(LazyHolder.INSTANCE != null){throw new RuntimeException("不允许非法访问");}}
public static LazyStaticInnerClassSingleton getInstance(){return LazyHolder.INSTANCE;
}private static class LazyHolder{
private static final LazyStaticInnerClassSingleton INSTANCE = new LazyStaticInnerClassSingleton();}
}
  • 注册式
  1. 枚举单例

枚举类实现单例模式是极力推荐的单例实现模式,因为枚举是线程安全的,并且只会装载一次,枚举类是所有单例类 实现中唯一不会被破坏的单例模式(解决了反射与序列化破坏)

public enum SendServiceEnum {
INSTANCE;public static SendServiceEnum getInstance(){return INSTANCE;}public String send() {System.out.println("发送短信");return "OK";}
}
  1. 容器式单例
public final class ContainerSingleton {
private ContainerSingleton() {}
private static final ConcurrentHashMap<String, Object> instanceMap = new ConcurrentHashMap<>();
public static <T> T get(String key,Supplier<T> supplier) {
T instance = null;
if(!instanceMap.contains(key)) {
synchronized(ContainerSingleton.class) {
if(!instanceMap.contains(key)){instance = supplier.get();instanceMap.put(key,instance);
}else {instance = (T)instanceMap.get(key);
}
return instance;
}
}else {
return (T) instanceMap.get(key);
}
}
}

相关文章:

设计原则、工厂、单例模式

什么是设计模式 简单来说&#xff0c;设计模式就是很多程序员经过相当长的一段时间的代码实践、踩坑所总结出来的一套解决方案&#xff0c;这个解决方案能让我们少写一些屎山代码&#xff0c;能让我们写出来的代码写出来更加优雅&#xff0c;更加可靠。所以设计模式的好处是显而…...

笔记:Mysql 主从搭建

主库 创建用户并授权 create user slave identified with mysql_native_password by 123456 GRANT REPLICATION SLAVE ON *.* to slave%; FLUSH PRIVILEGES;主库配置文件 /etc/my.cnf #日志路径及文件名&#xff0c;目录要是mysql有权限写入 log-bin/var/lib/mysql/binlog …...

HTTP Error 400. The request hostname is invalid.

异常信息 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd"> <HTML><HEAD><TITLE>Bad Request</TITLE> <META HTTP-EQUIV"Content-Type" Content"text/html;…...

mysql日志( Redo Log 、Undo Log、Bin Log)

InnoDB是一个带有ACID事务支持的存储引擎&#xff0c;其中redo log和undo log是其实现原子性、一致性、隔离性和持久性&#xff08;ACID&#xff09;的重要机制。 Redo Log&#xff08;重做日志&#xff09; Redo log主要用于实现事务的持久性。它记录了后续可以用来恢复数据…...

HarmonyOS如何创建及调用三方库

介绍 本篇主要向开发者展示了在Stage模型中&#xff0c;如何调用已经上架到三方库中心的社区库和项目内创建的本地库。效果图如下&#xff1a; 相关概念 Navigation&#xff1a;一般作为Page页面的根容器&#xff0c;通过属性设置来展示页面的标题、工具栏、菜单。Tabs&#…...

我手写的轮子开源了

我手写的轮子开源了 文章目录 1.gitee坐标和地址1.1.gitee坐标1.2.gitee地址 2.github坐标和地址2.1.github坐标2.2.github地址 3.总结 1.gitee坐标和地址 1.1.gitee坐标 <dependency><groupId>io.gitee.bigbigfeifei</groupId><artifactId>es-sprin…...

第十九章 linux部署scrapyd

文章目录 1. linux部署python环境1. 部署python源文件环境2. 下载python3. 解压安装包4. 安装5. 配置环境变量6. 检查是否安装成功7. 准备python使用的包8. 安装scrapyd9. 配置scrapyd10. 开放6800端口 2. 部署gerapy1. 本机下载包2. 初始化3. 进入gerapy同步数据库4. 创建用户…...

微信打卡小程序怎么做_用户的每日习惯培养神器

微信打卡小程序&#xff1a;你的每日习惯培养神器 在这个快节奏的现代社会&#xff0c;我们每天都在忙碌中度过&#xff0c;有时候甚至会忘记自己曾经立下的那些小目标、小习惯。然而&#xff0c;随着科技的不断发展&#xff0c;微信打卡小程序的出现&#xff0c;为我们的生活…...

C语言数据在内存中的存储

reference n.提及&#xff0c;谈到&#xff1b;参考&#xff0c;查阅&#xff1b;&#xff08;引自书或诗歌的&#xff09;引言&#xff0c;引文&#xff1b; 引文的作者&#xff0c;参考书目&#xff1b;&#xff08;帮助或意见的&#xff09;征求&#xff0c;征询&#xff1b…...

管理公司员工上网行为的软件都有哪些?

随着互联网的飞速发展&#xff0c;企业面临的网络安全威胁也日益加剧。为了保护企业数据安全、提高工作效率&#xff0c;上网行为管理系统及其相关管理软件应运而生。 未来&#xff0c;随着技术的不断进步和网络安全威胁的不断演变&#xff0c;上网行为管理系统及其管理软件将不…...

手撕C语言题典——逆序输出

有这样一个问题&#xff1a;读入一些整数&#xff0c;逆序输出到一行中。已知的是该整数不超过100个。我们该怎么办呢&#xff1f;我们先将这些整数循环输入&#xff0c;输入每个整数之后&#xff0c;我们只能将数组存下来&#xff0c;而这个地方就是数组。 本章可能用到的知识…...

如果保障服务器的安全

如果保障服务器的安全 一、修改它最开始的密码&#xff0c;后期也要一直更换。一般如果有客户来了服务器的话&#xff0c;服务器厂商都会提前把所有的系统都装好&#xff0c;之后再把这个权限交到用户的手里。很多用户可能在这方面不会特别注意&#xff0c;密码也不修改&#x…...

【SQL】1280. 学生们参加各科测试的次数 (笛卡尔积)

前述 知识点回顾&#xff1a;数据库中的四大join & 笛卡尔乘积&#xff08;以MySQL为例&#xff09; 笛卡尔积的两种写法 select * from stu,class; select * from stu cross join class; 题目描述 leetcode题目&#xff1a;1280. 学生们参加各科测试的次数 Code 写法…...

高企认定中科技成果转化是什么呢?

其实&#xff0c;这是一个流程&#xff0c;可以用下面的分段进程来表示&#xff1a;企业开展科研立项—科研立项得到科研结果—科研结果用于产品的生产—新产品品质提高带动了销售的增加。 上面的流程&#xff0c;其实是高企审核的核心&#xff0c;不仅仅关系到了量化打分。更…...

第十二届蓝桥杯省赛CC++ 研究生组-货物摆放

还是整数分解问题,注意n本身也是约数 #include <iostream> int main(){printf("2430");return 0; }#include <iostream> #include<cmath> #include<algorithm> using namespace std; typedef long long ll; const ll n 2021041820210418LL…...

基于SpringBoot的学生成绩管理系统

基于SpringBootVue的家教管理系统的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 系统功能结构展示 登录界面图 现今&#xff0c;越来越多的人乐于选择一项合适的管理方案&#xff0c;但是普通用户往往受到管理经验地限制&…...

旅游管理系统 |基于springboot框架+ Mysql+Java+Tomcat的旅游管理系统设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 前台功能效果图 管理员功能登录前台功能效果图 系统功能设计 数据库E-R图设计 lunwen参考 摘要 研究…...

SpringBoot(整合MyBatis + MyBatis-Plus + MyBatisX插件使用)

文章目录 1.整合MyBatis1.需求分析2.数据库表设计3.数据库环境配置1.新建maven项目2.pom.xml 引入依赖3.application.yml 配置数据源4.Application.java 编写启动类5.测试6.配置类切换druid数据源7.测试数据源是否成功切换 4.Mybatis基础配置1.编写映射表的bean2.MonsterMapper…...

GAMES104-现代游戏引擎 1

主要学习重点还是面向就业&#xff0c;重点复习八股和算法 每天早上八点到九点用来学习这个课程 持续更新中... 第一节 游戏引擎导论 第二节 引擎架构分层 引擎是分层架构的 编辑器功能层资源层核心层平台层 越底层的代码越稳定越坚固&#xff0c;越上层的代码越灵活越开…...

idea 开发serlvet篮球秩序册管理系统idea开发mysql数据库web结构计算机java编程layUI框架开发

一、源码特点 idea开发 java servlet 篮球秩序册管理系统是一套完善的web设计系统mysql数据库 系统采用serlvetdaobean mvc 模式开发&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 servlet 篮…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...