当前位置: 首页 > 科技观察

看我在项目中如何使用设计模式,像这样学习设计模式太简单了

时间:2023-03-20 19:52:12 科技观察

大家好,今天给大家分享一个写代码的设计模式,也就是我们最熟悉的单例设计模式。很多人可能听说过这种单例设计模式,甚至偷偷写过,但是今天我将告诉大家如何使用这种单例设计模式来极大地提高代码的性能。代码性能之间的关系,恐怕很多兄弟都没有认真研究过吧!一个请求的执行流程首先我们来看一下什么叫单例模式。要理解单例模式,就得说说我们平时不用单例模式的时候是怎么创建对象的。创建对象通常很容易。比如我们创建一个对外的web接口,然后在接口收到请求的时候创建一个对象。伪代码如下:@RestController("/user")publicclassController{privateUserServiceuserService;@RequestMapping("/create")publicResponsecreate(CreateUserRequestrequest){Useruser=newUser(request);UserServiceuserService=newUserService();userService.add(用户);返回Response.success();}}上面的代码极其简单,假设你有一个Controller,对外提供http接口,然后每次通过浏览器请求发送一个createuser。即对于url/user/create的请求,发送一个CreateUserRequest请求参数,代码会使用new关键字创建一个User对象。然后通过new关键字创建一个UserService组件,然后将User对象交给UserService组件来将用户数据插入到数据库中。这段代码,懂java的人基本都能看懂。但是这里有一个问题。您知道每次处理请求时这段代码会做什么吗?其实最关键的一点就是他每次请求的时候都会在内存中创建一个User对象和一个UserService对象,那么这些对象是怎么创建的呢?java代码是如何工作的?接下来就得给大家揭秘一下这段代码运行的底层原理了。首先,当我们启动一个Java程序时,必须启动一个JVM进程。比如上面的代码,你可以通过SpringBoot等框架从main方法启动,也可以打包放到Tomcat中运行。如果直接运行main方法启动,那么会直接启动一个JVM进程。如果把代码打包运行在Tomcat中,那么Tomcat本身就是一个JVM进程。如下图所示:然后,其实你启动的JVM进程会把你写的代码加载到内存中,然后运行你写的代码。当你的代码运行起来之后,它就可以做你想让它做的事情了,比如接收浏览器发送的http请求,然后创建一些对象,将它们插入到数据库中等等。如下图所示:那么这个时候,有一个非常关键的点,就是你的代码运行的时候,用newUser()和newUserService()创建的对象抛到哪里去了?很简单,你的JVM进程有自己的内存区域可以使用,只有他才能使用。该区域称为堆内存。这好比我们在自己的房子里建一个小别墅,弄个院子,可以种花种草。别人总不能在你院子里种黄瓜、种大蒜吧?如下图所示:那么,我们上面写的代码,请注意,每收到一个请求,都会创建一个User对象和一个UserService对象,对吧?那么,随着你不断的发送请求,发送请求,我们的代码会不会一直创建对象,创建对象,然后在我们的堆内存中,对象会不会越来越多,越来越多呢?如下图:堆内存满了怎么办?那我问大家一个问题,堆内存就是一块内存空间,他能不能无限往里面放对象呢?当然不是,当你的对象越来越多,多了的时候,这个内存空间就会被填满,满了就装不下新的对象,这时候怎么办呢?它会触发一个垃圾回收动作,即JVM进程偷偷开启一个垃圾回收线程。这个线程专门盯着我们的堆内存。当它感觉快满了的时候,就会清理里面的一部分对象。这称为垃圾收集。如下图所示:但是每次垃圾回收都有一个问题。因为它需要清理一些对象,所以在清理对象的时候经常会阻止你创建新的对象。否则,就和你妈妈打扫你的房间一样。人家收拾垃圾,你却一直吃东西,往地上扔垃圾,难怪你妈不打你屁股,对不对?因此,在进行一般垃圾回收时,JVM进程会停止工作,不会创建新的对象。如下图所示:那么在垃圾回收的时候JVM进程停止运行的这段时间,会不会造成一个问题,就是没有人会去处理你的用户发来的请求。没错,这时候用户会觉得每次发送请求都卡了,一直卡着没有返回。此时,系统性能处于很差的状态。如下图所示:单例模式如何优化系统性能?那么这个时候问题就来了。回到本文正文,单例模式如何优化系统性能?其实针对以上问题,很多小伙伴可能已经发现,如果要优化系统性能,其中一个关键点就是创建尽可能少的对象,避免堆内存的频繁填充和垃圾回收的频繁发生。,也可以避免频繁的JVM进程停顿,从而避免频繁的卡顿和无响应的系统请求。那么如何创建更少的对象呢?单例模式是一个很好的方式。对于我们来说,其实UserService对象只需要创建一次即可,没必要每次请求都重复创建。让一个对象创建一次,就是单例模式。单例模式的写法有很多种,其中一种是:@RestController("/user")publicclassController{privateUserServiceuserService;@RequestMapping("/create")publicResponsecreate(CreateUserRequestrequest){Useruser=newUser(request);UserServiceuserService=UserSerivce.getInstance();userService.add(用户);返回Response.success();}}publicclassUserService{privateUserService(){}privatestaticclassSingleton{staticUserServiceuserService=newUserService();}publicstaticUserServicegetInstance(){returnSingleton.userService;}}可以看到上面的代码,我们在UserService中定义了一个私有化的static内部类Singleton,在Singleton中定义了一个静态变量UserService对象。这样的话,Singleton类只会被加载一次,只有在加载类的时候才会实例化一个静态变量UserService对象,并且每次都会通过getInstance()方法直接获取唯一的对象,不会被重复创建对象。这是单例模式的一种写法,也是企业开发中最常用的一种写法。使用单例模式后,我们可以大大减少创建对象的数量,避免频繁的堆内存填满,以及频繁的垃圾回收。频繁的JVM进程停顿会影响请求性能,这往往可以帮助我们更好的提升系统性能。