目录
一、设计模式
1.什么是设计模式?
设计模式是一套被反复适用、多数人知晓的、经过分类编目的、代码设计经验的总结。适用设计模式是为了可重用代码、让代码更容易被他人理解、保障代码可靠性、程序的重用性。
2.适用设计模式的好处?
-
设计模式可在多个项目中重用。
-
设计模式提供了一个帮助定义系统架构的解决方案。
-
设计模式为应用程序的设计提供了透明性。
-
设计模式是被实践证明切实有效的,由于它们是建立在专家软件开发人员的知识和经验之上的。
3.设计模式六大原则?
原则 | 解释 |
单一责任原则(Principle of single responsibility) | 一个类或者一个方法只负责一项职责 |
里氏替换原则(Liskov Substitution Principle) | 使用基类的任何地方可以使用继承的子类,完美的替换基类。 |
依赖倒转原则(Dependence Inversion Principle) | 其核心思想是面向接口编程。 |
接口隔离原则(Interface Segregation Principle) | 使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思。 |
迪米特法则(Demeter Principle) | 最少知道原则,一个对象应当对其他对象有尽可能少地了解,简称类间解耦。 |
开闭原则(Open Close Principle) | 尽量通过扩展软件实体来解决需求变化,而不是通过修改已有的代码来完成变化。 |
4.设计模式如何分类?
分类 | 具体 |
创建模式 | 五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式 |
结构模式 | 七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 |
行为模式 | 十一种:策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 |
二、创建模式
1.单例模式
(1)什么是单例模式?
单例模式是指在内存中只会创建仅一次对象的设计模式。在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。
(2)单例模式的应用
1)应用程序的日志应用,一般都可用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
2)数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。
3)多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。
(3)单例模式的类型
单例模式有两种类型:懒汉式和饿汉式。
<1>饿汉式:类初始化时会立即创建该类单例对象,在程序调用时直接返回单例对象即可,线程天生安全,调用效率高。
public class Singleton{
private static final Singleton singleton = new Singleton();
private Singleton(){}
public static Singleton getInstance() {
return singleton;
}
}
<2>懒汉式:懒汉式创建对象的方法是在程序使用对象前,先判断该对象是否已经实例化(判空),若已实例化直接返回该类对象,否则则先执行实例化操作。
//懒汉式单例类.在第一次调用的时候实例化自己
public class Singleton {
private Singleton() {}
private static Singleton single=null;
//静态工厂方法
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
<3>静态内部方式:结合了懒汉式和饿汉式各自的优点,真正需要对象的时候才会加载,加载类是线程安全的。
public class Demo3 {
public static class SingletonClassInstance {
private static final Demo3 DEMO_3 = new Demo3();
}
// 方法没有同步
public static Demo3 getInstance() {
return SingletonClassInstance.DEMO_3;
}
}
<4>枚举单例:使用枚举实现单例模式,其优点是实现简单、调用效率高,枚举本身就是单例,由 JVM 从根本上提供保障,避免通过反射和反序列化的漏洞,而缺点是没有延迟加载。
public class Demo4 {
public static Demo4 getInstance() {
return Demo.INSTANCE.getInstance();
}
//定义枚举
private static enum Demo {
INSTANCE;
// 枚举元素为单例
private Demo4 demo4;
private Demo() {
demo4 = new Demo4();
}
public Demo4 getInstance() {
return demo4;
}
}
}
<5>双重检测锁方式:防止创建多个bean对象,保证线程安全。
第一次判断是为了验证是否创建对象,判断为了避免不必要的同步;
第二次判断是为了避免重复创建单例,因为可能会存在多个线程通过了第一次判断在等待锁,来创建新的实例对象。
public class Demo5 {
private volatile static Demo5 demo5;
public static Demo5 getInstance() {
if (demo5 == null) {
synchronized (Demo5.class) {
if (demo5 == null) {
demo5 = new Demo5();
}
}
}
return demo5;
}
}
2.工厂模式
工厂模式提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
(1)工厂模式的优点:
<1>工厂模式是我们最常用的实例化对象模式,是工厂方法代替new操作的一种模式;
<2>利用工厂模式可以降低程序的耦合,为后期维护提供了很大的便利;
<3> 将选择实现类、创建对象同一管理和控制。从而将调用者跟我们的实现类解耦。
(2)工厂模式的分类:
实现了创建者和调用者分离,工厂模式又可以分为简单工厂、工厂方法以及抽象工厂三种模式。
<1>简单工厂:用来生产统一登记结构中的热议产品。(不支持拓展增加产品)
<2>工厂方法:用来生产同一等级结构中的固定产品。(支持拓展增加产品)
<3>抽象工厂:用来生产不同产品族的全部产品。(支持拓展增加产品)