GOF(Group For Four)23设计模式
1. 创建型模式 1.1. 单例模式 只生成一个实例
1.1.1. 饿汉式 线程安全,调用效率高。不能延时加载
1 2 3 4 5 6 7 8 9 10 11 public class Singleton { private static Singleton instance = new Singleton (); private Singleton () {} public static Singleton getInstance () { return instance; } }
1.1.2. 懒汉式 线程安全,调用效率不高,可以延时加载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class Singleton { private static Singleton instance = null ; private Singleton () {} public static synchronized Singleton getInstance () { if (instance == null ){ instance = new Singleton (); } return instance; } }
1.1.3. 双重检测锁式 由于JVM底层内部模型原因,偶尔会出问题,不建议使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class Singleton { private static Singleton instance = null ; private Singleton () {} public static Singleton getInstance () { if (instance == null ){ Singleton s; synchronized (Singleton.class){ s = instance; if (s==null ){ synchronized (Singleton.class){ if (s==null ){ s = new Singleton (); } } instance = s; } } } return instance; } }
1.1.4. 静态内部类式 线程安全,调用效率高,不能延时加载
1 2 3 4 5 6 7 8 9 10 11 12 13 public class Singleton { private static class Singletonclass { private static final Singleton instance = new Singleton (); } private Singleton () {} public static Singleton getInstance () { return Singletonclass.instance; } }
1.1.5. 枚举单例 线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化漏洞
1 2 3 4 5 6 7 8 public enum Singleton { INSTANCE; public void singletonOperation () { } }
1.2. 工厂模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public interface Car { public void run () ; } public class Audi implements Car { public void run () { System.out.println("奥迪在跑" ); } } public class Baoma implements Car { public void run () { System.out.println("宝马在跑" ); } }
实现创建者和调用者分离
1.2.1. 简单工厂模式-静态 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class CarFactory { public static Car createCar (String type) { Car c = null ; if ("奥迪" .equals(type)){ c = new Audi (); }else if ("宝马" .equals(type)){ c = new Baoma (); } return c; } } public interface CarFactory { Car createCar () ; } public class AudiFactory implements CarFactory { public Car createCar () { return new Audi (); } } Car audi = new AudiFactory ().creatCar();
1.3. 抽象工厂模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 public interface Engine { void run () ; } public class LuxuryEngine implements Engine { @Override public void run () { } } public class LowEngine implements Engine { @Override public void run () { } } public interface Seat { void message () ; } public class LuxurySeat implements Seat { @Override public void message () { } } public class LowSeat implements Seat { @Override public void message () { } } public interface CarFatory { Engine createEngine () ; Seat createSeat () ; } public class LuxuryCarFactory implements CarFactory { @Override public Engine createEngine () { } @Override public Seat createSeat () { } }
1.4. 建造者模式 1.4.1. Airship 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package builder;public class Airship { private String engine; private String escapeTower; private String orbitalModule; public String getEngine () { return engine; } public void setEngine (String engine) { this .engine = engine; } public String getEscapeTower () { return escapeTower; } public void setEscapeTower (String escapeTower) { this .escapeTower = escapeTower; } public String getOrbitalModule () { return orbitalModule; } public void setOrbitalModule (String orbitalModule) { this .orbitalModule = orbitalModule; } @Override public String toString () { return "Airship [engine=" + engine + ", escapeTower=" + escapeTower + ", orbitalModule=" + orbitalModule + "]" ; } }
1.4.2. AirshipBuilder 1 2 3 4 5 6 7 8 9 10 package builder;public interface AirshipBuilder { String builderEngine () ; String builderOrbitalModule () ; String builderEscapeTower () ; }
1.4.3. AirshipDirector 1 2 3 4 5 6 7 8 package builder;public interface AirshipDirector { Airship createAirship (AirshipBuilder builder) ; }
1.4.4. CeacreteAirshipBuilder 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package builder;public class CeacreteAirshipBuilder implements AirshipBuilder { @Override public String builderEngine () { return "发动机" ; } @Override public String builderOrbitalModule () { return "轨道仓" ; } @Override public String builderEscapeTower () { return "逃逸塔" ; } }
1.4.5. CeacreteAirshipDirector 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package builder;public class CeacreteAirshipDirector implements AirshipDirector { @Override public Airship createAirship (AirshipBuilder builder) { Airship airship = new Airship (); airship.setEngine(builder.builderEngine()); airship.setEscapeTower(builder.builderEscapeTower()); airship.setOrbitalModule(builder.builderOrbitalModule()); return airship; } }
1.4.6. Client 1 2 3 4 5 6 7 8 9 10 11 12 13 14 package builder;public class Client { public static void main (String[] args) { AirshipDirector director = new CeacreteAirshipDirector (); Airship airship=director.createAirship(new CeacreteAirshipBuilder ()); System.out.println(airship); } }
1.5. 原型模式 2. 结构型模式 2.1. 适配器模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class Adaptee { public void method () { } } public interface Target { void handle () ; } public class Adapter extends Adaptee implements Target { public void handle () { } } public class Adapter implements Target { private Adaptee adaptee; public void handle () { } }
2.2. 桥接模式 多层继承结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public interface Brand { void sale () ; } public class Lenvo implements Brand { @Override public void sale () { } } public class Dell implements Brand { @Override public void sale () { } } public class computer { protected Brand brand; public Computer (Brand brand) { this .brand=brand; } public void sale () { brand.sale(); } } public class Laptop extends Computer { public Laptop (Brand brand) { super (brand); } } Computer c = new Laptop (new Dell ());
2.3. 装饰模式 IO流 BufferInputerStream(new InputStream())
线程 new Thread(new Runnable())
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public interface Car { void move () ; } public class Baoma implements Car { public void move () { } } public class SuperCar implements Car { protected Car car; public SuperCar (Car car) { this .car = car; } public void move () { car.move(); } } public class FlyCar extends SuperCar { public FlyCar (Car car) { super (car); } public void fly () { System.out.println("..." ); } public void move () { super .move(); fly(); } } Car car = new Baoma ();car.move(); FlyCar fly = new FlyCar (car);fly.move();
2.4. 组合模式 树形结构
1 2 3 4 5 6 7 8 9 10 11 12 13 public interface Component { void operation () ; } public interface Leaf extends Component { } public interface extends Component{ void add (Component c) ; void remove (Component c) ; Component getChlid () ; }
2.5. 外观模式 简单封装
2.6. 享元模式
2.7. 代理模式 使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。
代理模式的主要作用是扩展目标对象的功能,比如说在目标对象的某个方法执行前后你可以增加一些自定义的操作。
2.7.1. 静态代理模式 静态代理中,我们对目标对象的每个方法的增强都是手动完成的
它的适用性不高:
从 JVM 层面来说,静态代理在编译时就将接口、实现类、代理类这些都变成了一个个实际的 class 文件
静态代理实现步骤
定义一个接口及其实现类;
创建一个代理类同样实现这个接口
将目标对象注入进代理类,然后在代理类的对应方法调用目标类中的对应方法。通过代理类屏蔽对目标对象的访问,并且可以在目标方法执行前后做一些自己想做的事情。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public interface Star { void sing () ; } public class ProxyStar implements Star { private Star star; public proxy (Star star) { this .star=star; } @Override public void sing () { star.sing(); } } public class RealStar implements Star { @Override public void sing () { } } public class client { public static void main (String[] args) { Star star=new RealStar (); ProxyStar proxy = new ProxyStar (star); proxy.sing(); } }
2.7.2. 动态代理模式 相比于静态代理来说,动态代理更加灵活。不需要针对每个目标类都单独创建一个代理类,并且也不需要我们必须实现接口,我们可以直接代理实现类( CGLIB 动态代理机制 )。
从 JVM 角度来说,动态代理是在运行时动态生成类字节码,并加载到 JVM 中的
Spring AOP、RPC 框架的实现都依赖了动态代理
就 Java 来说,动态代理的实现方式有很多种,比如 JDK 动态代理 、CGLIB 动态代理 等等
2.7.2.1. Java动态代理机制 实现InvocationHandler
接口,利用Proxy
类的newProxyInstance
方法生成一个代理对象
1 2 3 4 5 6 7 8 9 public static Object newProxyInstance (ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException{}
要实现动态代理的话,还必须需要实现InvocationHandler
来自定义处理逻辑。 当动态代理对象调用一个方法时,这个方法的调用就会被转发到实现InvocationHandler
接口类的 invoke
方法来调用。
1 2 3 4 5 6 7 8 9 10 11 public interface InvocationHandler { public Object invoke (Object proxy, Method method, Object[] args) throws Throwable; }
也就是说:通过Proxy
类的 newProxyInstance()
创建的代理对象在调用方法的时候,实际会调用到实现InvocationHandler
接口的类的 invoke()
方法。 在 invoke()
方法中自定义处理逻辑,比如在方法执行前后做什么事情。
当动态代理对象调用原生方法的时候,最终实际上调用到的是 invoke()
方法,然后 invoke()
方法代替我们去调用了被代理对象的原生方法。
JDK 动态代理类使用步骤
定义一个接口及其实现类;
自定义 InvocationHandler
并重写invoke
方法,在 invoke
方法中我们会调用原生方法(被代理类的方法)并自定义一些处理逻辑;
通过 Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
方法创建代理对象;
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 package Proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public interface Star { public void sing (String name) ; } public class RealStar implements Star { @Override public void sing (String name) { System.out.println(name); } } public class ProxyInvocation implements InvocationHandler { Star star; public ProxyInvocation (Star star) { this .star = star; } @Override public Object invoke (Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before method " +method.getName()); Object obj = method.invoke(star, args); System.out.println("After method " +method.getName()); return obj; } package Proxy;import java.lang.reflect.Proxy;public class Client { public static void main (String[] args) { Star star = new RealStar (); Star proxy = (Star)Proxy.newProxyInstance( star.getClass().getClassLoader(), star.getClass().getInterfaces(), new ProxyInvocation (star)); proxy.sing("ABC" ); } }
或者使用代理对象的工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class JdkProxyFactory { public static Object getProxy (Object target) { return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new DebugInvocationHandler (target) ); } } Star proxy = (Star)JdkProxyFactory.getProxy(new Star ());proxy.sing("ABC" );
2.7.2.2. CGLIB 动态代理机制 JDK 动态代理有一个最致命的问题是其只能代理实现了接口的类
CGLIB (Code Generation Library )是一个基于ASM 的字节码生成库,它允许我们在运行时对字节码进行修改和动态生成。CGLIB 通过继承方式实现代理。很多知名的开源框架都使用到了CGLIB , 例如 Spring 中的 AOP 模块中:如果目标对象实现了接口,则默认采用 JDK 动态代理,否则采用 CGLIB 动态代理
在 CGLIB 动态代理机制中 MethodInterceptor
接口和 Enhancer
类是核心
自定义 MethodInterceptor
并重写 intercept
方法,intercept
用于拦截增强被代理类的方法
通过Enhancer
类来动态获取被代理类,当代理类调用方法的时候,实际调用的是 MethodInterceptor
中的 intercept
方法。
1 2 3 4 5 6 7 8 9 10 11 12 public interface MethodInterceptor extends Callback { public Object intercept (Object obj, java.lang.reflect.Method method, Object[] args, MethodProxy proxy) throws Throwable; }
CGLIB动态代理类使用步骤
定义一个类
自定义 MethodInterceptor
并重写 intercept
方法,intercept
用于拦截增强被代理类的方法,和 JDK 动态代理中的 invoke
方法类似
通过 Enhancer
类的 create()
创建代理类
代码示例
1 2 3 4 5 6 <dependency > <groupId > cglib</groupId > <artifactId > cglib</artifactId > <version > 3.3.0</version > </dependency >
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 class RealStar { public void sing (String name) { System.out.println(name); } } class myMethodInterceptor implements MethodInterceptor { @Override public Object intercept (Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("Before method " +method.getName()); Object obj = methodProxy.invokeSuper(o,objects); System.out.println("After method " +method.getName()); return obj; } } class CglibProxyFactory { public static Object getProxy (Class<?> clazz) { Enhancer enhancer = new Enhancer (); enhancer.setClassLoader(clazz.getClassLoader()); enhancer.setSuperclass(clazz); enhancer.setCallback(new myMethodInterceptor ()); return enhancer.create(); } } @Test void contextLoads () { RealStar star = (RealStar) CglibProxyFactory.getProxy(RealStar.class); star.sing("ABC" ); }
2.7.2.3. java动态代理 vs CGLIB 动态代理
JDK 动态代理只能代理实现了接口的类或者直接代理接口,而 CGLIB 可以代理未实现任何接口的类。 另外, CGLIB 动态代理是通过生成一个被代理类的子类来拦截被代理类的方法调用,因此不能代理声明为 final 类型的类和方法。
就二者的效率来说,大部分情况都是 JDK 动态代理更优秀,随着 JDK 版本的升级,这个优势更加明显。
2.7.3. 静态代理 vs 动态代理
灵活性 :动态代理更加灵活,不需要必须实现接口,可以直接代理实现类,并且可以不需要针对每个目标类都创建一个代理类。另外,静态代理中,接口一旦新增加方法,目标对象和代理对象都要进行修改,这是非常麻烦的
JVM 层面 :静态代理在编译时就将接口、实现类、代理类这些都变成了一个个实际的 class 文件。而动态代理是在运行时动态生成类字节码,并加载到 JVM 中的
3. 行为型模式 3.1. 模版方法模式 3.2. 命令模式 3.3. 迭代器模式 3.4. 观察者模式 3.5. 中介者模式 3.6. 备忘录模式 3.7. 解释器模式 3.8. 状态模式 3.9. 策略模式 3.10. 职责链模式 3.10.1. Leave 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package Chain;public class Leave { private String empName; private String reason; private int day; public Leave (String empName, String reason,int day) { super (); this .empName = empName; this .reason = reason; this .day=day; } public String getEmpName () { return empName; } public void setEmpName (String empName) { this .empName = empName; } public String getReason () { return reason; } public void setReason (String reason) { this .reason = reason; } public int getDay () { return day; } public void setDay (int day) { this .day = day; } }
3.10.2. Leader 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package Chain;public abstract class Leader { protected String name; protected Leader nextLeader; public Leader (String name) { super (); this .name = name; } public void setNextLeader (Leader nextLeader) { this .nextLeader = nextLeader; } public abstract void handleRequest (Leave leave) ; }
3.10.3. Manager 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package Chain;public class Manager extends Leader { public Manager (String name) { super (name); } @Override public void handleRequest (Leave leave) { if (leave.getDay()<3 ) { System.out.println(super .name+ "批准请假" ); }else { if (this .nextLeader!=null ) { this .nextLeader.handleRequest(leave); } } } }
3.10.4. Director 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package Chain;public class Director extends Leader { public Director (String name) { super (name); } @Override public void handleRequest (Leave leave) { if (leave.getDay()<10 ) { System.out.println(name+"批准" ); }else { this .nextLeader.handleRequest(leave); } } }
3.10.5. Client 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package Chain;public class Client { public static void main (String[] args) { Leader director = new Director ("主管" ); Leader manager = new Manager ("经理" ); manager.setNextLeader(director); Leave leave = new Leave ("员工" , "过年" , 2 ); manager.handleRequest(leave); Leave leave2 = new Leave ("员工" , "过年" , 5 ); manager.handleRequest(leave2); } }
3.11. 访问者模式