提示:以下是本篇文章正文内容,下面案例可供参考
一、代理模式
1、概念
为其他东西提供代理以控制对对象的访问 , 相对于一个中介
在有的时候一个对象不能或者不适合直接引另一个对象,而代理对象就可以成为中介的桥梁作用
2、特点
-
特征是代理类与委托类有同样的接口(有特别情况不一定),代理负责为委托类预处理信息过滤信息,把信息转发给委托类,以及处理信息等
-
代理类对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来通过特定的服务。
3、实现
- 静态代理
银行雇员代理客户执行相关银行服务
/**
* @author zhangyifan
* @version 8.0
* @description:委托类和代理类拥有的共同接口
* @date 2021/12/3 9:58
*/
public interface Account {
/**
*y银行
*/
void query();
void cueng();
}
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/12/3 9:58
*/
public class Client implements Account {
@Override
public void query() {
System.out.println("XXX 取了多少钱");
}
@Override
public void cueng() {
System.out.println(" 查");
}
}
/**
* @author zhangyifan
* @version 8.0
* @description: 代理 银行顾元
* @date 2021/12/3 9:59
*/
public class Employee implements Account{
//委托
private Client client;
public Employee(Client client) {
this.client = client;
}
/**
* 通过构造 或者set 方法给 赋值
*/
@Override
public void query() {
System.out.println("取钱钱干什么");
client.query();
System.out.println("取钱后干什么");
}
@Override
public void cueng( ) {
System.out.println("查询余额做什么准备");
client.cueng( );
System.out.println("查询后做什么工作");
}
}
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/12/3 14:32
*/
public class Testa {
public static void main(String[] args) {
Client client=new Client();
Employee employee=new Employee(client);
employee.cueng( );
employee.query();
}
}
- jdk动态代理
java.lang.reflect包下提共了一个Proxy类和一个invocationhandler接口 用来完成动态代理
Invocationhandler接口:
当我们通过代理对象调用一个方法时,这个方法的调用就会被转发为由Invocationhandler这个接口的invoke方法进行调用。
Object invoke(Object proxy,Method method ,Object[] args)
参数:Object proxy:指被代理的对象
Method method: 要调用的方法
Object[] args: 方法调用时所需的参数
Proxy类 :该类提供了一个创建动态代理对象的方法。
static Object newProxyInstance(ClassLoader loader,Class《?》【】 interface,Invocationhandler h)
ClassLoader loader:定义代理类的类加载器
Class《?》【】interface : 代理类要实现的接口列表
invocationHandler h:指派方法调用的调用处理程序 表示代理对象要关联的 invocationHandler对象。
/**
* @author zhangyifan
* @version 8.0
* @description: JDK代理 可以代理任意委托类
* @date 2021/12/3 10:42
*/
public class JDKProxy implements InvocationHandler {
/**
* 委托类
*/
private Object obj;
/**
* 给委托类赋值,返回代理类对象
* @param obj
* @return
*/
public Object bindObj(Object obj){
this.obj=obj;
//获取委托类的所有接口 通过方式
Class<?>[] interfaces = this.obj.getClass().getInterfaces();
//参数1 类加载器 参数2、
return Proxy.newProxyInstance(
JDKProxy.class.getClassLoader()
,interfaces
,this);
}
/**
*
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result=null;
String name=method.getName();
System.out.println("方法名称为:"+name);
/* if ("query".equals(name)){
System.out.println("存取前做什么准备。。。。。。");
result = method.invoke(this.obj,args);
System.out.println("存取后做什么工作。。。。。。");
}else if ("cueng".equals(name)){
System.out.println("查询前");
result = method.invoke(this.obj,args);
System.out.println("查询后");
}*/
System.out.println("前干什么");
result =method.invoke(this.obj,args);
System.out.println("后干什么");
return result;
}
}
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/12/3 15:22
*/
public interface DeptService {
/**
* 修改
* @param o
* @return
*/
int update(Object o);
/**
* 添加
* @param o
* @return
*/
int add(Object o);
/**
* 删除
* @param id
* @return
*/
int deleteById(int id);
/**
* 分页带参数查询
* @param str
* @return
*/
List<Object> queryAll(String ...str);
}
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/12/3 15:23
*/
public class DeptServiceImpl implements DeptService{
@Override
public int update(Object o) {
System.out.println("...............模拟更新。。。。。。。。。。。。。。。。。");
return 0;
}
@Override
public int add(Object o) {
System.out.println("...............模拟添加。。。。。。。。。。。。。。。。。");
return 0;
}
@Override
public int deleteById(int id) {
System.out.println("...............模拟删除。。。。。。。。。。。。。。。。。");
return 0;
}
@Override
public List<Object> queryAll(String... str) {
System.out.println("...............模拟查询。。。。。。。。。。。。。。。。。");
return null;
}
}
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/12/3 15:39
*/
public class TestA {
public static void main(String[] args) {
DeptService deptService=new DeptServiceImpl();
JDKProxy jdkProxy=new JDKProxy();
DeptService deptService1 = (DeptService) jdkProxy.bindObj(deptService);
deptService1.add(1);
deptService1.update(1);
deptService1.deleteById(1);
deptService1.queryAll();
}
}
- CGLIB(Code Generation Library) 动态代理
主要应用于没有接口的动态代理生成(主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的),Spring AOP 框架 ,HIbernate都使用了CGLLIB。
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/12/3 16:56
*/
public class DeptServiceImpl implements DeptService {
public final int update(Object o) {
System.out.println("................模拟更新。。。");
return 0;
}
public int add(Object o) {
System.out.println("................模拟添加。。。");
return 0;
}
public int deleteById(int id) {
System.out.println("................模拟删除。。。");
return 0;
}
public List<Object> queryAll(String... str) {
System.out.println("................模拟查询。。。");
return null;
}
}
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/12/3 16:56
*/
public class CGLbProxy implements MethodInterceptor {
//委托
private Object obj;
public Object binObj(Object obj){
this.obj=obj;
Enhancer enhancer=new Enhancer();
//设置生成代理类的付类
enhancer.setSuperclass(this.obj.getClass());
//生成委托类的子类后 用Callback调用子类的所有方法
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Object result=null;
System.out.println("事情前");
result=methodProxy.invoke(this.obj,objects);
System.out.println("事情后");
return null;
}
}
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/12/3 16:57
*/
public class Test {
public static void main(String[] args) {
DeptService deptService=new DeptServiceImpl();//实例
CGLbProxy cgLbProxy=new CGLbProxy();//委托
DeptService deptService1 = (DeptService) cgLbProxy.binObj(deptService);
deptService.deleteById(1);
System.out.println("==================");
deptService1.deleteById(1);
}
}
二、观察者模式(Observer Pattern)
1.定义
观察者模式是软件设计模式的一种。它定义了一种一对多的依赖关系,让多个观察者对象同时监听听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。在观察者模式中,监视另一个对象状态的对象称为Observer,正在被监视的对象称为Subject。
2.现实例子
例如,某种商品的物价上涨时会导致部分商家高兴,而消费者伤心;还有,当我们开车到交叉路口时,遇到红灯会停,遇到绿灯会行。这样的例子还有很多,例如,股票价格与股民、微信公众号与微信用户、气象局的天气预报与听众、小偷与警察等
3.角色
- 抽象主题(Subject)
它把所有观察者对象的引用保存到一个集合里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。 - 具体主题(Concrete Subject)
将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。 - 抽象观察者(Observer)
为所有的具体观察者定义一个接口,在得到主题通知时更新自己。 - 具体观察者(Concrete Observer)
实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
被观察者接口
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/12/3 11:43
*/
public interface Subject {
/**
* 注册观察z
*/
void registerObservier(ObServer obServer);
/**
* 移除
* @param obServer
*/
void removeObserver(ObServer obServer);
/**
* * 通知所有观察者
* @param message
* */
void notifyObserver(String message);
}
被观察者实现
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/12/3 11:45
*/
public class ConcreteSubject implements Subject{
//观察者集合
private List<ObServer> obServers=new ArrayList<>();
@Override
public void registerObservier(ObServer obServer) {
obServers.add(obServer);
}
@Override
public void removeObserver(ObServer obServer) {
obServers.remove(obServer);
}
@Override
public void notifyObserver(String message) {
if (obServers!=null&&obServers.size()>0){
for (ObServer observer:obServers){
observer.update(message);
}
}
}
}
观察者:
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/12/3 11:44
*/
public interface ObServer {
/**根据主题变化,观察者也发生变化
*
* @param message
*/
void update(String message);
}
观察者实现
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/12/3 18:51
*/
public class ConcreteObserver implements ObServer {
//观察者
private String obName;
public ConcreteObserver(String obName){
this.obName=obName;
}
@Override
public void update(String message) {
System.out.println("观察者"+obName+"根据"+message+"变化,自己做了什么什么调整。。。。");
}
}
测试
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/12/3 18:54
*/
public class Test {
public static void main(String[] args) {
//实例化 OB
ObServer obServer1=new ConcreteObserver("ob1");
ObServer obServer2=new ConcreteObserver("ob2");
ObServer obServer3=new ConcreteObserver("ob3");
ObServer obServer4=new ConcreteObserver("ob4");
//实例化
Subject subject=new ConcreteSubject();
subject.registerObservier(obServer1);
subject.registerObservier(obServer2);
subject.registerObservier(obServer3);
subject.registerObservier(obServer4);
//主题变化
subject.notifyObserver("变黄了");
System.out.println("-----------------------------");
//移除
subject.removeObserver(obServer1);//移除
subject.notifyObserver("变红了");
/* org.example.dp.observer.Test
观察者ob1根据变黄了变化,自己做了什么什么调整。。。。
观察者ob2根据变黄了变化,自己做了什么什么调整。。。。
观察者ob3根据变黄了变化,自己做了什么什么调整。。。。
观察者ob4根据变黄了变化,自己做了什么什么调整。。。。
-----------------------------
观察者ob2根据变红了变化,自己做了什么什么调整。。。。
观察者ob3根据变红了变化,自己做了什么什么调整。。。。
观察者ob4根据变红了变化,自己做了什么什么调整。。。。*/
}
}
4、好处
观察者模式将观察者和主题(被观察者)彻底解耦,主题只知道观察者实现了某一接口(也就是Observer接口)。并不需要观察者的具体类是谁、做了些什么或者其他任何细节。任何时候我们都可以增加新的观察者。因为主题唯一依赖的东西是一个实现了Observer接口的对象列表。