设计模式
-
是程序员们在开发中总结的编码套路
单例模式
-
一个类只能创建出一个实例对象
饿汉式
-
思路:直接将唯一的实例对象创建出来
package com.bz.entity; /** * 单例模式-饿汉式 */ public class ClassA { //唯一实例 //static:1. 保证getClassA可以返回 2. 保证只会创建一次 //private:为了防止外界直接访问 private static ClassA ca = new ClassA(); //static:保证外界可以直接通过类名调用 public static ClassA getClassA(){ return ca; } //构造私有化:防止外界自由调用构造创建对象 private ClassA(){ } }
缺点:有可能浪费空间
懒汉式
-
思路:只有在需要获取对象时,才会创建实例
/** * 单例模式-懒汉式基础版 */ public class ClassB { //唯一实例 //static:1. 保证getClassA可以返回 2. 保证只会创建一次 //private:为了防止外界直接访问 private static ClassB cb =null; //static:保证外界可以直接通过类名调用 //同步方法:预防线程安全问题 public static synchronized ClassB getClassB(){ //调用该方法,意味着需要实例化对象 if (cb == null) {//当第一次获取时 cb = new ClassB(); } return cb; } //构造私有化:防止外界自由调用构造创建对象 private ClassB(){ } }
缺点:线程效率低
懒汉式-进阶版
-
思路:在懒汉式的基础上,利用同步代码块+二次校验尽可能提高线程效率
/** * 单例模式-懒汉式进阶版 */ public class ClassB { //唯一实例 //static:1. 保证getClassA可以返回 2. 保证只会创建一次 //private:为了防止外界直接访问 private static ClassB cb =null; //static:保证外界可以直接通过类名调用 public static ClassB getClassB(){ if (cb==null) {//判断线程是否需要加锁执行 synchronized (ClassB.class) {//临界资源:当前的类对象 //调用该方法,意味着需要实例化对象 //二次校验:在实例化之前确定引用为空 if (cb == null) {//当第一次获取时 cb = new ClassB(); } } } return cb; } //构造私有化:防止外界自由调用构造创建对象 private ClassB(){ } }
工厂模式
-
对象的创建和销毁全部交由工厂完成,也是底层技术,通常用于底层框架
案例:利用工厂模式获取对象实例(Properties集合+配置文件、反射)
步骤
-
书写实体类
package com.bz.entity; public class Student { private String name; private int age; private double score; //省略getter、setter、构造 }
-
创建配置文件
-
在项目下新建后缀名为.properties的文件
-
书写内容
-
格式:自定义键=全限定名
-
等号左右不加双引号
-
语句末尾不加分号
-
一行只能书写一个键值对
-
不允许添加无关符号,比如空格
-
StudentClassName=com.bz.entity.Student
-
-
书写工厂类
package com.bz.util; import com.bz.entity.Student; import java.io.FileInputStream; import java.util.Properties; /** * 自定义工厂类 */ public class MyFactory { //获取Student的实例对象 public static Student getStudent(){ Student stu =null;//用来返回 try ( //创建一个字节输入流 FileInputStream fis=new FileInputStream("ClassNames.properties") ) { //将配置文件中的内容读取到集合中 Properties p = new Properties(); p.load(fis); //获取全限定名 String className=p.getProperty("StudentClassName"); //获取类对象 Class c = Class.forName(className); //利用反射构建对象 stu = (Student) c.newInstance(); } catch (Exception e) { System.out.println("执行异常!"); e.printStackTrace(); } return stu; } }
-
书写测试类
package com.bz.test; import com.bz.entity.Student; import com.bz.util.MyFactory; public class TestMyFactory { public static void main(String[] args) { //利用工厂类获取一个学生对象实例 Student stu1 = MyFactory.getStudent(); Student stu2 = MyFactory.getStudent(); System.out.println(stu1); System.out.println(stu2); } }