Java反射机制:就是正在运行,动态获取这个类的所有信息。作用是反编译、访问java对象的属性,方法,构造方法等。应用场景有Jdbc 加载驱动、Spring IOC、框架等。


反射获取类方式

  • Class.forName(“Employee”)
  • Employee.class
  • Employee e = new Employee();
    Class class3 = e.getClass();

反射创建对象的方式

  • 无参构造
Class<?> forName = Class.forName("com.ylw.reflect.Employee");
 Object newInstance = forName.newInstance();
  • 有参构造
Class<?> forName1 = Class.forName("com.ylw.reflect.Employee");
 Constructor<?> constructor = forName1.getConstructor(String.class, String.class);
 Employee newInstance1 = (Employee) constructor.newInstance("张三", "男");

备注:通过将构造函数为私有化可以禁止使用反射机制初始化


设计模式的六大原则:

  • 开闭原则(Open Close Principle): 就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类。
  • 里氏代换原则(Liskov Substitution Principle LSP): 面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
  • 依赖倒转原则(Dependence Inversion Principle): 针对接口编程,依赖于抽象而不依赖于具体。
  • 接口隔离原则(Interface Segregation Principle): 使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。
  • 迪米特法则(最少知道原则)(Demeter Principle): 一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
  • 合成复用原则(Composite Reuse Principle): 原则是尽量使用合成/聚合的方式,而不是使用继承。

单例模式:保证一个类只有一个实例,并且提供一个访问该全局访问点。创建方式有如下几种:

  • 饿汉式: 类初始化时,会立即加载该对象,线程天生安全,调用效率高。
  • 懒汉式: 类初始化时,不会初始化该对象,真正需要使用的时候才会创建该对象,具备懒加载功能。
  • 静态内部方式: 结合了懒汉式和饿汉式各自的优点,真正需要对象的时候才会加载,加载类是线程安全的。
  • 枚举单例 : 使用枚举实现单例模式, 优点是实现简单、调用效率高,枚举本身就是单例,由jvm从根本上提供保障!避免通过反射和反序列化的漏洞, 缺点没有延迟加载。
  • 双重检测锁方式 :因为JVM本质重排序的原因,可能会初始化多次,不推荐使用。

工厂模式:代替new操作的一种模式、实现了创建者和调用者分离、将选择实现类、创建对象统一管理和控制。(回忆:Flink的工厂模式)


代理模式:通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用处理,或调用后处理。既(AOP微实现) ,AOP核心技术面向切面编程。

代理模式的应用场景:SpringAOP、事务原理、日志打印、权限控制、远程调用、安全代理、可以隐蔽真实角色等

代理分类

  • 静态代理:在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了;
  • 动态代理:动态的在内存中构建代理对象。分为JDK动态代理(利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理)、cglib动态代理(利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理)。在Spring中,目标对象没有实现了接口,必须采用CGLIB库,如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP。

建造者模式:将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。(举例:企微SDK的消息体构建、hutool工具类的builder模式);


模板方法模式:定义一个操作中的算法骨架,而将一些步骤延迟到子类中。简单的说就是实现一些操作时,整体步骤很固定,但就是其中一小部分容易变,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。(举例:Junit单元测试、JDBCTemplate、DataX的生命周期、DS的生命周期等)。


适配器模式:将一个类的接口转接成用户所期待的。


门面模式:隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口(举例:消息统一发送接口,一个接口发送多种渠道消息);


原型模式:原型二字表明了改模式应该有一个样板实例,用户从这个样板对象中复制一个内部属性一致的对象,这个过程也就是我们称的“克隆”。分为:

  • 浅复制:只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做“(浅复制)浅拷贝”,换句话说,浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅复制出来的对象也会相应改变。
  • 深复制:在计算机中开辟了一块新的内存地址用于存放复制的对象。

策略模式:定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。(举例:消息发送可以控制渠道的开关、数据同步可以控制同步内容的开关。不一定定义枚举,可以通过ServiceLoader加载,插件化)


责任链模式:按顺序执行,这里贴图做回忆。

Review:设计模式篇_开发语言


观察者模式:观察者模式主要用于1对N的通知,当一个对象的状态变化时,他需要及时告知一系列对象,令他们做出相应。(举例:通知同步进度)

Review:设计模式篇_开发语言_02