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

设计模式

是一种编码套路

单例模式

一个类只能创建一个实例

饿汉式

直接创建唯一实例

复制代码
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();
    ​
        }
    }
    ​
相关推荐
3***68842 分钟前
Spring Boot中使用Server-Sent Events (SSE) 实现实时数据推送教程
java·spring boot·后端
C***u1765 分钟前
Spring Boot问题总结
java·spring boot·后端
会员果汁13 分钟前
15.设计模式-组合模式
设计模式·组合模式
Elieal20 分钟前
5 种方式快速创建 SpringBoot 项目
java·spring boot·后端
better_liang28 分钟前
每日Java面试场景题知识点之-Java修饰符
java·访问控制·static·abstract·final·修饰符·企业级开发
rgeshfgreh43 分钟前
Spring事务传播机制深度解析
java·前端·数据库
无名-CODING44 分钟前
Java Spring 事务管理深度指南
java·数据库·spring
xiaolyuh12344 分钟前
Spring MVC Bean 参数校验 @Validated
java·spring·mvc
蕨蕨学AI1 小时前
【Wolfram语言】45.2 真实数据集
java·数据库
予枫的编程笔记1 小时前
【Java集合】深入浅出 Java HashMap:从链表到红黑树的“进化”之路
java·开发语言·数据结构·人工智能·链表·哈希算法