【Java】设计模式之单例模式与工厂模式

简介: 【Java】设计模式之单例模式与工厂模式

1、设计模式概念及分类

简单来说设计模式是被广大程序员们总结并认可的编码套路,其中最常用的莫过于单例模式与工厂模式,而单例模式也有更加细的分类,一起来学习一下这些模式的用法和特点吧。


2、单例模式

一个类只能被实例化出来一个对象

2.1、饿汉式

无论如何,都会创建出来一个对象

思路:

在类中直接实例化一个用来返回的对象,再为外界提供一个获取该对象的方法

缺点:有可能造成空间浪费

代码解释:


/**
 * 单例模式-饿汉式
 */
public class ClassA {
    //唯一的、全局的、私有的、用来返回的对象实例
   private static ClassA ca=new ClassA();
    //方法:用来被外界调用,从而获取该类的唯一实例
    //static:为了使外界直接通过类名调用该方法
    public static ClassA getClassA(){
        return ca;
    }
   //私有化构造:避免外界通过构造创建该类的对象
   private ClassA(){}
}
public class Test {
    public static void main(String[] args) {
        ClassA ca1=ClassA.getClassA();
        ClassA ca2=ClassA.getClassA();
        System.out.println(ca1==ca2);//true
    }
}

相当于类加载,ca1和ca2都是类对象,为同一个对象,要与类的对象有所区分。


2.2、懒汉式

思路:只有当需要创建唯一实例时,才会在对应方法中进行实例化

使用synchronized来同步方法

缺点:同步方法效率太慢,线程效率低

代码解释:


/**
 * 单例模式-懒汉式
 */
public class ClassB {
    //声明用来返回的对象引用
    private static ClassB cb=null;
    //synchronized:避免线程安全问题
    public synchronized static ClassB getClassB(){
        if (cb==null){//非空判断,避免重复创建
            cb=new ClassB();
        }
        return cb;
    }
    //私有化构造
    private ClassB(){}
}

这里利用了synchronized来防止重复创建实例化对象:如果事先没有创建,那就新创建,不会浪费空间。


2.2.1、懒汉式进阶版

思路:在保证线程安全的基础上,最大程度提高线程效率

使用synchronized来同步代码块

代码演示:

/**
 * 单例模式-懒汉式进阶版
 */
public class ClassB2 {
    //声明用来返回的对象引用
    private static ClassB2 cb=null;
    //synchronized:避免线程安全问题
    public static ClassB2 getClassB2(){
        if (cb==null){//非空判断,避免重复创建
            synchronized (ClassB2.class){
                if (cb==null){//二次校验,如果出现了线程安全问题,最大程度保证数据安全
                    cb=new ClassB2();
                }
            }
        }
        return cb;
    }
    //私有化构造
    private ClassB2(){}
}

同步代码块会使程序运行效率提升,因为此时只需时间片就可以执行此线程。


2.2.2、懒汉式之懒加载

思路:在懒汉式的基础上,将获取自己类实例的任务交给静态内部类完成

public class ClassC {
    //声明用来返回的对象引用
    private static ClassC cc=null;
    //静态内部类:获取ClassC的唯一实例
    private static class ClassC2{
        //synchronized:避免线程安全问题
        public static ClassC get(){
            if (cc==null){//非空判断,避免重复创建
                synchronized (ClassC.class){
                    if (cc==null){//二次校验,如果出现了线程安全问题,最大程度保证数据安全
                        cc=new ClassC();
                    }
                }
            }
            return cc;
        }
    }
    public static ClassC getClassC(){
        return  ClassC2.get();
    }
    //私有化构造
    private ClassC(){}
}

这种方式效果跟懒汉式的进阶类似,只不过是将加载交给了静态内部类,效率更高。


3、工厂模式

特点:


常用于框架

自身不再直接创建对象,交给 “工厂” 完成,需要对象时直接调用工厂的指定方法获取

步骤:


书写实体类,用来构建对象

书写.properties配置文件,存放工厂使用反射时需要的类信息

书写工厂类,创建对象

书写测试类

用一个实例演示:


3.1、书写实体类

public class Student {
    private String name;
    private int age;
    private double score;
    //此处省略getter与setter方法
    public Student() {
    }
    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}

3.2、新建配置文件.properties

右键项目名创建一个后缀名为.properties的配置文件

文件内容:

键(自定义)=值(类的全限定名)

例如:StudentClassName=com.bz.entity.Student

结构特点:

键不可重复

等号左右无双引号

整条语句不要存在多余空格

末尾无分号

一行只能有一个键值对

3.3、书写工厂类并创建对象

/**
 * 工厂类
 */
public class MyFactory {
    //书写获取Student实例的方法
    //static:方便直接通过类名调用
    public static Student getStudent(){
        Student stu=null;
        try (
                //创建字节输入流对象
                FileInputStream fis = new FileInputStream("Factory.properties");
                //添加缓冲流
                BufferedInputStream bis = new BufferedInputStream(fis);
        ) {
            //创建用来接收配置文件信息的Properties集合
            Properties p = new Properties();
            //通过load方法将配置文件读取值集合中
            p.load(bis);
            //获取全限定名
            String str= p.getProperty("StudentClassName");
            //获取类对象
            Class c = Class.forName(str);
            //利用无参构造构建类的对象
            stu=(Student) c.newInstance();
        }catch (FileNotFoundException e){
            System.out.println("文件路径不正确");
        }catch (IOException e){
            System.out.println("读取失败");
        }catch (Exception e){
            System.out.println("未知异常!");
            e.printStackTrace();
        }
        return stu;
    }
}

3.4、对工厂类测试

public class TestMyFactory {
    public static void main(String[] args) {
        //利用工厂获取学生对象
        Student stu = MyFactory.getStudent();
        stu.setName("张三");
        stu.setAge(20);
        stu.setScore(78);
        System.out.println(stu);
    }
}

到这里有关设计模式单例模式与工厂模式就分享结束了,最后祝大家国庆节high起来,心情愉快!


目录
相关文章
|
5月前
|
设计模式 网络协议 数据可视化
Java 设计模式之状态模式:让对象的行为随状态优雅变化
状态模式通过封装对象的状态,使行为随状态变化而改变。以订单为例,将待支付、已支付等状态独立成类,消除冗长条件判断,提升代码可维护性与扩展性,适用于状态多、转换复杂的场景。
786 157
|
5月前
|
设计模式 Java Spring
Java 设计模式之责任链模式:优雅处理请求的艺术
责任链模式通过构建处理者链,使请求沿链传递直至被处理,实现发送者与接收者的解耦。适用于审批流程、日志处理等多级处理场景,提升系统灵活性与可扩展性。
639 2
|
7月前
|
设计模式 缓存 Java
Java设计模式(二):观察者模式与装饰器模式
本文深入讲解观察者模式与装饰器模式的核心概念及实现方式,涵盖从基础理论到实战应用的全面内容。观察者模式实现对象间松耦合通信,适用于事件通知机制;装饰器模式通过组合方式动态扩展对象功能,避免子类爆炸。文章通过Java示例展示两者在GUI、IO流、Web中间件等场景的应用,并提供常见陷阱与面试高频问题解析,助你写出灵活、可维护的代码。
|
5月前
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
1217 35
|
10月前
|
设计模式 缓存 安全
【设计模式】【创建型模式】单例模式(Singleton)
一、入门 什么是单例模式? 单例模式是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点。它常用于需要全局唯一对象的场景,如配置管理、连接池等。 为什么要单例模式? 节省资源 场景:某些对象创
376 15
|
5月前
|
设计模式 消息中间件 传感器
Java 设计模式之观察者模式:构建松耦合的事件响应系统
观察者模式是Java中常用的行为型设计模式,用于构建松耦合的事件响应系统。当一个对象状态改变时,所有依赖它的观察者将自动收到通知并更新。该模式通过抽象耦合实现发布-订阅机制,广泛应用于GUI事件处理、消息通知、数据监控等场景,具有良好的可扩展性和维护性。
475 8
|
10月前
|
设计模式 缓存 安全
【高薪程序员必看】万字长文拆解Java并发编程!(8):设计模式-享元模式设计指南
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的经典对象复用设计模式-享元模式,废话不多说让我们直接开始。
218 0
|
7月前
|
设计模式 安全 Java
Java设计模式(一):单例模式与工厂模式
本文详解单例模式与工厂模式的核心实现及应用,涵盖饿汉式、懒汉式、双重检查锁、工厂方法、抽象工厂等设计模式,并结合数据库连接池与支付系统实战案例,助你掌握设计模式精髓,提升代码专业性与可维护性。
|
7月前
|
设计模式 XML 安全
Java枚举(Enum)与设计模式应用
Java枚举不仅是类型安全的常量,还具备面向对象能力,可添加属性与方法,实现接口。通过枚举能优雅实现单例、策略、状态等设计模式,具备线程安全、序列化安全等特性,是编写高效、安全代码的利器。
|
设计模式 Java 数据安全/隐私保护
Java 设计模式:装饰者模式(Decorator Pattern)
装饰者模式属于结构型设计模式,允许通过动态包装对象的方式为对象添加新功能,提供比继承更灵活的扩展方式。该模式通过组合替代继承,遵循开闭原则(对扩展开放,对修改关闭)。

热门文章

最新文章