【设计模式的开始,设计原则+单例】

前言

每周一更,这周开始和大家一起学习设计模式。

谈谈设计原则

设计原则是很重要的一个东西,大厦之于地基,它是我们编码要牢记在心的一个东西。

  • 单一职责原则
    单一职责指的是一个接口只干一件事情嘛?显然这样理解就太片面了,职责单一应该说的是只对一种事情负责。那改变我们的接口的原因只有一个,当负责的那件事情发生改变我们接口也相对应的改变,即一个接口支撑一个业务,当该业务改变,接口随着改变。
  • 开闭原则
    当我们去做功能增强或者优化的时候我们得想到这个原则了,对拓展开放,对修改关闭。当我们去增强时,尽量不去修改别人的代码,而是用继承等方式增加类或者增加方法的方式进行增强。
  • 接口隔离职责
    接口隔离我的理解是根据业务场景最小粒度的去拆分接口,
  • 里式替换原则
    里氏替换指的是子类能完全的替换父类,替换后对应的功能没有发生改变。这样是为了在继承父类时,避免子类重写父类,导致方法调用的混乱。所以设计父类尽量没有具体实现。
  • 依赖倒置原则
    依赖倒置是指我们在方法的入参处,我们需要依赖抽象类而不是具体类。越抽象越稳定,我们需要依赖稳定,同时也方便后续的拓展。
  • 迪米特原则
    迪米特也叫最少知识原则,即用户调用接口时需要知道的知识越少越好。倘若一个接口调用需要读一本说明书,那这个接口肯定是不符合这个原则的。可以将一些参数、常量封装在类内部、使用构造器等方式,在创建对象的时候就拥有了这些知识。也解释为只与直接朋友通信。类的属性、方法的参数与返回值称作类的直接关联对象,而类中的方法则成非直接关联对象,所以当出现依赖非直接关联对象我们就得考虑将方法拆分。
  • 合成复用原则
    合成复用是指尽量使用合成、聚合的方式依赖,而不使用继承。继承的耦合性高于合成/聚合的方式,当我们用不到父类的一些方法时,也继承到了子类。其二java中只能单继承,所以尽量不使用继承。

单例模式

单例模式一般都是大家学的第一个设计模式。当我们系统中某个东西只能有一个的时候(比如建立目录 数据库连接都需要这样的单线程操作),或者是和实例无关使用单例来节约资源(例如springBoot中bean的创建)
java中有很多种方式会破坏单例,于是就有为了解决各种破坏单例写法。饿汉式、懒汉式、双重检查、静态内部类、枚举。

如果该对象一定会使用到,那使用饿汉式一点问题没有。

  • 构造私有化
  • 创建私有静态对象
  • 提供获取对象方法
    private static Singleton INSETANCE = new Singleton();
    private Singleton() {
    }
    public static Singleton getInstance() {
        return INSETANCE;
    }

创建两个对象进行对比结构返回ture,表明是同一个对象

当单例实现后就会有人想,要是没用到这个对象,岂不是就会浪费资源。是的,于是有了懒汉式,当调用的时候才创建,即在上面getInstance中不直接return了,判断Singleton是否为空,为空则创建,否则就返回Singleton对象。此刻又有高手提出疑问,当多线程时那这单例就彻底失效了,会有多个对象创建出来。答曰:加锁嘛,synchronized 一套就好了。于是就有了双重检查方式创建单例。

  • 双重检查
public class Singleton {
    private static volatile Singleton instance = null;
    private Singleton() {
    }

    public static Singleton getInstance() {
        if(instance == null){
            synchronized (Singleton.class){
                if (instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

【注意】记得保证instance的原子性,需要使用volatile 修饰

静态内部类也能实现单例模式

public class Singleton {
    private Singleton() {
    }

    private static class SingletonInstance{
        private static Singleton singleton = new Singleton();
    }

    public static Singleton getInstance(){
        return SingletonInstance.singleton;
    }
}

其实核心还是构造私有禁止直接创建对象,线程同步和避免资源的浪费都由这个内部类来帮我们完成。静态内部类只有当使用的时候才加载,这时候才会创建Singleton,虚拟机类加载时是同步操作,所以这是个比较完美的单例。
【注】虚拟机类加载等在后续JVM章节

接下来该到我们jdk1.5的神器-枚举出场了,实现单例的最优解

public enum  Singleton {
    INSTANCE;
}

是的,就这样实现了单例,同时它还避免了反序列化和反射重新创建对象

    public static void main(String[] args) {
        Singleton singleton1 = Singleton.INSTANCE;
        Singleton singleton2 = Singleton.INSTANCE;
        System.out.println(singleton1 == singleton2);
    }

在这里插入图片描述

后续

后续应该是每周一个设计模式的方式进行更新,所以有同样想学设计模式的同学可以跟着我一起。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值