工作中我们会用到设计模式来帮助我们更好的写代码,下面就慢慢的记录我使用到的吧
1、单例模式
在这里我用链接温湿度传感器为例,使用socket链接的
import java.net.Socket;
/**
* socket链接
* @author ljw
*
*/
public class SingtonSocket {
//加上volatile 防止new 对象的时候发生重排序,导致其他线程拿到的对象不完整
private static volatile Socket client = null;
public static Socket getInstance(String ip,Integer port) {
if(client==null) {
synchronized(SingtonSocket.class) {
if (client == null) {
try {
client = new Socket(ip, port);
} catch (Exception e) {
}
}
}
}
return client;
}
}
使用:Socket clientSocket = SingtonSocket.getInstance(hardRecord.getIp(), hardRecord.getPort())
2、策略模式
之前代码是这样的
现在是这样的了
List<?> strategy = strategyUseService.resolveStrategy(params.getMenuId()+"");
List<?> list = resultDataList(strategy, collect);
第一步定义一个策略接口
import java.util.List;
public interface ExpireStrategy {
String strategy();
List<?> getExpireData();
}
贴两个策略的实现类
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.system.service.ImportantService;
@Component
public class ImportantStrategy implements ExpireStrategy{
@Autowired
ImportantService importantService;
@Override
public String strategy() {
return "2015";
}
@Override
public List<?> getExpireData() {
return importantService.getExpireData();
}
}
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.system.service.LibraryService;
@Component
public class LibraryStrategy implements ExpireStrategy{
@Autowired
LibraryService libraryService;
@Override
public String strategy() {
return "2014";
}
@Override
public List<?> getExpireData() {
return libraryService.getExpireData();
}
}
重点在这
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class StrategyUseService implements ApplicationContextAware{
private Map<String, ExpireStrategy> strategyMap = new ConcurrentHashMap<>();
public List<?> resolveStrategy(String menuId) {
ExpireStrategy expireStrategy = strategyMap.get(menuId);
if (expireStrategy != null) {
return expireStrategy.getExpireData();
}else {
return new ArrayList<>();
}
}
//把不同策略放到map
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, ExpireStrategy> tmepMap = applicationContext.getBeansOfType(ExpireStrategy.class);
tmepMap.values().forEach(strategyService -> strategyMap.put(strategyService.strategy(), strategyService));
}
}
使用
@Autowired
StrategyUseService strategyUseService;
List<?> strategy = strategyUseService.resolveStrategy(params.getMenuId()+"");
List<?> list = resultDataList(strategy, collect);
3、模板设计模式
我们以支付为例子,支付可以选择微信、支付宝、银联、建行支付等各种方式,支付结果一般都会有一个异步通知过程、假如我们使用if else是不是显得太low ,假设按照我们的异步回调过程大致分为三个步骤1、日志记录 2、发送消息通知 3、签名验证 4、返回结果。像1和2步骤是通用的,可以交给父类去实现,例如验签和返回结果,每个支付方式都是自己的方式,所以可以将具体实现交给子类去处理。这里为了方便我也使用了策略模式。首先定给看下演示效果1代表支付宝支付2代表微信支付
首先定义一个模板抽象类
import lombok.extern.slf4j.Slf4j;
@Slf4j
public abstract class AbstractPayTemplate {
abstract String type();
public String getResult(){
addLog();
boolean b = verifySignature();
String result = getMsg(b);
log.info("返回结果:{}",result);
return result;
}
//记录日志
public void addLog(){
log.info("我在这里记录了日志*********");
}
//验证签名
public abstract boolean verifySignature();
//返回结果
public abstract String getMsg(boolean b);
}
支付宝的实现方式
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class AliPayTemplate extends AbstractPayTemplate {
@Override
String type() {
return "1";
}
@Override
public boolean verifySignature() {
log.info("支付宝验证签名成功");
return true;
}
@Override
public String getMsg(boolean b) {
if(b){
return "success";
}
return "fail";
}
}
微信的实现方式
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class WeChatTemplate extends AbstractPayTemplate {
@Override
String type() {
return "2";
}
@Override
public boolean verifySignature() {
log.info("微信验证签名成功");
return true;
}
@Override
public String getMsg(boolean b) {
if(b){
return "ok";
}
return "error";
}
}
策略模式代码
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class StrategyPayService implements ApplicationContextAware {
private Map<String, AbstractPayTemplate> strategyMap = new ConcurrentHashMap<>();
public String resolveStrategy(String type) {
AbstractPayTemplate expireStrategy = strategyMap.get(type);
if (expireStrategy != null) {
return expireStrategy.getResult();
}
return null;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, AbstractPayTemplate> tmepMap = applicationContext.getBeansOfType(AbstractPayTemplate.class);
tmepMap.values().forEach(strategyService -> strategyMap.put(strategyService.type(), strategyService));
System.out.println(strategyMap);
}
}
调用实现
@Autowired
StrategyPayService strategyPayService;
@GetMapping("/asyncCallBack")
@ResponseBody
public String payResult(String type){
String result = strategyPayService.resolveStrategy(type);
return result;
}
有没有感觉很nice
4、Jdk动态代理
以前我们调用方法都这样调用,接下来使用动态代理,为什么要使用代理呢,能在方法执行前后搞点操作,接下来就用jdk动态代理实现方法的调用。
定义一个接口
public interface UserService {
public String sayHello(String str);
public String sayYes();
}
接口实现类
public class UserServiceImpl implements UserService {
@Override
public String sayHello(String str) {
return "你好啊:"+str;
}
@Override
public String sayYes() {
return "Yes!";
}
}
使用
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
String tom = userService.sayHello("tom");
String s = userService.sayYes();
}
新建代理类,实现InvocationHandler
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class UserProxy implements InvocationHandler {
private Object target;
public Object newProxyInstance(Object target){
//传入被代理的目标
this.target = target;
//返回代理对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//method被代理的方法 args 参数
System.out.println("方法执行前**************"+method.getName());
Object invoke = method.invoke(target, args);
System.out.println(invoke);
System.out.println("方法执行后**************"+invoke);
return invoke;
}
}
使用
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserProxy userProxy = new UserProxy();
UserService userService1 = (UserService)userProxy.newProxyInstance(userService);
userService1.sayYes();
userService1.sayHello("Tom");
}
jdk动态代理实现微服务调用。我们之前使用服务之间的调用都是通过openfeign完成,这次我们使用jdk动态代理简单模拟实现一下。
1、先修改我们的feign接口,使用自定义注解
//@FeignClient("mayikt-order")
@MyFeignClient("mayikt-order")
public interface OrderFeign extends OrderApi {
}
2、自定义注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyFeignClient {
String value() default "";
}
3、创建代理类
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.client.RestTemplate;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
@Component
@Slf4j
public class FeignClientProxy {
@Autowired
private RestTemplate restTemplate;
public <T> T create(Class<T> tClass) {
return (T) Proxy.newProxyInstance(tClass.getClassLoader(), new Class<?>[]{tClass}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 1.判断接口上是否有加上MyFeignClient
MyFeignClient mayiktFeignClient = tClass.getDeclaredAnnotation(MyFeignClient.class);
if (mayiktFeignClient == null) {
throw new Exception("FeignClient is null");
}
// 2.获取服务的名称
String serviceName = mayiktFeignClient.value();
if (StringUtils.isEmpty(serviceName)) {
throw new Exception("serviceName is null");
}
// 3.接口地址如何获取?
GetMapping getMapping = method.getDeclaredAnnotation(GetMapping.class);
if (getMapping == null) {
throw new Exception("getMapping is null");
}
String[] requestName = getMapping.value();
// 3.使用restTemplate发送请求
String requestUrl = "http://" + serviceName + requestName[0];
log.info("<requestUrl:{}>", requestUrl);
//发起调用
ResponseEntity<?> result = restTemplate.getForEntity(requestUrl, method.getReturnType());
return result.getBody();
}
});
}
}
4、使用
@RestController
public class MemberService {
//@Autowired
// OrderFeign orderFeign;
@Autowired
FeignClientProxy feignClientProxy;
@GetMapping("/getMember")
public String getMember(){
//String orderMsg = orderFeign.getOrderMsg();
OrderFeign orderFeign = feignClientProxy.create(OrderFeign.class);
String orderMsg = orderFeign.getOrderMsg();
System.out.println("订单服务结果-》"+orderMsg);
return "获取到会员服务";
}
}
5、测试结果
5、cglib动态代理
被代理类
public class HelloService {
public void sayHello() {
System.out.println("Hello Wordl!");
}
}
代理类
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 CglibProxy implements MethodInterceptor {
private Object target;
public CglibProxy(Object target) {
this.target = target;
}
public Object newProxyInstance(){
Enhancer en = new Enhancer();
en.setSuperclass(target.getClass());
en.setCallback(this);
return en.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("方法执行之前");
Object returnValue = method.invoke(target, args);
System.out.println("方法执行之后");
return returnValue;
}
}
public static void main(String[] args) {
HelloService helloService = (HelloService) new CglibProxy(new HelloService()).newProxyInstance();
helloService.sayHello();
}
6、装饰者模式
7、观察者模式
个人理解,观察者模式,一个人在看着你,你要是有个动静,他就会跟着响应。
先定于一个抽象观察者
public interface Observer {
void action(String message);
}
具体观察者
public class TeacherObsever implements Observer {
private String msg;
public TeacherObsever(String msg){
this.msg = msg;
}
@Override
public void action(String message) {
System.out.println(msg+message);
}
}
定义一个抽象类或者接口的主题
/**
* 抽象或者接口主题
*/
public interface Subject {
void add(Observer observer);
void notify(String msg);
}
具体主题行为
public class StudentObsever implements Observer {
private String msg;
StudentObsever(String msg){
this.msg=msg;
}
@Override
public void action(String message) {
System.out.println(msg+message);
}
}
测试
public static void main(String[] args) {
Subject subject = new MySubject();
subject.add(new TeacherObsever("教师"));
subject.add(new StudentObsever("学生"));
subject.notify("6666");
}