1 策略模式
优点:根据不同的路由选择不同执行方法或者调用时省去多个if判断,并且使代码有更好的扩展性 更高的可读性 不用修改之前的代码
缺点: 会出现多个冗余类 类会变多
示例: 将多个类放入到枚举类中保存 调用时通过spring上下文获取具体对象进行调用
package com.example.celue.celue;
public interface CarStract {
String carComment();
}
package com.example.celue.celue;
import org.springframework.stereotype.Component;
@Component
public class BmwCar implements CarStract {
@Override
public String carComment() {
return "宝马车";
}
}
package com.example.celue.celue;
import org.springframework.stereotype.Component;
@Component
public class DaZhong implements CarStract {
@Override
public String carComment() {
return "我是大众车";
}
}
package com.example.celue.celue;
import org.springframework.stereotype.Component;
@Component
public class ToyoCar implements CarStract {
@Override
public String carComment() {
return "丰田车";
}
}
package com.example.celue.Enu;
public enum FactoryEnu {
TOYO("toyoCar"),
BMWCar("bmwCar"),
dd("daZhong");
FactoryEnu(String beanName) {
this.beanName = beanName;
}
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
private String beanName;
}
package com.example.celue.factory;
import com.example.celue.celue.CarStract;
import com.example.zerenlian.IluoboDun;
import com.example.zerenlian.LanLuobo;
import com.example.zerenlian.LvLuobo;
import com.example.zerenlian.RedLuobo;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class Factory implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
//获取对象
public Object getBean(String beanName) {
return applicationContext.getBean(beanName);
}
}
package com.example.service;
import com.example.celue.Enu.FactoryEnu;
import com.example.celue.celue.CarStract;
import com.example.celue.factory.Factory;
import com.example.zerenlian.IluoboDun;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class CeLueService {
@Resource
private Factory factory;
public String testCelue(String type) {
CarStract bean = (CarStract) factory.getBean(FactoryEnu.valueOf(type).getBeanName());
return bean.carComment();
}
public void testZeRenLian() {
factory.getZerenLianBean().dun();
}
}
package com.example.controller;
import com.alibaba.fastjson.JSONObject;
import com.example.celue.shipeiqi.DbLogService;
import com.example.celue.shipeiqi.LogService;
import com.example.daili.*;
import com.example.guanchazhe.AobServer;
import com.example.guanchazhe.BobServer;
import com.example.guanchazhe.MyObServer;
import com.example.guanchazhe.springevent.MyMessageEvent;
import com.example.service.CeLueService;
import com.fasterxml.jackson.databind.util.JSONPObject;
import org.apache.tomcat.util.json.JSONParser;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
@RestController
public class Test {
@Resource
private ApplicationContext applicationContext;
@Resource
private CeLueService ceLueService;
@Resource
private LogService logService;
@Resource
private OrderService orderService;
@RequestMapping("testCelue")
public String testCeLue(String type) {
return ceLueService.testCelue(type);
}
@RequestMapping("testZeRenLian")
public String testZeRenLian() {
ceLueService.testZeRenLian();
return null;
}
@RequestMapping("testDaiLi")
public String testDaiLi() {
OrderService obj = new JdkInvocation<>(orderService).getProxy();
obj.order();
return null;
}
@RequestMapping("testDailiCglib")
public String testDailiCglib() {
CglibService proxy = (CglibService) new MethodInte<>(new CglibService()).getProxy();
proxy.test();
return null;
}
@RequestMapping("testGuanChaZhe")
public String testGuanChaZhe() {
MyObServer myObServer = new MyObServer();
//注册a观察者
new AobServer(myObServer);
//注册b观察者
new BobServer(myObServer);
myObServer.sendMessage("来了 ok 我觉得可以");
return null;
}
@RequestMapping("testGuanChaZheSpring")
public String testGuanChaZheSpring() {
HashMap<String, String> stringStringHashMap = new HashMap<>();
stringStringHashMap.put("message1", "发送消息1");
stringStringHashMap.put("message2", "发送消息2");
ApplicationEvent myMessageEvent = new MyMessageEvent(this, JSONObject.toJSONString(stringStringHashMap));
applicationContext.publishEvent(myMessageEvent);
return null;
}
@RequestMapping("testShiPeiqi")
public String testShiPeiqi() {
new DbLogService(logService).whriteLog();
return null;
}
}
2.代理模式
代理模式分为静态代理和动态代理
静态代理: 手动写每个类的代理类进行增强功能 很少用
动态代理:
jdk动态代理: 实现invocationhandler接口 重写方法实现 自动生成的代理类会自动实现我们的被代理类的接口 所以要求我们的被代理类必须要实现接口 没有接口会报错 使用反射和字节码技术生成代理类 生成的代理类会通过反射方法调用我们实现invocation接口的类
/**
* 生成代理类方法 传入类加载器,被代理类接口,实现invovationhandler接口的我们的代理类
* @return
*/
public T getProxy() {
return (T) Proxy.
newProxyInstance(Thread.currentThread().getContextClassLoader(), target.getClass().getInterfaces(), this);
}
cglib动态代理:实现methodIntercepter接口便可实现 不需要我们的被代理类实现接口 底层使用字节码技术生成代理类 生成的代理类会继承被代理类 所以被代理类不能是final 方法也不能有final
示例:
package com.example.daili;
public interface OrderService {
void order();
}
package com.example.daili;
import org.springframework.stereotype.Component;
@Component
public class OrderServiceImpl implements OrderService {
@Override
public void order() {
System.out.println("执行业务代码");
}
}
package com.example.daili;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkInvocation<T> implements InvocationHandler {
private T target;
public JdkInvocation(T target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("jdk动态代理");
return method.invoke(target, args);
}
/**
* 生成代理类方法 传入类加载器,被代理类接口,实现invovationhandler接口的我们的代理类
* @return
*/
public T getProxy() {
return (T) Proxy.
newProxyInstance(Thread.currentThread().getContextClassLoader(), target.getClass().getInterfaces(), this);
}
}
package com.example.daili;
public class CglibService {
public void test() {
System.out.println("执行测试方法 ");
}
}
package com.example.daili;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class MethodInte<T> implements MethodInterceptor {
private T target;
public MethodInte(T target) {
this.target = target;
}
/**
* cglib底层是继承了我们的被代理类 所以我们是用invokesuper方法 意思是直接执行父类的方法
*
* @param o 被代理类
* @param method 具体的执行方法
* @param objects 参数
* @param methodProxy 代理类执行方法
* @return 返回值
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("cglib");
return methodProxy.invokeSuper(o, objects);
}
public Object getProxy() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
}
@RequestMapping("testDaiLi")
public String testDaiLi() {
OrderService obj = new JdkInvocation<>(orderService).getProxy();
obj.order();
return null;
}
@RequestMapping("testDailiCglib")
public String testDailiCglib() {
CglibService proxy = (CglibService) new MethodInte<>(new CglibService()).getProxy();
proxy.test();
return null;
}
一般我们不会使用代理模式 使用springAOP会替换 AOP底层是代理实现 如果有顶层接口会走jdk动态代理 没有会走cglib
3 观察者模式
jdk有自带的观察者模式observer 我们一般不用 只讲spring封装的观察者模式
客户端会发送消息到主题中 服务端会从主题中接受到 并进行消费 也是简化版的rabbitMQ 项目不大可以替代mq
package com.example.guanchazhe;
import org.springframework.util.StringUtils;
import java.util.Observable;
/**
* 被观察者 只有setchange方法被调用才 发送消息 jdk自带的观察者模式
*/
public class MyObServer extends Observable {
public void sendMessage(String message) {
if (!StringUtils.isEmpty(message)) {
setChanged();
notifyObservers(message);
}
}
}
package com.example.guanchazhe;
import java.util.Observable;
import java.util.Observer;
public class BobServer implements Observer {
public BobServer(MyObServer myObServer) {
myObServer.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
System.out.println("观察者b接受到了消息" + arg.toString());
}
}
package com.example.guanchazhe;
import java.util.Observable;
import java.util.Observer;
public class AobServer implements Observer {
public AobServer(MyObServer myObServer) {
myObServer.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
System.out.println("观察者a接受到了消息" + arg.toString());
}
}
package com.example.guanchazhe.springevent;
import com.fasterxml.jackson.databind.util.JSONPObject;
import org.springframework.context.ApplicationEvent;
public class MyMessageEvent extends ApplicationEvent {
private String jsonpObject;
public MyMessageEvent(Object source, String jsonpObject) {
super(source);
this.jsonpObject = jsonpObject;
}
public String getJsonpObject() {
return jsonpObject;
}
public void setJsonpObject(String jsonpObject) {
this.jsonpObject = jsonpObject;
}
}
package com.example.guanchazhe.springevent;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
public class BobServer implements ApplicationListener<MyMessageEvent> {
@Override
@Async
public void onApplicationEvent(MyMessageEvent myMessageEvent) {
System.out.println(Thread.currentThread().getName() + myMessageEvent.getJsonpObject());
}
}
package com.example.guanchazhe.springevent;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
public class AobService implements ApplicationListener<MyMessageEvent> {
@Override
@Async
public void onApplicationEvent(MyMessageEvent myMessageEvent) {
String jsonpObject = myMessageEvent.getJsonpObject();
System.out.println(Thread.currentThread().getName() + jsonpObject);
}
}
@RequestMapping("testGuanChaZhe")
public String testGuanChaZhe() {
MyObServer myObServer = new MyObServer();
//注册a观察者
new AobServer(myObServer);
//注册b观察者
new BobServer(myObServer);
myObServer.sendMessage("来了 ok 我觉得可以");
return null;
}
@RequestMapping("testGuanChaZheSpring")
public String testGuanChaZheSpring() {
HashMap<String, String> stringStringHashMap = new HashMap<>();
stringStringHashMap.put("message1", "发送消息1");
stringStringHashMap.put("message2", "发送消息2");
ApplicationEvent myMessageEvent = new MyMessageEvent(this, JSONObject.toJSONString(stringStringHashMap));
applicationContext.publishEvent(myMessageEvent);
return null;
}
4 门面模式
就是将复杂的业务代码封装到一个类中统一调用 使使用者用起来很简单
5 适配器模式
通过适配器类去将原本不能直接调用的方法或接口变得可用 也可以扩展功能 类似苹果转接口功能
具体用法有继承原类的叫做类适配器 有在类中引用的叫做组装适配器
package com.example.celue.shipeiqi;
public interface LogService {
void whriteLog();
}
package com.example.celue.shipeiqi;
import org.springframework.stereotype.Component;
@Component
public class LogServiceImpl implements LogService {
@Override
public void whriteLog() {
System.out.println("打印日志");
}
}
package com.example.celue.shipeiqi;
public class DbLogService implements LogService{
private LogService logService;
public DbLogService(LogService logService) {
this.logService = logService;
}
@Override
public void whriteLog() {
logService.whriteLog();
System.out.println("兼容适配 扩展写入数据库功能业务");
}
}
@RequestMapping("testShiPeiqi")
public String testShiPeiqi() {
new DbLogService(logService).whriteLog();
return null;
}
6责任链模式
工作流实现---- 功能1结束之后功能2才能开始以此类推 场景类似层层审批
package com.example.zerenlian;
/**
* 责任链模式实现的抽象类 定义同意的行为 内置一个下一个实现的行为nextDun 封装在抽象类中调用
*/
public abstract class IluoboDun {
public IluoboDun() {
}
private IluoboDun iluoboDun;
public IluoboDun(IluoboDun iluoboDun) {
this.iluoboDun = iluoboDun;
}
public abstract void dun();
protected void nextDun() {
if (iluoboDun != null) {
this.iluoboDun.dun();
}
}
}
package com.example.zerenlian;
public class LanLuobo extends IluoboDun {
public LanLuobo() {
}
public LanLuobo(IluoboDun iluoboDun) {
super(iluoboDun);
}
@Override
public void dun() {
System.out.println("蓝萝卜蹲 蓝萝卜蹲 蓝萝卜蹲完绿萝卜蹲");
nextDun();
}
}
package com.example.zerenlian;
public class LvLuobo extends IluoboDun {
@Override
public void dun() {
System.out.println("绿萝卜蹲 绿萝卜蹲 蹲蹲蹲");
nextDun();
}
}
package com.example.zerenlian;
public class RedLuobo extends IluoboDun {
public RedLuobo(IluoboDun iluoboDun) {
super(iluoboDun);
}
@Override
public void dun() {
System.out.println("红萝卜蹲 红萝卜蹲 红萝卜蹲完蓝萝卜蹲");
nextDun();
}
}
package com.example.celue.factory;
import com.example.celue.celue.CarStract;
import com.example.zerenlian.IluoboDun;
import com.example.zerenlian.LanLuobo;
import com.example.zerenlian.LvLuobo;
import com.example.zerenlian.RedLuobo;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class Factory implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public Object getBean(String beanName) {
return applicationContext.getBean(beanName);
}
public IluoboDun getZerenLianBean() {
return new RedLuobo(new LanLuobo(new LvLuobo()));
}
}
@RequestMapping("testZeRenLian")
public String testZeRenLian() {
ceLueService.testZeRenLian();
return null;
}
7装饰者模式
动态扩展被装饰类的功能 是继承的一种替代
package com.example.zhuangshizhe;
/**
* 装饰者接口
*/
public interface AnimalZhuang {
void todo();
}
package com.example.zhuangshizhe;
import org.springframework.stereotype.Component;
/**
* 被装饰者
*/
@Component
public class Dog implements AnimalZhuang {
@Override
public void todo() {
System.out.println("我是狗我会汪汪汪");
}
}
package com.example.zhuangshizhe;
/**
* 装饰类构件角色
*/
public class DogZhuang implements AnimalZhuang {
/**
* 一个具体的引用
*/
private AnimalZhuang animalZhuang;
public DogZhuang(AnimalZhuang animalZhuang) {
this.animalZhuang = animalZhuang;
}
@Override
public void todo() {
//调用被装饰者的行为
animalZhuang.todo();
}
}
package com.example.zhuangshizhe;
/**
* 具体的装饰角色
*/
public class DogZhuangImpl extends DogZhuang {
public DogZhuangImpl(AnimalZhuang animalZhuang) {
super(animalZhuang);
}
@Override
public void todo() {
super.todo();
todos();
}
private void todos() {
System.out.println("增加附加功能 我是狗我会叫我还会咬人呢");
}
}
@RequestMapping("testZhuang")
public String testZhuang() {
dog.todo();
AnimalZhuang dogZhuang = new DogZhuangImpl(dog);
dogZhuang.todo();
return null;
}