✅作者简介:热爱后端语言的大学生,CSDN内容合伙人
✨精品专栏:C++面向对象
🔥系列专栏:JavaSE精品总结
文章目录
前言
国庆节快乐!今天家里的风很凉爽,就好像在为国庆而欢呼!与此同时我决定把Java的设计模式总结一番,为以后能够书写清晰的项目结构打下基础。
1、设计模式概念及分类
简单来说设计模式是被广大程序员们总结并认可的编码套路,其中最常用的莫过于单例模式与工厂模式,而单例模式也有更加细的分类,一起来学习一下这些模式的用法和特点吧。
2、单例模式
- 一个类只能被实例化出来一个对象
2.1、饿汉式
- 无论如何,都会创建出来一个对象
- 思路:****在类中直接实例化一个用来返回的对象,再为外界提供一个获取该对象的方法
- 缺点:有可能造成空间浪费
代码解释:
/**
* 单例模式-饿汉式
*/publicclassClassA{//唯一的、全局的、私有的、用来返回的对象实例privatestaticClassA ca=newClassA();//方法:用来被外界调用,从而获取该类的唯一实例//static:为了使外界直接通过类名调用该方法publicstaticClassAgetClassA(){return ca;}//私有化构造:避免外界通过构造创建该类的对象privateClassA(){}}publicclassTest{publicstaticvoidmain(String[] args){ClassA ca1=ClassA.getClassA();ClassA ca2=ClassA.getClassA();System.out.println(ca1==ca2);//true}}
相当于类加载,
ca1
和
ca2
都是类对象,为同一个对象,要与类的对象有所区分。
2.2、懒汉式
- 思路:只有当需要创建唯一实例时,才会在对应方法中进行实例化- 使用synchronized来同步方法
- 缺点:同步方法效率太慢,线程效率低
代码解释:
/**
* 单例模式-懒汉式
*/publicclassClassB{//声明用来返回的对象引用privatestaticClassB cb=null;//synchronized:避免线程安全问题publicsynchronizedstaticClassBgetClassB(){if(cb==null){//非空判断,避免重复创建
cb=newClassB();}return cb;}//私有化构造privateClassB(){}}
这里利用了
synchronized
来防止重复创建实例化对象:如果事先没有创建,那就新创建,不会浪费空间。
2.2.1、懒汉式进阶版
- 思路:在保证线程安全的基础上,最大程度提高线程效率
- 使用synchronized来同步代码块
代码演示:
/**
* 单例模式-懒汉式进阶版
*/publicclassClassB2{//声明用来返回的对象引用privatestaticClassB2 cb=null;//synchronized:避免线程安全问题publicstaticClassB2getClassB2(){if(cb==null){//非空判断,避免重复创建synchronized(ClassB2.class){if(cb==null){//二次校验,如果出现了线程安全问题,最大程度保证数据安全
cb=newClassB2();}}}return cb;}//私有化构造privateClassB2(){}}
同步代码块会使程序运行效率提升,因为此时只需时间片就可以执行此线程。
2.2.2、懒汉式之懒加载
- 思路:在懒汉式的基础上,将获取自己类实例的任务交给静态内部类完成
publicclassClassC{//声明用来返回的对象引用privatestaticClassC cc=null;//静态内部类:获取ClassC的唯一实例privatestaticclassClassC2{//synchronized:避免线程安全问题publicstaticClassCget(){if(cc==null){//非空判断,避免重复创建synchronized(ClassC.class){if(cc==null){//二次校验,如果出现了线程安全问题,最大程度保证数据安全
cc=newClassC();}}}return cc;}}publicstaticClassCgetClassC(){returnClassC2.get();}//私有化构造privateClassC(){}}
这种方式效果跟懒汉式的进阶类似,只不过是将加载交给了静态内部类,效率更高。
3、工厂模式
特点:
- 常用于框架
- 自身不再直接创建对象,交给 “工厂” 完成,需要对象时直接调用工厂的指定方法获取
步骤:
- 书写实体类,用来构建对象
- 书写
.properties
配置文件,存放工厂使用反射时需要的类信息 - 书写工厂类,创建对象
- 书写测试类
用一个实例演示:
3.1、书写实体类
publicclassStudent{privateString name;privateint age;privatedouble score;//此处省略getter与setter方法publicStudent(){}publicStudent(String name,int age,double score){this.name = name;this.age = age;this.score = score;}@OverridepublicStringtoString(){return"Student{"+"name='"+ name +'\''+", age="+ age +", score="+ score +'}';}}
3.2、新建配置文件.properties
- 右键项目名创建一个后缀名为
.properties
的配置文件 - 文件内容: - 键(自定义)=值(类的全限定名)- 例如:
StudentClassName=com.bz.entity.Student
- 结构特点: 1. 键不可重复2. 等号左右无双引号3. 整条语句不要存在多余空格4. 末尾无分号5. 一行只能有一个键值对
3.3、书写工厂类并创建对象
/**
* 工厂类
*/publicclassMyFactory{//书写获取Student实例的方法//static:方便直接通过类名调用publicstaticStudentgetStudent(){Student stu=null;try(//创建字节输入流对象FileInputStream fis =newFileInputStream("Factory.properties");//添加缓冲流BufferedInputStream bis =newBufferedInputStream(fis);){//创建用来接收配置文件信息的Properties集合Properties p =newProperties();//通过load方法将配置文件读取值集合中
p.load(bis);//获取全限定名String str= p.getProperty("StudentClassName");//获取类对象Class c =Class.forName(str);//利用无参构造构建类的对象
stu=(Student) c.newInstance();}catch(FileNotFoundException e){System.out.println("文件路径不正确");}catch(IOException e){System.out.println("读取失败");}catch(Exception e){System.out.println("未知异常!");
e.printStackTrace();}return stu;}}
3.4、对工厂类测试
publicclassTestMyFactory{publicstaticvoidmain(String[] args){//利用工厂获取学生对象Student stu =MyFactory.getStudent();
stu.setName("张三");
stu.setAge(20);
stu.setScore(78);System.out.println(stu);}}
到这里有关设计模式单例模式与工厂模式就分享结束了,最后祝大家国庆节high起来,心情愉快!
版权归原作者 微凉秋意 所有, 如有侵权,请联系我们删除。