java基础之设计模式(单例模式,工厂模式)

发布时间:2024年01月17日

设计模式

是一种编码套路

单例模式

一个类只能创建一个实例

饿汉式

直接创建唯一实例

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:true
 ? ? ? ? ? ?synchronized (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:true
 ? ? ? ? ? ?synchronized (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;
     ?  }
    ?
     ? ?@Override
     ? ?public String toString() {
     ? ? ? ?return "Student{" +
     ? ? ? ? ? ? ? ?"name='" + name + '\'' +
     ? ? ? ? ? ? ? ?", age=" + age +
     ? ? ? ? ? ? ? ?", score=" + score +
     ? ? ? ? ? ? ? ?'}';
     ?  }
    ?
     ? ?public Student() {
     ?  }
    ?
     ? ?public Student(String name, int age, double score) {//string,int,double
     ? ? ? ?this.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();
    ?
     ?  }
    }
    ?

文章来源:https://blog.csdn.net/zhzjn/article/details/135653905
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。