设计模式

是一种编码套路

单例模式

一个类只能创建一个实例

饿汉式

直接创建唯一实例

package com.by.entity;​/** * 单例模式-饿汉式 */public class ClassA {//static: 1. newClassA可以访问返回 2. 静态属性内存中只会存在一个//private: 防止外界直接访问属性private static ClassA ca = new ClassA();​//外界获取唯一实例的渠道//static:使外界直接通过类名访问public static ClassA newClassA(){return ca; }​//构造私有化-防止外界调用构造创建对象private ClassA(){​ }}

缺点: 有可能浪费空间

懒汉式

在获取实例是创建唯一对象

package com.by.entity;​/** * 单例模式-懒汉式 */public class ClassB {//static: 1. newClassA可以访问返回 2. 静态属性内存中只会存在一个//private: 防止外界直接访问属性private static ClassB cb = null;​//外界获取唯一实例的渠道//static:使外界直接通过类名访问//synchronized: 同步方法预防线程安全问题public static synchronized ClassB newClassB(){if (cb == null) {//当第一次获取时再进行实例化 cb = new ClassB(); }return cb; }​//构造私有化-防止外界调用构造创建对象private ClassB(){​ }​}

缺点: 线程效率慢

懒汉式-进阶版

在懒汉式的基础上,利用同步代码块结合二次校验提高执行效率

package com.by.entity;​/** * 单例模式-懒汉式进阶版 */public class ClassC {//static: 1. newClassA可以访问返回 2. 静态属性内存中只会存在一个//private: 防止外界直接访问属性private static ClassC cc = null;​//外界获取唯一实例的渠道//static:使外界直接通过类名访问public static ClassC newClassC(){if (cc == null) {//二次校验: 决定是否需要开启互斥锁 t1:truet2:truesynchronized (ClassC.class) {//临界资源对象: 当前类的类对象//对属性进行实例化if (cc == null) {//当第一次获取时再进行实例化cc = new ClassC(); } } }return cc; }​//构造私有化-防止外界调用构造创建对象private ClassC(){​ }​}package com.by.entity;​/** * 单例模式-懒汉式进阶版 */public class ClassC {//static: 1. newClassA可以访问返回 2. 静态属性内存中只会存在一个//private: 防止外界直接访问属性private static ClassC cc = null;​//外界获取唯一实例的渠道//static:使外界直接通过类名访问public static ClassC newClassC(){if (cc == null) {//二次校验: 决定是否需要开启互斥锁 t1:truet2:truesynchronized (ClassC.class) {//临界资源对象: 当前类的类对象//对属性进行实例化if (cc == null) {//当第一次获取时再进行实例化cc = new ClassC(); } } }return cc; }​//构造私有化-防止外界调用构造创建对象private ClassC(){​ }​}

工厂模式

  • 是一种底层技术,通常用于底层框架的编写

  • 思路: 将数据的创建和维护交由工厂完成

案例
  • 需求: 构建一个工厂类,获取学生对象

  1. 提供学生类

    package com.by.entity;​public class Student {private String name;private int age;private double score;​public String getName() {return name; }​public void setName(String name) {this.name = name; }​public int getAge() {return age; }​public void setAge(int age) {this.age = age; }​public double getScore() {return score; }​public void setScore(double score) {this.score = score; }​@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}'; }​public Student() { }​public Student(String name, int age, double score) {//string,int,doublethis.name = name;this.age = age;this.score = score; }}
  2. 书写配置文件

    • 在项目下创建后缀名为.properties的配置文件

    • 作用: 存放被管理类的全限定名

    • 键=值的形式存放数据

    • 键值不可添加双引号、末尾不可添加分号、中间不可存在多个符号(如空格)

    • 一行只能有一个键值对

    StudentClassName=com.by.entity.Student
  3. 书写工厂类

    package com.by.util;​import com.by.entity.Student;​import java.io.FileInputStream;import java.util.Properties;​public class MyFactory {/** * 获取学生对象 */public static Student getStudent(){Student student = null;try (//创建输入流FileInputStream fis=new FileInputStream("factory.properties") ) {//将配置文件的内容加载到集合中Properties p = new Properties();p.load(fis);//获取全限定名String className = p.getProperty("StudentClassName");//获取类对象Class c = Class.forName(className);//利用反射构建学生实例student = (Student) c.newInstance(); } catch (Exception e) {System.out.println("未知异常!");e.printStackTrace(); }return student;​ }}​
  4. 测试

    package com.by.test;​import com.by.entity.Student;import com.by.util.MyFactory;​public class Test5 {public static void main(String[] args) {//利用工厂获取学生实例对象Student s1 = MyFactory.getStudent();Student s2 = MyFactory.getStudent();​ }}​