1 动态代理

代理是什么?

代理其实就是代为处理的意思,个人理解就是产生一个处理类对需要代理的对象进行处理,并且返回该代理对象

静态代理

首先实现一个Moveable接口,表示代理与被代理的对象都属于同一个类别

public interface Moveable {void move();void stop();
}

接下来实现一个被代理对象坦克类,有着坦克开始与结束的方法

public class Tank implements Moveable{@Overridepublic void move() {System.out.println("Tank moving 。。");try {Thread.sleep(new Random().nextInt(1000));} catch (InterruptedException e) {e.printStackTrace();}}@Overridepublic void stop() {System.out.println("Tank stop");}
}

接下来如果想要知道Tank的move方法允许了多久的话,最直接的就是使用继承方法,但是如果使用继承的话,想要再知道运行的日志的话就需要再继承扩展一个类,因此使用聚合来解耦合。

实现时间代理

public class TankTimeProxy implements Moveable{Moveable t;public TankTimeProxy(Moveable t) {super();this.t = t;}@Overridepublic void move() {Long start = System.currentTimeMillis();t.move();long end = System.currentTimeMillis();System.out.println(end-start);}@Overridepublic void stop() {Long start = System.currentTimeMillis();t.stop();long end = System.currentTimeMillis();System.out.println(end-start);}
}

实现日志代理

public class TankLogProxy implements Moveable{Moveable t;public TankLogProxy(Moveable t) {super();this.t = t;}@Overridepublic void move() {System.out.println("Tank start");t.move(); //这里调用的其实是Tank的方法long end = System.currentTimeMillis();System.out.println("Tank end");}@Overridepublic void stop() {}
}

调用地方的代码如下

 public static void main(String[] args) throws NoSuchMethodException, IOException, InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException {Tank t =new Tank();TankTimeProxy ttp =new TankTimeProxy(t);TankLogProxy tlp = new TankLogProxy(ttp);  //在时间代理上再加上日志代理
//        Moveable m = tlp;Moveable m = tlp;m.move();
}

打印数据的数据如下

Tank start
Tank moving 。。
861
Tank end

动态代理

(这里借用网上的例子,代码已经测过无误)
在完成了静态代理之后,我们需要考虑另外的问题,如果在我们需要计算的是除了move之外的其他方法的运行时间,那么岂不是又要生成一个代理类了?多个方法的话就是多个代理类,会导致类无限制扩展。因此就用到了动态代理

使用动态代理需要用到反射,反射是用于获取已创建实例的方法或者属性,并对其进行调用或者赋值。在这里我们可以动态一个代理对象,并且动态编译。然后,再通过反射创建对象并加载到内存中,就实现了对任意对象进行代理

第一步:定义自己的一个代理的逻辑处理接口,用来实现处理自定义逻辑

public interface InvocationHandler {void invoke(Object o, Method m) throws InvocationTargetException, IllegalAccessException;
}

第二步:定义一个运行时间处理器,用来处理代理对象,

public class TimeHandler implements InvocationHandler {//被代理的对象private Object target;public TimeHandler(Object target) {this.target = target;}public Object getTarget() {return target;}public void setTarget(Object target) {this.target = target;}// o 是代理对象@Overridepublic void invoke(Object o, Method m) throws InvocationTargetException, IllegalAccessException {long start = System.currentTimeMillis();System.out.println("starttiem: "+ start);m.invoke(target); //调用被代理对象原来的方法long end = System.currentTimeMillis();System.out.println("time: " + (end -start));}
}

第三步:编写动态代理的代码:

public class Proxy {/*** 动态代理* 产生新的代理类* infce 产生对应接口的代理   该接口对应的处理方法* @return*/public static Object newProxyInstance(Class infce, InvocationHandler h) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {String methodStr = "";Method[] methods = infce.getMethods();String rt = "\r\n";for(Method m : methods) { //动态代码 编译后动态生成一个对象,该对象包含着InvocationHandler,methodStr += "@Override" + rt +"public void " + m.getName() + "() {" + rt +"    try {" + rt +"    Method md = " + infce.getName() + ".class.getMethod(\"" + m.getName() + "\");" + rt +"    h.invoke(this, md);" + rt +  //传入的是this"    }catch(Exception e) {e.printStackTrace();}" + rt +"}";}String src ="package com.bjsxt.proxy;" +  rt +"import java.lang.reflect.Method;" + rt +"public class $Proxy1 implements " + infce.getName() + "{" + rt +"    public $Proxy1(InvocationHandler h) {" + rt +"        this.h = h;" + rt +"    }" + rt +"    com.bjsxt.proxy.InvocationHandler h;" + rt +methodStr +"}";String fileName ="d:/src/com/bjsxt/proxy/$Proxy1.java";File f = new File(fileName);FileWriter fw = new FileWriter(f);fw.write(src);//将要编译的代码写到文件中去fw.flush();fw.close();//编译TimeProxy源码JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);Iterable units = fileMgr.getJavaFileObjects(fileName);JavaCompiler.CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);t.call();fileMgr.close();//加载到内存中并创建对象URL[] urls = new URL[] {new URL("file:/" + "d:/src/")};URLClassLoader ul = new URLClassLoader(urls);Class c = ul.loadClass("com.bjsxt.proxy.$Proxy1");System.out.println(c);//传过来那个处理器就按照那个处理器去实现Constructor ctr = c.getConstructor(InvocationHandler.class);Object m = ctr.newInstance(h);//m.move();return m;}
}

第四步:调用:

public static void main(String[] args) throws Exception {Tank t = new Tank();InvocationHandler h = new TimeHandler(t);Moveable m = (Moveable)Proxy.newProxyInstance(Moveable.class, h);m.move();}

在这里Proxy.newProxyInstance(Moveable.class, h)生成的Proxy1代理类为:

class Prox1 implements Moveable {private InvocationHandler handler;public TimeProxy(InvocationHandler handler) {this.handler = handler;}@Overridepublic void move() {try {Method method = com.youngfeng.proxy.Flyable.class.getMethod("move");this.handler.invoke(this, method, null);} catch(Exception e) {e.printStackTrace();}}
}

方法调用链:Proxy1 . move() -> TimeHandler.invoke(Object o, Method m) -> Tank.move();

主要逻辑
  • Proxy->newProxyInstance(infs, handler) 用于生成代理对象
  • InvocationHandler:这个接口主要用于自定义代理逻辑处理
  • 为了完成对被代理对象的方法拦截,我们需要在InvocationHandler对象中传入被代理对象实例。

因此对其他对象进行代理就不再需要修改newProxyInstance方法中的代码

2 策略模式

策略模式主要用于不同的类根据不同的方法去解决,比如一只猫的属性有体重跟身高,实现按身高进行排序与按体重进行排序,即可使用策略模式

  • Comparable表明实现该接口的类必须实现compare方法,
  • Comparator则是比较器的具体实现
    第一步:定义一个实现了Comparable的Cat类
public class Cat implements Comparable{int Height;int weight;Comparator comparator;public int getHeight() {return Height;}public void setHeight(int height) {Height = height;}public int getWeight() {return weight;}public void setWeight(int weight) {this.weight = weight;}public Comparator getComparator() {return comparator;}public void setComparator(Comparator comparator) {this.comparator = comparator;}@Overridepublic int compareTo(Object o) {return comparator.compare(this, o);}
}

在这个类里面实现了一个继承器,传入自己实现的Comparator可以实现对身高和体重进行比较。
第二步:实现一个接口类使它的实现类确定实现了compareTo方法

public interface Comparable {int compareTo(Object o);
}

第三步:实现一个比较器的接口:

public interface Comparator {int compare(Object o1, Object o2);
}

第四步:继承Comparator接口实现身高比较器

public class CatHeightComparator implements Comparator{@Overridepublic int compare(Object o1, Object o2) {Cat c1 = (Cat)o1;Cat c2 = (Cat)o2;if (c1.getHeight() > c2.getHeight()) return 1;else if (c1.getHeight() > c2.getHeight()) return -1;return 0;}
}

策略模式其实就是需要变化的类其中聚合一个策略,根据需要传入不同的实现类实现不同的需要

3 状态模式

状态模式使用对象的形式来记录某种状态。使用状态模式可以省去多个if-else或者是switch的判断。可以直接使用对象方法的形式来处理逻辑。
例如在这里实现两个类Boy和MM类,其中MM中包含了抽象类State。代表了MM此时的心情

public class Boy {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}}
public class MM {private MMState state = new MMHappyState();private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public void smile(){state.smile();}public void cry(){state.cry();}public void say(){state.say();}
}

抽象类MyState

public abstract class MMState {public abstract void smile();public abstract void cry();public abstract void say();
}

代表MM好心情的MMHappyState

public class MMHappyState extends MMState{@Overridepublic void smile() {}@Overridepublic void cry() {}@Overridepublic void say() {}
}

因此当MM状态改变时,比如从开心的哭变成悲伤的哭只需要改变State即可,不需要修改其他代码。

4 工厂模式

抽象工厂

当需要新的工厂时直接继承VehicleFactory就可以
第一步:Moveable接口

public interface Moveable {void run();
}

所有的交通工具都实现了该接口
第二步:定义了汽车和飞机类

public class Plane implements Moveable{@Overridepublic void run() {System.out.println("plane");}
}public class Car implements Moveable{private static Car c = new Car();public void run(){System.out.println("run");}//静态工厂方法 用来产生car产品public static Car getInstance(){return c;}
}

第三步:实现一个工厂类,负责实现创建所有实例的内部逻辑。

public abstract class VehicleFactory {abstract Moveable create();
}

第四步: 实现工厂接口

public class PlaneFactory extends VehicleFactory{@OverrideMoveable create() {return new Plane();}
}public class CarFactory extends VehicleFactory{@OverrideMoveable create() {return new Car();}
}

在调用时需要那个类的工厂直接new它的工厂就行

public static void main(String[] args) {VehicleFactory factory = new PlaneFactory();Moveable m = factory.create();m.run();}

5 责任链模式

使多个对象都有处理请求的机会,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象串成一条链,并沿着这条链一直传递该请求,直到有对象处理它为止。

目标

用Filter模拟处理Request、Response

思路技巧

(1)Filter的doFilter方法改为doFilter(Request,Resopnse,FilterChain),有FilterChain引用,为利用FilterChain调用下一个Filter做准备
(2)FilterChain继承Filter,这样,FilterChain既是FilterChain又是Filter,那么FilterChain就可以调用Filter的方法doFilter(Request,Resopnse,FilterChain)
(3)FilterChain的doFilter(Request,Resopnse,FilterChain)中,有index标记了执行到第几个Filter,当所有Filter执行完后request处理后,就会return,以倒序继续执行response处理

代码如下:

Filter.java

public interface Filter {void doFilter (Request request, Response response,FilterChain filterChain);
}

HTMLFilter.java :替换HTML代码

public class HTMLFilter implements Filter {@Overridepublic void doFilter(Request request, Response response,FilterChain filterChain) {request.setRequestStr(request.getRequestStr().replace('<', '[').replace(">", "]")+"---HTMLFilter()");filterChain.doFilter(request, response, filterChain);response.setResponseStr(response.getResponseStr()+"---HTMLFilter()");}
}

3.SensitiveFilter.java 替换敏感词汇

public class SensitiveFilter implements Filter {@Overridepublic void doFilter(Request request, Response response,FilterChain filterChain) {request.setRequestStr(request.getRequestStr().replace("敏感", "幸福")+"---SensitiveFilter()");filterChain.doFilter(request, response, filterChain);response.setResponseStr(response.getResponseStr()+"---SensitiveFilter()");}}

4.FilterChian.java 过滤器链

public class FilterChain implements Filter {private List<Filter> filters = new ArrayList<Filter>();int index = 0;    //标记执行到第几个filter//把函数的返回值设为FilterChain,返回this,就能方便链式编写代码public FilterChain addFilter(Filter filter) {filters.add(filter);return this;}public void doFilter(Request request, Response response, FilterChain fc) {if(index == filters.size()) return ;Filter f = filters.get(index);index++;f.doFilter(request, response, fc);}
}

5.Request.java 和 Response.java

public class Request {private String requestStr;public String getRequestStr() {return requestStr;}public void setRequestStr(String requestStr) {this.requestStr = requestStr;}}public class Response {private String responseStr;public String getResponseStr() {return responseStr;}public void setResponseStr(String responseStr) {this.responseStr = responseStr;}}

6Test.java

public class Test {@org.junit.Testpublic void testFilter(){String msg = "<html>敏感字眼</html>"; Request request = new Request();request.setRequestStr(msg);Response response = new Response();response.setResponseStr("response------------");FilterChain fc = new FilterChain();fc.addFilter(new HTMLFilter()).addFilter(new SensitiveFilter());fc.doFilter(request, response, fc);System.out.println(request.getRequestStr());System.out.println(response.getResponseStr());}}

6 命令模式

命令也是类,将命令作为一个类来保存,当要使用的时候可以直接拿来使用

1.Client.java

public class Client {public void request(Server server){server.addCommand(new TextCommand());server.addCommand(new ImageCommand());server.doSomething();}}

2.Server.java

 public class Server {private List<Command> commands = new ArrayList<Command>();public void doSomething() {for(Command c : commands){c.execute();}}public void addCommand(Command command) {commands.add(command);}}

3.Command.java

public abstract class Command {public abstract void execute();public abstract void unDo();}

4.TextCommand.java

 public class TextCommand extends Command {@Overridepublic void execute() {System.out.println("TextCommand...........");}@Overridepublic void unDo() {// 涉及到操作的历史记录}}

5.ImageCommand.java

public class ImageCommand extends Command {@Overridepublic void execute() {System.out.println("ImageCommand...........");}@Overridepublic void unDo() {// 涉及到操作的历史记录}}

6.Test.java

public class Test {@org.junit.Testpublic void test(){Client c = new Client();c.request(new Server());}}

7 桥接模式

设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下两种设计方案:
• 第一种设计方案是为每一种形状都提供一套各种颜色的版本。

• 第二种设计方案是根据实际需要对形状和颜色进行组合。

模式定义
桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式

应用情况:(1)两个维度扩展(2)排列组合

1.Gift.java 礼物

public class Gift {GiftImpl impl;
}

2.GiftImpl.java 继承该类是具体物品


public class GiftImpl {}

3.WarmGift.java

public class WarmGift extends Gift {public WarmGift(GiftImpl giftImpl) {//调用父类的giftImplthis.giftImpl = giftImpl;}@Overridepublic String toString() {return this.getClass().getName()+"-----"+giftImpl.getClass().getName();}
}

4.WildGift.java

public class WildGift extends Gift {public WildGift(GiftImpl giftImpl) {//调用父类的giftImplthis.giftImpl = giftImpl;}@Overridepublic String toString() {return this.getClass().getName()+"-----"+giftImpl.getClass().getName();}
}

5.Flower.java

public class Folwer extends GiftImpl{}

6.Ring.java

public class Ring extends GiftImpl{}

7.MM.java

public class MM {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}}

8.Boy.java
pursue(MM mm)是送给女孩子礼物的方法 想要送不同的礼物修改gift = new WildGift(new Flower())即可

public class Boy {private String name;public void pursue(MM mm){Gift gift = new WildGift(new Flower());give(gift, mm);System.out.println(gift);}public void give(Gift gift, MM mm) {}
}

9.Test.java

public class Test {@org.junit.Testpublic void test() {Boy b = new Boy();b.pursue(new MM());}}

二十三种设计模式详解相关推荐

  1. 23 种设计模式详解

    转自原文 23 种设计模式详解(全23种) 设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种: 工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种: 适配 ...

  2. 二十三种设计模式-六大原则

    二十三种设计模式 一.创建型: 单例模式.工厂模式.抽象工厂模式.原型模式.建造者模式: 二.结构型: 代理模式,装饰器模式.适配器模式.外观模式.组合模式.享元模式.桥梁模式: 三.行为型: 策略模 ...

  3. Java二十三种设计模式 之代理(proxy)

    Java二十三种设计模式 之代理(proxy) 今天我们学习一下静态代理和动态代理 我们来看代码(写一个坦克运行了多少时间): 第一种方法: public calss Tank implements ...

  4. 二十三种设计模式(第十二种)-----代理模式(Proxy)

    二十三种设计模式(第十二种)-----代理模式(Proxy) 尚硅谷视频连接https://www.bilibili.com/video/BV1G4411c7N4?from=search&se ...

  5. 二十三种设计模式之原型模式

    今天继续探讨GOF二十三种设计模式的原型模式,原型模式也是属于创建型模式的一种 原型模式通俗的讲就是对象复制的过程,即通过一个原型对象,我可以得到一个该对象的克隆. 下面来看下原型模式的第一种写法-- ...

  6. 23种设计模式详解(代码讲解、持续更新)

    目录 设计模式分类 设计模式的六大原则 创建型模式 1.工厂方法模式(Factory Method) 2.建造者模式(Builder Pattern(常用.常见)) 行为型模式 模板模式(Templa ...

  7. 深入理解常见的二十三种设计模式

    深入理解常见的二十三种设计模式 文章目录 深入理解常见的二十三种设计模式 一.设计模式的分类 1.1 创建型(五种) 1.2 结构型(七种) 1.3 行为型(十一种) 二.创建型 2.1 单例模式 2 ...

  8. 第二部分:二十三种设计模式解读——什么是工厂方法模式

    二十三种设计模式解读--什么是工厂方法模式 author:陈镇坤27 日期:2022年2月10日 修改日期:2022年6月23日 文章目录 二十三种设计模式解读--什么是工厂方法模式 一.工厂方法模式 ...

  9. Java实现二十三种设计模式(五)—— 十一种行为型模式 (中)——解释器模式、迭代器模式、中介者模式、备忘录模式

    Java实现二十三种设计模式(五)-- 十一种行为型模式 (中)--解释器模式.迭代器模式.中介者模式.备忘录模式 一.解释器模式 我国 IT 界历来有一个汉语编程梦,虽然各方对于汉语编程争论不休,甚 ...

最新文章

  1. 常考数据结构与算法:合并k个已排序的链表
  2. Java 消息机制之回调详解
  3. Python urllib与requests、XML和HTMLParser
  4. node 16位 转24位_C代码实现16位和32位数据字节序转换
  5. ASP.NET生成静态页面方法大全(1)
  6. 下行文格式图片_收藏!公文写作格式大全(附示例图)
  7. LLVM 4中将加入新的LLVM链接器LLD
  8. jsp springmvc 视图解析器_SpringMVC 视图解析器
  9. OMP算法的物理意义表示
  10. 吐槽一下:武装GoldenDict时,好一个OALD,RAR格式,12万多的文件,晕!!
  11. python凹多边形分割_在Python中OpenCV多边形的凹凸角点
  12. 【论文解读】 FPGA实现卷积神经网络CNN(二): Optimizing FPGA-based Accelerator Design for DCNN
  13. aggr代码 cellranger_CellRanger初探
  14. Cura工程环境配置教程
  15. 9.5 隐函数求导法则
  16. SAP SHDB(BDC)心得
  17. VBA的参数传递:ByVal 和 ByRef 的区别
  18. MATLAB 函数大全
  19. SQL中的WHILE循环使用
  20. ”全球软件测试实践“问卷调查报告

热门文章

  1. HTML table 和 div
  2. 求1+2+…+n变态问题的两个很棒的解法
  3. 安装Sqlserver2008的问题
  4. 基于主机Overlay和自研虚拟化网关的VPC在360的落地
  5. 反思,今天总体感觉事情很简单,但项目比较多,没有掌握住很好的技巧,所以感觉很混乱
  6. 《Go 语言程序设计》读书笔记 (三) 方法
  7. Rand7()实现Rand10()
  8. @JsonFormat与@DateTimeFormat注解的使用
  9. 解决URI is not registered (Settings | Languages Frameworks | Schemas and DTDs)
  10. docker-compose搭建kafka集群