文章目录
前言
提示:详细内容可观看黑马程序员教程
基本概念:设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
黑马程序员教程对设计模式的叙述:一个问题通常有 N 种解法,其中肯定有一种解法是最优的,这个最优的解法被总结出来,称之为设计模式
本篇文章记录学习spring框架中所涉及的23种设计模式之一的单例模式笔记
提示:以下是本篇文章正文内容,下面案例仅供参考
一、单例模式的应用
既然设计模式是解决一个(类)问题的最优解,那么单例模式主要解决什么问题呢?也就是说它的应用场景是什么?
单例模式是确保一个类只能实例化一个对象,也就是说,这个对象在内存中只有一份。
接下来通过java代码来做个单例模式的DEMO
(一)Java实现单例模式
新建一个Maven项目,使用Maven项目是为了方便我们引入一些依赖,比如后续引入Spring框架的基础依赖和简化代码的依赖lombok
(二)引入lombok依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
</dependency>
(三)实体类
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
// lombok 提供的注解,帮组我们实现set、get和toString方法
@Getter
@Setter
@ToString
public class Student {
private Long sId;
private String sName;
private String sSex;
private String sClass;
}
(四)在测试类编写测试代码
在测试类中,我们 new 两个 Student 对象 studentOne 和 studentTwo ,显然是两个不同对象,使用 == 比较两个对象是否相等,结果是false
@Test
public void test()
{
Student studentOne = new Student();
studentOne.setSId(1L);
studentOne.setSName("项羽");
studentOne.setSSex("男");
studentOne.setSClass("计科17甲");
System.out.println(studentOne);
Student studentTwo = new Student();
studentTwo.setSId(2L);
studentTwo.setSName("虞姬");
studentTwo.setSSex("女");
studentTwo.setSClass("计科17甲");
System.out.println(studentTwo);
System.out.println(studentOne == studentTwo);
}
输出结果:
Student(sId=1, sName=项羽, sSex=男, sClass=计科17甲)
Student(sId=2, sName=虞姬, sSex=女, sClass=计科17甲)
false
接下来,我们将 Student类 中的构造方法(无参构造)私有化,定义一个类变量记住类的一个对象,再通过类方法来返回这个对象,这样就实现了单例模式
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
// lombok 提供的注解,帮组我们实现set、get和toString方法
@Getter
@Setter
@ToString
public class Student {
private Long sId;
private String sName;
private String sSex;
private String sClass;
//私有化构造器
private Student(){
}
// 定义一个类变量 student 来存储对象
private static final Student student = new Student();
// 定义一个静态方法,返回 student 变量
public static Student getObject(){
return student;
}
}
我们再编写一个测试类,输出结果是true。说明Student类在内存中只有一个实例对象。可以将Student类中的 @ToString 注解去掉,查看输出结果,很明显结果是相同的
@Test
public void test()
{
Student student1 = Student.getObject();
student1.setSId(1L);
student1.setSName("张三");
student1.setSSex("男");
student1.setSClass("计科17甲");
System.out.println(student1);
Student student2 = Student.getObject();
student2.setSId(2L);
student2.setSName("李四");
student2.setSSex("男");
student2.setSClass("计科17甲");
System.out.println(student2);
System.out.println(student1 == student2);
}
输出结果:
Student(sId=1, sName=张三, sSex=男, sClass=计科17甲)
Student(sId=2, sName=李四, sSex=男, sClass=计科17甲)
true
去掉注解 @ToString 输出结果:
com.personal.demo.entity.Student@38cccef
com.personal.demo.entity.Student@38cccef
true
二、Spring中的单例模式
(一)引入spring基础依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.1.5</version>
</dependency>
(二)添加spring配置文件
在resources目录下添加spring的配置文件,配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
bean标签: 配置一个Bean对象,将对象交由IOC容器管理
id: 对象在IOC容器中的唯一标识
class: 对象的全类名, 对象在IOC容器中的类型
-->
<bean id = "Student" class="com.personal.demo.entity.Student"></bean>
</beans>
(三)编写测试类
通过加载我们配置文件来获取一个 ioc 容器,在从ioc容器中根据 bean 的id 获取实例对象
@Test
public void testSpring(){
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
Student studentOne =(Student) ioc.getBean("Student");
studentOne.setSId(1L);
studentOne.setSName("张三");
studentOne.setSSex("男");
studentOne.setSClass("计科17甲");
System.out.println(studentOne);
Student studentTwo =(Student) ioc.getBean("Student");
studentTwo.setSId(2L);
studentTwo.setSName("李四");
studentTwo.setSSex("男");
studentTwo.setSClass("计科17甲");
System.out.println(studentTwo);
System.out.println(studentOne == studentTwo);
}
输出结果:
Student(sId=1, sName=张三, sSex=男, sClass=计科17甲)
Student(sId=2, sName=李四, sSex=男, sClass=计科17甲)
true
从上述结果我们发现 studentOne 和 studentTwo 是相等的,说明Spring框架中 ioc创建实例对象时,默认使用是单例模式。当然我们可以在配置文件中通过设置 scope 属性来设置为多实例的
再次输出结果就是 false
总结
写这些文章主要目的是想将知识一点点融会贯通,知其然知其所以然才是自我提升的根本(个人觉得八股文有点难背)。从基本的 java语言出发,到框架中所使用的设计模式,自己不但要如何验证框架是否使用了设计模式,还能手搓简单的设计模式,并且还需要学会一些框架配置:比如将单例设置成多例,以及为什么Spring要使用单例模式呢等等