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 PrincipleJAVA23种设计模式在软件工程当中,设计原则和设计模式是不同的.# 设计原则设计原则是为了更好的设计软件的高层指导方针. 它不提供具体的实现方式也不会绑定任何一种编程语言. 最常用的原则是SOLID(SRP, OCP, LSP, ISP, DIP)原则设计模式设计模式对关于面向对象问题的具体解决方案.比如说, 如果你想创建一个类而且它在任何时刻只会有一个对象,那么你就应该使用单例类模式.设计模式是经过大量检测的安全的做法.
单例设计模式
懒汉式:
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);}
}
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;}
}
饿汉式:
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;}
}
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);}
}
代理模式
静态代理:
package com.apesource.statictest;public interface ISinger {public void sing();
}
package com.apesource.statictest;public class luhanImp implements ISinger{@Overridepublic void sing() {System.out.println("我们的明天");}
}
package com.apesource.statictest;public class DailirenImp implements ISinger{//注入一个代理对象ISinger singer;public void setSinger(ISinger singer) {this.singer = singer;}@Overridepublic void sing() {System.out.println("===跳舞==");singer.sing();}
}
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):
动态生成代理对象:
客户端通过Proxy.newProxyInstance()
请求生成代理对象时,JVM 会在内存中动态创建一个类(代理类),该类实现了目标对象的所有接口(如IStar
),并生成对应的方法(sing())。方法调用转发:
当客户端调用代理对象的任何方法(如proxyStar.sing()
),动态生成的代理类会将调用转发给InvocationHandler
的invoke()
方法,并传入三个参数:- 代理对象本身(
proxy
); - 当前调用的方法(
method
,如sing()
对应的 Method 对象); - 方法参数(
args
)。
- 代理对象本身(
增强逻辑执行:
在invoke()
方法中,我们可以自由定义增强逻辑:- 先执行前置操作(如经纪人的准备工作);
- 通过
method.invoke(target, args)
调用目标对象的实际方法(核心业务); - 再执行后置操作(如经纪人的收尾工作)。
返回结果:
目标方法的返回值通过invoke()
方法返回给客户端,整个过程对客户端透明。
package com.apesource.proxy;public interface ISinger {public void sing();
}
package com.apesource.proxy;public class CaiYiImp implements ISinger{@Overridepublic void sing() {System.out.println("===日不落===");}
}
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() {// :实现调用处理器逻辑@Overridepublic 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)
package com.apesource.cglibtest;public interface ISinger {public void sing();
}
package com.apesource.cglibtest;public class TengGeErImp implements ISinger{@Overridepublic void sing() {System.out.println("听了赵雷的成都去了成都,听了王峰的北京去了北京,至今不敢听腾格尔的天堂~");}
}
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() {@Overridepublic 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 |
工厂模式
package com.apesource.test;public interface INoodles {public void noodleType();
}
package com.apesource.test;public class LanZhouLaMian implements INoodles{@Overridepublic void noodleType() {System.out.println("========来一碗兰州拉面=====");}
}
package com.apesource.test;public class ReGanMianNoodleImp implements INoodles{@Overridepublic void noodleType() {System.out.println("======来一碗热干面==========");}
}
package com.apesource.test;public class YouPoMianNoodleImp implements INoodles{@Overridepublic void noodleType() {System.out.println("========来一碗油泼面========");}
}
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;}}
package com.apesource.test;public class Test01 {public static void main(String[] args) {NoodleFactory.getNoodle(NoodleFactory.NOODLE_LANZHOULA).noodleType();;NoodleFactory.getNoodle(3).noodleType();}
}
模板模式:
所谓模板板式,就是在父类中定义算法的主要流程,而把一些个性化的步骤延迟到子类中去实现,父类始终控制着整个流程的主动权,子类只是辅助父类实现某些可定制的步骤
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("好好学习 天天向上");}
}
public class SonClass extends FatherClass{@Overridepublic void aiqing() {System.out.println("真诚是唯一的必杀技");}@Overridepublic void study() {System.out.println("学到很晚才回家睡觉");}@Overridepublic void work() {System.out.println("以后会努力的工作");}
}
public class Test {public static void main(String[] args) {FatherClass fatherClass=new SonClass();fatherClass.time();}
}