设计模式
是一种编码套路
单例模式
一个类只能创建一个实例
饿汉式
直接创建唯一实例
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:true t2: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:true t2:truesynchronized (ClassC.class) {//临界资源对象: 当前类的类对象//对属性进行实例化if (cc == null) {//当第一次获取时再进行实例化cc = new ClassC();}}}return cc;}
//构造私有化-防止外界调用构造创建对象private ClassC(){
}
}
工厂模式
-
是一种底层技术,通常用于底层框架的编写
-
思路: 将数据的创建和维护交由工厂完成
案例
-
需求: 构建一个工厂类,获取学生对象
-
提供学生类
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;} }
-
书写配置文件
-
在项目下创建后缀名为
.properties
的配置文件 -
作用: 存放被管理类的全限定名
-
以
键=值
的形式存放数据 -
键值不可添加双引号、末尾不可添加分号、中间不可存在多个符号(如空格)
-
一行只能有一个键值对
StudentClassName=com.by.entity.Student
-
-
书写工厂类
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; } }
-
测试
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(); } }