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();
    ​
        }
    }
    ​
相关推荐
悟空码字9 小时前
SpringBoot 整合 ElasticSearch,给搜索插上“光速翅膀”
java·后端·elasticsearch
博语小屋9 小时前
简单线程池实现(单例模式)
linux·开发语言·c++·单例模式
电子科技圈9 小时前
SiFive车规级RISC-V IP获IAR最新版嵌入式开发工具全面支持,加速汽车电子创新
嵌入式硬件·tcp/ip·设计模式·汽车·代码规范·risc-v·代码复审
骚戴9 小时前
DeepSeek V3 & Llama 3 推理避坑指南:自建 vLLM 集群 vs API 网关架构深度对比
java·人工智能·python·大模型·api·vllm
墨雪不会编程9 小时前
C++基础语法篇八 ——【类型转换、再探构造、友元】
java·开发语言·c++
老毛肚9 小时前
登录架构设计
java·开发语言
月明长歌9 小时前
【码道初阶】【牛客BM30】二叉搜索树与双向链表:java中以引用代指针操作的艺术与陷阱
java·数据结构·算法·leetcode·二叉树·笔试·字节跳动
小坏讲微服务9 小时前
Spring Boot4.0整合RabbitMQ死信队列详解
java·spring boot·后端·rabbitmq·java-rabbitmq
yuuki2332339 小时前
【C++】内存管理
java·c++·算法
消失的旧时光-19439 小时前
Java 线程池(第四篇):ScheduledThreadPoolExecutor 原理与定时任务执行机制全解析
java·开发语言