12种常用设计模式

1 反射 (类名)Class forName(String 类路径) newInstance();类对象 getClass() newInstance()类

1.反射

(类名)Class.forName(String 类路径).newInstance();
类对象.getClass().newInstance()
类.class.newInstance()
如何防止被反射

2.六大原则

开闭原则OCP、里氏代换原则、依赖倒转原则、迪米特法则、合成复用原则

 

行为型模式5(工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式)
创建型模式7(适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式)
结构型模式11(策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式)

1.单例模式:

节约内存、重复利用、方便管理,但是有线程安全问题
五种创建方式:饿汉、懒汉、静态内部类、枚举方式、双重检测锁(会有重排序问题)
构造函数私有化、变量使用static修饰放永久区、懒汉式用synchronized达到线程安全(效率低)
如何防止单例被攻击:在构造函数中做判断,只能执行初始化一次,如果执行了两次构造函数就报错
private static boolean flag = false;
private SingletonDemo04() {
  if (flag == false) {
    flag = !flag;
  } else {
    throw new RuntimeException("单例模式被侵犯!");
  }
}

 

工厂设计模式Factory:

简单工厂:动态使用缓存或者数据库+反射,实现,项目里open_utils_service+!!动态代理设计模式!!(不支持拓展增加产品)

2.工厂方法模式即多个简单工厂相结合(用来生产同一等级结构中的固定产品,车,不同牌子的车),支持拓展增加产品

3.抽象工厂生产不同产品族群的全部产品(不仅是不同牌子的车,还有车的零件:椅子、发动机等的族群),支持增加产品族群,不支持拓展增加产品

 

4.代理模式Proxy :

静态代理:在代理类的构造函数里传入本体类,调用其方法并加上自己的自定义需要执行的代码
JDK动态代理、CGLIb动态代理(传入的类可以不用是实现接口的)
JDK动态代理只能对实现了接口的类生成代理,而不能针对类 。
CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 。
因为是继承,所以该类或方法最好不要声明成final ,final可以阻止继承和多态
如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

 

5.创建者模式:

要创建的复杂对象Product,包含所有创建方法的接口Builder,ConcreteBuilder实现此接口细化创建过程并返回创建的Product,指导者Director调用具体建造者来创建复杂对象的各个部分,不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建
相较于策略模式:把使用者那一步加进来了
使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。

 

6.模板方法:

定义一个处理流程模板abstract,相似的不易变得的都放在此实现,将容易变的部分抽象出来,供子类实现,使得子类可以不改变一个算法的结构即可重定义该算法的,使用者只要用子类调用流程方法就可以了
场景:处理某个流程的代码已经都具备,但是其中某个节点的代码暂时不能确定
实际使用:数据库访问的封装、Junit单元测试、servlet中关于doGet/doPost方法的调用、Hibernate中模板程序、spring中JDBCTemplate,HibernateTemplate等等

 

7.适配器模式:

适配器继承适配的类,构造函数中传入被适配的类,并重写方法函数中代码,变为调用被适配的类的方法。即在运行中,没有调用适配器,则运行原本的方法,一旦调用了适配器(继承自原本方法),久会调用适配器里重写的方法(被适配的类的方法),就是转换。
使用案例:
OutputStreamWriter:是Writer的子类,将输出的字符流变为字节流,即:将一个字符流的输出对象变为字节流的输出对象。
InputStreamReader:是Reader的子类,将输入的字节流变为字符流,即:将一个字节流的输入对象变为字符流的输入对象。
SpringMVC 适配器

 

8.外观模式:

结构型模式,向现有的系统添加一个接口,来隐藏系统的复杂性

 

9.原型模式:

浅复制只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用(但String类型是final修饰,支持克隆,复制后不会发生引用),浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅复制出来的对象也会相应改变
深复制 —-在计算机中开辟了一块新的内存地址用于存放复制的对象

 

10.装饰模式Decorator :

与代理模式区别:装饰模式,突出的是运行期增加行为,动态扩展对象的访问;代理是在代理类中创建一个对象的实例,控制使用者对对象的访问,完全限制了使用者,更像是一种特殊定制;装饰模式将原始对象作为参数传递给修饰类,可以很灵活的让使用者感受到增强或着说装饰了那些东西,就像IO流一样。就是代理模式中要实现的点太多独立变化,就可以考虑装饰模式了(一人包干和团体运作的区别吧)。
不论使用哪个模式,都可以很容易地在真实对象的方法前后加上自定义方法
实现的是同一接口,可以通过构造函数反复修饰,加糖加盐加油加醋,想先加那个后加哪个,想加那个再加哪个都可以,灵活的鸭皮
思考:如果不仅仅想在真是对象方法前后加上自定义呢?我想在中间加,该怎么办?

 

11.策略模式:

相较于模板模式,模板方法把流程定下来,使用什么实现用子类去继承重写,使用者直接调用流程方法(即单继承实现所有)。策略就是各个流程分开为多个抽象模板,每个抽象模板有多个实现策略,把单个流程模板放在一个context类里去自定义实现,调用者自己实现此流程,每个流程里用哪个方法就是调用哪个策略
策略模式中一个‘策略’是一个完整的算法,流程中算法可以自定义组合,但是模板模式中只能改变一个或几个特定的算法(全都要改就没必要用这个模式了)。算法流程策略模式可以改变,模板模式也可以在子类中是实现改变
使用场景:多个变化点会独立变化时,使用策略模式更优,多个变化点少数会独立变化是,使用模块方法更优

 

12.观察者模式:

目标和观察者是基类,目标提供维护观察者的一系列方法,观察者提供更新接口
(将观察者类注册进观察目标类,当目标信息改变的时候,目标类循环注册列表里的观察者的update()方法更新观察者数据,即被动观察到被观察目标改变)
两种实现方式:
推:每次都会把通知以广播的方式发送给所有观察者,所有的观察者只能被动接收
拉:观察者只要知道有情况即可,至于什么时候获取内容,获取什么内容,都可以自主决定。