湖北分行建设银行网站,wordpress.html插件,中国域名有哪些,唐朝网站设计模式#xff0c;面试级别的详解(持续更新中)
软件的设计原则
常⽤的⾯向对象设计原则包括7个#xff0c;这些原则并不是孤⽴存在的#xff0c;它们相互依赖#xff0c;相互补充。
开闭原则#xff08;Open Closed Principle#xff0c;OCP#xff09;单⼀职责原则…设计模式面试级别的详解(持续更新中)
软件的设计原则
常⽤的⾯向对象设计原则包括7个这些原则并不是孤⽴存在的它们相互依赖相互补充。
开闭原则Open Closed PrincipleOCP单⼀职责原则Single Responsibility Principle, SRP⾥⽒替换原则Liskov Substitution PrincipleLSP依赖倒置原则Dependency Inversion PrincipleDIP接⼝隔离原则Interface Segregation PrincipleISP合成/聚合复⽤原则Composite/Aggregate Reuse Principle C/ARP最少知识原则Least Knowledge PrincipleLKP或者迪⽶特法则 Law of DemeterLOD
设计模式的分类
创建型 在创建对象的同时隐藏创建逻辑不使用 new 直接实例化对象程序在判断需要创建哪些对象时更灵活。包括工厂/抽象工厂/单例/建造者/原型模式。结构型 通过类和接口间的继承和引用实现创建复杂结构的对象。包括适配器/桥接模式/过滤器/组合/装饰器/外观/享元/代理模式。行为型 通过类之间不同通信方式实现不同行为。包括责任链/命名/解释器/迭代器/中介者/备忘录/观察者/状态/策略/模板/访问者模式。 单例模式
单例模式Singleton Pattern是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类该类负责创建自己的对象同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式可以直接访问不需要实例化该类的对象。
单例模式是一种创建型设计模式它确保一个类只有一个实例并提供了一个全局访问点来访问该实例。
构造方法必须是私有的、由自己创建一个静态变量存储实例对外提供一个静态公有方法获取实例
优点 内存中只有一个实例减少了开销尤其是频繁创建和销毁实例的情况下并且可以避免对资源的多重占用 缺点 没有抽象层难以扩展与单一职责原则冲突。
单例模式的常见写法
饿汉式线程安全
饿汉式单例模式顾名思义类一加载就创建对象这种方式比较常用但容易产生垃圾对象浪费内存空间。
/*** 单例模式。饿汉式* 比较常用但是容易产生垃圾对象* 优点不用加锁执行效率会很高* 缺点类加载时就初始化浪费内存*/
public class SingletonEHan {private static SingletonEHan instance new SingletonEHan();private SingletonEHan(){}public static SingletonEHan getInstance(){return instance;}
}优点线程安全没有加锁执行效率较高缺点不是懒加载类加载时就初始化浪费内存空间 懒加载 lazy loading使用的时候再创建对象
饿汉式单例是如何保证线程安全的呢
它是基于类加载机制避免了多线程的同步问题但是如果类被不同的类加载器加载就会创建不同的实例比如使用反射来破坏单例
懒汉式线程安全
通过 synchronized 关键字加锁保证线程安全 synchronized 可以添加在方法上面也可以添加在代码块上面这里演示添加在方法上面存在的问题是 每一次调用getInstance获取实例时都需要加锁和释放锁这样是非常影响性能的。
/*** 单例模式* 懒汉式线程安全但是效率很低* 优点第一次调用才初始化避免内存浪费* 缺点必须枷锁synchronized才能保证单例枷锁会影响效率*/
public class SingletonLanHan{private static SingletonLanHan instance;private SingletonLanHan(){}public static synchronized SingletonLanHan getInstance(){if(instance null){instance new SingletonLanHan();}return instance;}
}优点懒加载线程安全缺点必须枷锁synchronized才能保证单例枷锁会影响效率
双重检查锁DCL 即 double-checked locking
采用双锁机制安全且能在多线程的情况下保持高性能
public class SingletonDCL{private static volatile SingletonDCL instance;private SingletonDCL(){}publica static SingletonDCL getInstance(){if(instance null){synchronized(SingletonDCL.class){if(instance null){instance new SingletonDCL();}}}return instance;}
}优点懒加载线程安全效率较高缺点实现较复杂
这里的双重检查是指两次非空判断锁指的是 synchronized 加锁。
为什么要进行双重判断
其实很简单第一重判断如果实例已经存在那么就不再需要进行同步操作而是直接返回这个实例如果没有创建才会进入同步块同步块的目的与之前相同目的是为了防止有多个线程同时调用时导致生成多个实例有了同步块每次只能有一个线程调用访问同步块内容当第一个抢到锁的调用获取了实例之后这个实例就会被创建之后的所有调用都不会进入同步块直接在第一重判断就返回了单例。
关于内部的第二重空判断的作用当多个线程一起到达锁位置时进行锁竞争其中一个线程获取锁如果是第一次进入则为 null会进行单例对象的创建完成后释放锁其他线程获取锁后就会被空判断拦截直接返回已创建的单例对象。
这里为什么要使用 volatile
volatile的两个特性可⻅性、禁止指令重排序
这是因为 new 关键字创建对象不是原子操作创建一个对象会经历下面的步骤
在堆内存开辟内存空间调用构造方法初始化对象引用变量指向堆内存空间
为了提高性能编译器和处理器常常会对既定的代码执行顺序进行指令重排序排序后的顺序可能为1、2、3或者1、3、2因此当某个线程在乱序运行 1、3、2 指令的时候引用变量指向堆内存空间这个对象不为 null但是没有初始化其他线程有可能这个时候进入了 getInstance 的第一个 if(instance null) 判断不为 nulll 导致错误使用了没有初始化的非 null 实例这样的话就会出现异常这个就是著名的DCL 失效问题。
其他线程有可能这个时候进入了 getInstance 的第一个 if(instance null) 判断不为 nulll 导致错误使用了没有初始化的非 null 实例这样的话就会出现异常这个就是著名的DCL 失效问题**。
⼯⼚模式
简单工厂模式
简单⼯⼚模式指由⼀个⼯⼚对象来创建实例客户端不需要关注创建逻 辑只需提供传⼊⼯⼚的参数。
UML类图如下 适⽤于⼯⼚类负责创建对象较少的情况缺点是如果要增加新产品就需要修改⼯⼚类的判断逻辑违背开闭原则且产品多的话会使⼯⼚类⽐较复杂。
例子
Calendar 抽象类的 getInstance ⽅法调⽤createCalendar ⽅法根据不同 的地区参数创建不同的⽇历对象。
Spring 中的 BeanFactory 使⽤简单⼯⼚模式根据传⼊⼀个唯⼀的标识来 获得 Bean 对象.
⼯⼚⽅法模式
和简单⼯⼚模式中⼯⼚负责⽣产所有产品相⽐⼯⼚⽅法模式将⽣成具体 产品的任务分发给具体的产品⼯⼚。
UML类图如下 也就是定义⼀个抽象⼯⼚其定义了产品的⽣产接⼝但不负责具体的产品将⽣产任务交给不同的派⽣类⼯⼚。这样不⽤通过指定类型来创建对象了。
抽象⼯⼚模式
简单⼯⼚模式和⼯⼚⽅法模式不管⼯⼚怎么拆分抽象都只是针对⼀类产 品如果要⽣成另⼀种产品就⽐较难办了
抽象⼯⼚模式通过在 AbstarctFactory 中增加创建产品的接⼝并在具体⼦⼯⼚中实现新加产品的创建当然前提是⼦⼯⼚⽀持⽣产该产品。否则继承的这个接⼝可以什么也不⼲。
UML类图如下 从上⾯类图结构中可以清楚的看到如何在⼯⼚⽅法模式中通过增加新产品 接⼝来实现产品的增加的。