java的设计模式及代理模式

复制代码
 JAVA六大设计原则
 JAVA设计模式提供六个基本原则,分别是:

  开闭原则(OCP) - The Open-Closed Principle
  单一职责原则(SRP) - Single Responsibility Principle
 里氏替换原则(LSP) - Liskov Substitution Principle
 依赖倒置原则(DIP) - Dependency Inversion Principle
 接口隔离原则(ISP) - Interface Segregation Principle
 迪米特法则(DP) - Demeter Principle

 JAVA23种设计模式

 在软件工程当中,设计原则和设计模式是不同的.

 # 设计原则
 设计原则是为了更好的设计软件的高层指导方针. 
 它不提供具体的实现方式也不会绑定任何一种编程语言.  
 最常用的原则是SOLID(SRP, OCP, LSP, ISP, DIP)原则

   设计模式
 设计模式对关于面向对象问题的具体解决方案.
 比如说, 如果你想创建一个类而且它在任何时刻只会有一个对象,那么你就应该使用单例类模式.
 设计模式是经过大量检测的安全的做法.

单例设计模式

懒汉式:

java 复制代码
package com.apesource.lazytest;

public class Test02 {
    public static void main(String[] args) {
        Student stu1=Student.getInstance();
        Student stu2=Student.getInstance();
        System.out.println(stu1==stu2);
    }
}
java 复制代码
package com.apesource.lazytest;

public class Student {
    //3。创建static修饰的成员变量
    private static Student stu;

    //1。设计私有构造方法
    private Student(){
        super();
    }
    //2.提供共有的方法
    public static synchronized Student getInstance(){
        if(stu==null){
            stu=new Student();
        }
        return stu;
    }
}

饿汉式:

java 复制代码
package com.apesource.hungrytest;

/**
 * 饿汉式
 */
public class Student {
    //创建static修饰的成员变量
    private static Student stu=new Student();

    //1.设计私有构造方法
    private Student(){
        super();
    }
    //2.提供共有方法
    public static synchronized Student getInstance(){
        return stu;
    }
}
java 复制代码
package com.apesource.hungrytest;

import com.apesource.lazytest.Student;

public class Test03 {
    public static void main(String[] args) {

        com.apesource.lazytest.Student stu1=com.apesource.lazytest.Student.getInstance();
        com.apesource.lazytest.Student stu2= Student.getInstance();
        System.out.println(stu1==stu2);
    }
}

代理模式

静态代理:
java 复制代码
package com.apesource.statictest;

public interface ISinger {
    public void sing();
}
java 复制代码
package com.apesource.statictest;

public class luhanImp implements ISinger{
    @Override
    public void sing() {
        System.out.println("我们的明天");
    }
}
java 复制代码
package com.apesource.statictest;

public class DailirenImp implements ISinger{

    //注入一个代理对象
    ISinger singer;

    public void setSinger(ISinger singer) {
        this.singer = singer;
    }

    @Override
    public void sing() {
        System.out.println("===跳舞==");
        singer.sing();
    }
}
java 复制代码
package com.apesource.statictest;

public class Test01 {
    public static void main(String[] args) {
        //1.创建鹿晗(被代理)
        luhanImp luhanImp=new luhanImp();
        //2.创建经纪人(代理)
        DailirenImp dailirenImp=new DailirenImp();
        dailirenImp.setSinger(luhanImp);

        //3.调用经纪人的唱歌
        dailirenImp.sing();
    }
}
动态代理(proxy):
  1. 动态生成代理对象

    客户端通过Proxy.newProxyInstance()请求生成代理对象时,JVM 会在内存中动态创建一个类(代理类),该类实现了目标对象的所有接口(如IStar),并生成对应的方法(sing())。

  2. 方法调用转发

    当客户端调用代理对象的任何方法(如proxyStar.sing()),动态生成的代理类会将调用转发InvocationHandlerinvoke()方法,并传入三个参数:

    • 代理对象本身(proxy);
    • 当前调用的方法(method,如sing()对应的 Method 对象);
    • 方法参数(args)。
  3. 增强逻辑执行

    invoke()方法中,我们可以自由定义增强逻辑:

    • 先执行前置操作(如经纪人的准备工作);
    • 通过method.invoke(target, args)调用目标对象的实际方法(核心业务);
    • 再执行后置操作(如经纪人的收尾工作)。
  4. 返回结果

    目标方法的返回值通过invoke()方法返回给客户端,整个过程对客户端透明。

java 复制代码
package com.apesource.proxy;

public interface ISinger {
    public void sing();
}
java 复制代码
package com.apesource.proxy;

public class CaiYiImp implements ISinger{

    @Override
    public void sing() {
        System.out.println("===日不落===");
    }
}
java 复制代码
package com.apesource.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Test01 {
    public static void main(String[] args) {
        //1.创建被代理对象
        final ISinger cai=new CaiYiImp();
        //2.创建代理对象
//        cai.getClass().getInterfaces(),   // 被代理对象实现的接口
//        new InvocationHandler()          // 调用处理器
        ISinger proxy=(ISinger) Proxy.newProxyInstance(cai.getClass().getClassLoader(),// 类加载器
                cai.getClass().getInterfaces(), new InvocationHandler() {


//            :实现调用处理器逻辑
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object object=null;
                        try {
                            //执行被代理对象内的方法
                            object=method.invoke(cai,args);
                            return object;
                        } catch (Exception e) {
                            return object;
                        }
                    }
                });
//        这里通过代理对象 proxy 调用 sing() 方法,实际会触发调用处理器的 invoke 方法,最终执行被代理对象 cai 的 sing() 方法。
        proxy.sing();
    }


}
动态代理(cglib)
java 复制代码
package com.apesource.cglibtest;

public interface ISinger {
    public void sing();
}
java 复制代码
package com.apesource.cglibtest;

public class TengGeErImp implements ISinger{
    @Override
    public void sing() {
        System.out.println("听了赵雷的成都去了成都,听了王峰的北京去了北京,至今不敢听腾格尔的天堂~");
    }
}
java 复制代码
package com.apesource.cglibtest;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InvocationHandler;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test02 {
    public static void main(String[] args) {
        //1。创建被代理对象
        final ISinger teng = new TengGeErImp();

        //2.代理对象
        ISinger proxy = (ISinger) Enhancer.create(teng.getClass(), new InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                Object obj;
                try {
                    obj = method.invoke(teng, objects);

                    return obj;
                } catch (IllegalAccessException e) {
                    return null;
                }
            }
        });

        proxy.sing();
    }


}

动态代理 vs 静态代理(核心区别)

对比维度 静态代理 动态代理(JDK)
代理类创建方式 手动编写,编译期确定 JVM 运行时动态生成,无需手动编写
灵活性 代理类与接口绑定(如 Agent 只能代理 IStar) 可代理任意接口的对象,一个处理器可通用
接口方法变更 需修改代理类(如新增 greet () 需同步实现) 无需修改,自动适配接口所有方法
适用场景 接口固定、方法少的简单场景 接口多变、需要通用代理逻辑的场景(如 Spri

工厂模式

java 复制代码
package com.apesource.test;

public interface INoodles {
    public void noodleType();
}
java 复制代码
package com.apesource.test;

public class LanZhouLaMian implements INoodles{

    @Override
    public void noodleType() {
        System.out.println("========来一碗兰州拉面=====");
    }
}
java 复制代码
package com.apesource.test;

public class ReGanMianNoodleImp implements INoodles{
    @Override
    public void noodleType() {
        System.out.println("======来一碗热干面==========");
    }
}
java 复制代码
package com.apesource.test;

public class YouPoMianNoodleImp implements INoodles{

    @Override
    public void noodleType() {
        System.out.println("========来一碗油泼面========");
    }
}
java 复制代码
package com.apesource.test;
/**
 * 面长
 */
public class NoodleFactory {
    /**
     * 规范下面条类型
     */
    public static final int NOODLE_YOUPO=1;
    public static final int NOODLE_REGAN=2;
    public static final int NOODLE_LANZHOULA=3;

    /**
     * 创建面条
     *
     */
    public static INoodles getNoodle(int type){
        if(type==1){
            return new YouPoMianNoodleImp();
        }else if(type==2){
            return new ReGanMianNoodleImp();
        }else if(type==3){
            return new LanZhouLaMian();
        }
        return null;
    }

}
java 复制代码
package com.apesource.test;

public class Test01 {
    public static void main(String[] args) {
        NoodleFactory.getNoodle(NoodleFactory.NOODLE_LANZHOULA).noodleType();;
        NoodleFactory.getNoodle(3).noodleType();
    }
}

模板模式:

复制代码
所谓模板板式,就是在父类中定义算法的主要流程,而把一些个性化的步骤延迟到子类中去实现,父类始终控制着整个流程的主动权,子类只是辅助父类实现某些可定制的步骤
java 复制代码
public abstract class FatherClass {
    public final void time(){
        study();
        work();
        aiqing();
    }

    public abstract void aiqing();


    public void work() {
        System.out.println("努力工作");
    }

    public void study() {
        System.out.println("好好学习 天天向上");
    }
}
java 复制代码
public class SonClass extends FatherClass{

    @Override
    public void aiqing() {
        System.out.println("真诚是唯一的必杀技");
    }

    @Override
    public void study() {
        System.out.println("学到很晚才回家睡觉");
    }

    @Override
    public void work() {
        System.out.println("以后会努力的工作");
    }
}
java 复制代码
 public class Test {
    public static void main(String[] args) {
        FatherClass fatherClass=new SonClass();
        fatherClass.time();
    }
}