Java设计模式之单例模式和工厂模式

设计模式

  • 是程序员们在开发中总结的编码套路

单例模式

  • 一个类只能创建出一个实例对象

饿汉式

  • 思路:直接将唯一的实例对象创建出来

package com.bz.entity;
​
/**
 * 单例模式-饿汉式
 */
public class ClassA {
    //唯一实例
    //static:1. 保证getClassA可以返回  2. 保证只会创建一次
    //private:为了防止外界直接访问
    private static ClassA ca = new ClassA();
​
    //static:保证外界可以直接通过类名调用
    public static ClassA getClassA(){
        return ca;
    }
​
    //构造私有化:防止外界自由调用构造创建对象
    private ClassA(){
​
    }
}

缺点:有可能浪费空间

懒汉式

  • 思路:只有在需要获取对象时,才会创建实例

​
/**
 * 单例模式-懒汉式基础版
 */
public class ClassB {
    //唯一实例
    //static:1. 保证getClassA可以返回  2. 保证只会创建一次
    //private:为了防止外界直接访问
    private static ClassB cb =null;
​
    //static:保证外界可以直接通过类名调用
    //同步方法:预防线程安全问题
    public static synchronized ClassB getClassB(){
        //调用该方法,意味着需要实例化对象
        if (cb == null) {//当第一次获取时
            cb = new ClassB();
        }
        return cb;
    }
​
​
    //构造私有化:防止外界自由调用构造创建对象
    private ClassB(){
    }
}

缺点:线程效率低

懒汉式-进阶版

  • 思路:在懒汉式的基础上,利用同步代码块+二次校验尽可能提高线程效率

​
/**
 * 单例模式-懒汉式进阶版
 */
public class ClassB {
    //唯一实例
    //static:1. 保证getClassA可以返回  2. 保证只会创建一次
    //private:为了防止外界直接访问
    private static ClassB cb =null;
​
    //static:保证外界可以直接通过类名调用
    public static ClassB getClassB(){
        if (cb==null) {//判断线程是否需要加锁执行
            synchronized (ClassB.class) {//临界资源:当前的类对象
                //调用该方法,意味着需要实例化对象
                //二次校验:在实例化之前确定引用为空
                if (cb == null) {//当第一次获取时
                    cb = new ClassB();
                }
            }
        }
        return cb;
    }
​
​
    //构造私有化:防止外界自由调用构造创建对象
    private ClassB(){
    }
}

工厂模式

  • 对象的创建和销毁全部交由工厂完成,也是底层技术,通常用于底层框架

案例:利用工厂模式获取对象实例(Properties集合+配置文件、反射)

步骤

  1. 书写实体类

    package com.bz.entity;
    ​
    public class Student {
        private String name;
        private int age;
        private double score;
    ​
        //省略getter、setter、构造
    }
  2. 创建配置文件

    • 在项目下新建后缀名为.properties的文件

    • 书写内容

      1. 格式:自定义键=全限定名

      2. 等号左右不加双引号

      3. 语句末尾不加分号

      4. 一行只能书写一个键值对

      5. 不允许添加无关符号,比如空格

    StudentClassName=com.bz.entity.Student
  3. 书写工厂类

    package com.bz.util;
    ​
    import com.bz.entity.Student;
    ​
    import java.io.FileInputStream;
    import java.util.Properties;
    ​
    /**
     * 自定义工厂类
     */
    public class MyFactory {
    ​
        //获取Student的实例对象
        public static Student getStudent(){
            Student stu =null;//用来返回
            try (
                    //创建一个字节输入流
                    FileInputStream fis=new FileInputStream("ClassNames.properties")
                    ) {
                //将配置文件中的内容读取到集合中
                Properties p = new Properties();
                p.load(fis);
                //获取全限定名
                String className=p.getProperty("StudentClassName");
                //获取类对象
                Class c = Class.forName(className);
                //利用反射构建对象
                stu = (Student) c.newInstance();
                
            } catch (Exception e) {
                System.out.println("执行异常!");
                e.printStackTrace();
            }
            
            return stu;
        }
    ​
    }
  4. 书写测试类

    package com.bz.test;
    ​
    import com.bz.entity.Student;
    import com.bz.util.MyFactory;
    ​
    public class TestMyFactory {
        public static void main(String[] args) {
            //利用工厂类获取一个学生对象实例
            Student stu1 = MyFactory.getStudent();
            Student stu2 = MyFactory.getStudent();
            System.out.println(stu1);
            System.out.println(stu2);
        }
    }

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值