java设计模式

1、单例模式

1.1 饿汉式

public class TestSingle {
    public static void main(String[] args) {
        Single instance1 = Single.getSingleHunger();
        Single instance2 = Single.getSingleHunger();
        System.out.println(instance2 == instance1);
        System.out.println(instance2.hashCode());
        System.out.println(instance1.hashCode());
    }
}
class Single {
    private static final Single single = new Single();
    private Single() {}
    public static Single getSingleHunger() {
        return single;
    }
}

优缺点:
线程安全
在类加载时就会被创建,没有实现懒加载,可能会浪费资源

1.2 懒汉式

public class TestSingle {
    public static void main(String[] args) {
        Single instance1 = Single.getSingle();
        Single instance2 = Single.getSingle();
        System.out.println(instance2 == instance1);
        System.out.println(instance2.hashCode());
        System.out.println(instance1.hashCode());
    }
}
class Single {
    private static Single single;
    private Single() {}
    public static Single getSingle() {
        if (single == null) {
            single = new Single();
        }
        return single;
    }
}

优缺点:
起到了懒加载效果,但是只能在单线程模式下使用,所有要使用加锁的方式,并使用双重验证提高效率

1.3 双重验证

public class TestSingle {
    public static void main(String[] args) {
        Single instance1 = Single.getSingle();
        Single instance2 = Single.getSingle();
        System.out.println(instance2 == instance1);
        System.out.println(instance2.hashCode());
        System.out.println(instance1.hashCode());
    }
}

class Single {
    private static Single single;
    private Single() {}
    public static Single getSingle() {
        if (single == null) {
            synchronized (Single.class) {
                if (single == null) {
                    single = new Single();
                }
            }
        }
        return single;
    }
}

优缺点:

  1. 实例化代码只执行一次后续再次访问,直接return实例对象
  2. 线程安全,延迟加载,效率较高

1.4 静态内部类

// 测试函数
public class TestSingle {
    public static void main(String[] args) {
        Single instance1 = Single.getInstance();
        Single instance2 = Single.getInstance();
        System.out.println(instance2 == instance1);
        System.out.println(instance2.hashCode());
        System.out.println(instance1.hashCode());
    }
}
// 单例模式
class Single {
    // 私有化构造函数
    private Single(){}
	// 静态内部类,当Single类被调用时,静态内部类不会被装载,
	// 只有当调用getInstance函数的时候,静态内部类才会被装载,且只会被装载一次(懒加载)
	// 而且当类装载的时候是线程安全的,所以该方法是线程安全的,
    private static class SingleInstance {
        private static Single INSTANCE = new Single();
    }
	// 提供一个静态的公有方法
    public static Single getInstance() {
        return SingleInstance.INSTANCE;
    }
}

优缺点:

  1. 采用了类装载机制,保证初始化实例时只有一个线程
  2. 静态内部类在类装载时并不会立即实例化,而是在需要实例化时,通过调用getInstance方法,才会装载SingleInstance 静态类,从而完成Single 的实例化;
  3. 类的静态属性只有在第一次加载类的时候初始化,所以是线程安全的

1.5 枚举

public class TestSingle {
    public static void main(String[] args) {
        Single instance1 = Single.INSTANCE;
        Single instance2 = Single.INSTANCE;
        System.out.println(instance2 == instance1);
        System.out.println(instance2.hashCode());
        System.out.println(instance1.hashCode());
    }
}
enum Single {
    INSTANCE;
    public void sayOK() {
        System.out.println("ok");
    }
}

优缺点:
借助枚举实现单例模式,不仅可以避线程不安全,还能避免通过反序列化重新创建新的对象

单例模式总结

  • 单例模式保证了系统中只存在一个对象,节省了系统资源,对于一些需要频繁创建和销毁的对象,使用单例模式可以提高系统性能
  • 当实例化一个单例类的时候,要是用相应的获取对象的方法,而不是使用new
  • 单例模式使用场景: 需要频繁的进行创建和销毁的对象、创建对象时耗时过多或者耗费资源过多(重量级对象),但是又经常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源、session工厂等)

2、工厂模式

2.1 简单工厂模式

定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

步骤1:创建一个接口

public interface Shape {
    void draw();
}

步骤2:创建实现接口的实体类

CircleImpl实现类

public class CircleImpl implements Shape {
    @Override
    public void draw() {
        System.out.println("这是一个圆形");
    }
}

RectangleImpl 实现类

public class RectangleImpl implements Shape {
    @Override
    public void draw() {
        System.out.println("这是一个矩形");
    }
}

SquareImpl 实现类

public class SquareImpl implements Shape {
    @Override
    public void draw() {
        System.out.println("这是一个正方形");
    }
}

步骤三:创建一个工厂,生成基于给定信息的实体类对象

public class ShapeFactory {
	//使用 getShape 方法获取形状类型的对象
    public Shape getShape(String factoryType) {
        if(factoryType == null) {
            return null;
        }
        if (factoryType.equals("圆形")) {
            return new CircleImpl();
        } else if (factoryType.equals("矩形")) {
            return new RectangleImpl();
        } else if (factoryType.equals("正方形")) {
            return new SquareImpl();
        }
        return null;
    }
}

步骤4:使用该工厂,通过传递类型信息来获取实体类的对象

public class TestFactory {
    public static void main(String[] args) {
        ShapeFactory shapeFactory = new ShapeFactory();

        Shape shape1 = shapeFactory.getShape("圆形");
        shape1.draw();

        Shape shape2 = shapeFactory.getShape("矩形");
        shape2.draw();

        Shape shape3 = shapeFactory.getShape("正方形");
        shape3.draw();

        Shape shape4 = shapeFactory.getShape("椭圆形");
        shape4.draw();
    }
}

输出结果

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值