设计模式

设置模式的六大原则:

  1.     单一职责 : 一个类只能负责一个功能领域的相应职责。
  2.     开闭原则: 一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展
  3.     里氏代换原则: 所有引用基类(父类)的地方必须能透明地使用其子类的对象 里氏代换原则告诉我们,在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用基类对象。例如:我喜欢动物,那我一定喜欢狗,因为狗是动物的子类;但是我喜欢狗,不能据此断定我喜欢动物,因为我并不喜欢老鼠,虽然它也是动物
  4.     依赖倒转原则(Dependency Inversion  Principle, DIP): 抽象不应该依赖于细节,细节应当依赖于抽象。换言之,要针对接口编程,而不是针对实现编程。依赖倒转原则要求我们在程序代码中传递参数时或在关联关系中,尽量引用层次高的抽象层类,即使用接口和抽象类进行变量类型声明、参数类型声明、方法返回类型声明,以及数据类型的转换等,而不要用具体类来做这些事情。为了确保该原则的应用,一个具体类应当只实现接口或抽象类中声明过的方法,而不要给出多余的方法,否则将无法调用到在子类中增加的新方法。
  5.   接口隔离原则(Interface  Segregation Principle, ISP):使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。
  6.   迪米特法则(Law of  Demeter, LoD)(最少知识法则):一个软件实体应当尽可能少地与其他实体发生相互作用。

工厂模式:

   分为三类: 简单工厂模式  : 抽象接口,具体实现类,在工厂中用if ..else  ||  switch 来选择具体的类

                      工厂方法模式   :在简单工厂基础上 定义一个工厂的抽象接口类, 根据抽象接口类来生成具体的类

                      抽象工厂模式

策略模式 :

    定义⼀组算法,将每⼀个算法封装起来,从⽽使它们可以相互切换

单例设计模式:

线程安全的单例:双重检锁:

 

 

      破坏单例:  使用反射

     防止单例破坏:

        

private Singleton() {

if (null != Singleton.uniqueSingleton)
throw new RuntimeException();

 }

    

 

在反序列化时,指定反序化的对象实例。即只要在Singleton类中定义readResolve就可以解决该问题 

  1.  private Object readResolve(){ 
  2.         return instance;
  3.     }
 

spring中bean的单例
a. 当多个用户同时请求多个服务时,容器会给每个请求分配一个线程,这时多个线程会并发执行该 请求对应的业务逻辑(成员方法),此时就要注意了,如果该处理逻辑中有对单例状态的修改(体 现为该单例的成员属性),则必须考虑线程同步问题。 有状态就是有数据存储功能。
有状态对象(Stateful Bean),就是有实例变量的对象,可以保存数 据,是线程安全的。在不同方法调用间不保留任何状态。
无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变量的对象 . 不能保存数据,是不变类,是线程安全的。

命令模式:

代理模式:静态代理 动态代理  cglib

静态代理

  

优点:可以做到在不修改⽬标对象的功能前提下,对⽬标功能扩展.
缺点:每⼀个代理类都必须实现⼀遍委托类(也就是realsubject)的接⼝,如果接⼝增加⽅法,则代理类
也必须跟着修改。其次,代理类每⼀个接⼝对象对应⼀个委托对象,如果委托对象⾮常多,则静态代理类
就⾮常臃肿,难以胜任。
 
jdk动态代理
动态代理解决静态代理中代理类接⼝过多的问题,通过反射来实现的,借助Java⾃带的
java.lang.reflect.Proxy,通过固定的规则⽣成。
 实现一个接口 
InvocationHandler
Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler)
 

1. loader,指定代理对象的类加载器;
2. interfaces,代理对象需要实现的接⼝,可以同时指定多个接⼝;
3. handler,⽅法调⽤的实际处理者,代理对象的⽅法调⽤都会转发到这⾥(*注意1)

 

cglib代理:

⾸先实现⼀个MethodInterceptor,⽅法调⽤会被转发到该类的intercept()
 
 
jdk动态代理:利⽤拦截器(拦截器必须实现InvocationHanlder)加上反射机制⽣成⼀个实现代理接⼝的
匿名类,在调⽤具体⽅法前调⽤InvokeHandler来处理。只能对实现了接⼝的类⽣成代理只能对实现了
接⼝的类⽣成代理
 
2. cglib:利⽤ASM开源包,对代理对象类的class⽂件加载进来,通过修改其字节码⽣成⼦类来处理。主
要是对指定的类⽣成⼀个⼦类,覆盖其中的⽅法,并覆盖其中⽅法实现增强,但是因为采⽤的是继承,
对于final类或⽅法,是⽆法继承的。
3. 选择
a. 如果⽬标对象实现了接⼝,默认情况下会采⽤JDK的动态代理实现AOP。
b. 如果⽬标对象实现了接⼝,可以强制使⽤CGLIB实现AOP。
c. 如果⽬标对象没有实现了接⼝,必须采⽤CGLIB库,Spring会⾃动在JDK动态代理和CGLIB之间转
 

  

 

 

                      

posted @ 2021-02-07 11:23  SinceJuly~  阅读(63)  评论(0)    收藏  举报