-
对接口编程:接口和抽象类
2014-05-16 09:40:10在《大话设计模式》这本书中,我会听到这个字眼“对接口编程”,而在文中的类图中,会提出这样一个疑问?为什么有的用的是:接口?有的用的是抽象类呢? 本文主要介绍以下内容:接口、抽象类。 文章的最后,会给出...在《大话设计模式》这本书中,我会听到这个字眼“对接口编程”,而在文中的类图中,会提出这样一个疑问?为什么有的用的是:接口?有的用的是抽象类呢?
本文主要介绍以下内容:接口、抽象类。
文章的最后,会给出软考下午设计模式题中的一些做题技巧
• 什么是接口?
接口是包含一组虚方法的抽象类型,其中每一种方法都有其名称、参数和返回值。接口方法不能包含任何实现,CLR 允许接口可以包含事件、属性、索引器、静态方法、静态字段、静态构造函数以及常数。
注意:一个类可以实现多个接口,当一个类继承某个接口时,它不仅要实现该接口定义的所有方法,还要实现该接口从其他接口中继承的所有方法。• 什么是抽象类?
抽象类提供多个派生类共享基类的公共定义,它既可以提供抽象方法,也可以提供非抽象方法。抽象类不能实例化,必须通过继承由派生类实现其抽象方法,因此对抽象类不能使用new 关键字,也不能被密封。如果派生类没有实现所有的抽象方法,则该派生类也必须声明为抽象类。• 对比分析
• 考试秘籍
下面从软考设计模式的做题技巧入手,提供一些参考:(以Java语言为例)
抽象类用关键字abstract声明,用extends继承。抽象类的目的是定义一个框架,规定某些类必须具有的一些共性。抽象方法:没有函数体的方法
注意:包含抽象方法的类,一定是抽象类。
抽象类的直接派生类必须实现其抽象方法,抽象类只能用于继承,不能用于创建对象(所谓的new)。
接口用关键字interface声明,关键字implements实现。接口用于替代多继承的概念。
注意:直接继承了接口的类,必须实现接口中的抽象方法;间接的则可以实现,也可以不实现。
区分:
1、接口和抽象类都不能创建对象。
2、抽象类不能参与多继承,抽象类可以有非静态的成员变量,可以有非抽象的方法;
3、接口可以参与多继承,所有的属性都是静态常量,所有的方法都是public方法。
• 结论
本文基本概况了接口和抽象类的概念、异同和使用规则。但是,对于面向对象和软件设计的深入理解,还是建立在不断实践的基础上。 -
通过AOP切入注解的方式对接口参数进行非空判断
2018-11-07 15:38:47文章目录通过AOP切入注解的方式对接口参数进行非空判断1、创建注解2、创建切入点3、应用注解4、注解响应 通过AOP切入注解的方式对接口参数进行非空判断 1、创建注解 package ...通过AOP切入注解的方式对接口参数进行非空判断
1、创建注解
package com.zyfycs.college.core.aop.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author Created by 谭健 on 2018/11/2 0002. 星期五. 9:47. * © All Rights Reserved. */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface HandleParams { /** * 不需要检验的参数的名称 * 默认情况下,会检查该接口的所有参数值 */ String[] excludeParams() default {}; /** * notNull * notBlank * 两个只会处理一个,notBlank 的优先级更高, * 如果notBlank 为 true 则不进行 notNull 逻辑处理,因为 notNull 是 notBlank 的子内容 * 如果只使用 notNull 判断,则应该设置 notBlank 为 false ,notNull 为true */ boolean notNull() default false; boolean notBlank() default true; }
2、创建切入点
package com.zyfycs.college.core.aop; import com.google.common.collect.Lists; import com.zyfycs.college.core.aop.annotation.HandleParams; import com.zyfycs.college.exception.runtime.ParamBlankException; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; /** * @author Created by 谭健 on 2018/11/2 0002. 星期五. 9:45. * © All Rights Reserved. */ @Slf4j @Component @Aspect public class AspectParamCheck { @Around("@annotation(com.zyfycs.college.core.aop.annotation.HandleParams)") public Object paramCheck(ProceedingJoinPoint point) throws Throwable { MethodSignature signature = (MethodSignature) point.getSignature(); String[] parameterNames = signature.getParameterNames(); Object[] args = point.getArgs(); Class<?>[] parameterTypes = signature.getParameterTypes(); HandleParams handleParams = signature.getMethod().getAnnotation(HandleParams.class); String[] excludeParams = handleParams.excludeParams(); List<String> excludeParamList = Lists.newArrayList(excludeParams); String location = point.getTarget().toString() + "." + signature.getMethod().getName(); for (int i = 0; i < args.length; i++) { if (handleParams.notBlank()) { notBlank(location, excludeParamList, parameterNames[i], args[i], parameterTypes[i].getName()); } else if (handleParams.notNull()) { notNull(location, excludeParamList, parameterNames[i], args[i], parameterTypes[i].getName()); } } return point.proceed(); } private void notNull(String location, List<String> excludeParamList, String paramName, Object value, String paramType) { // 如果该参数不在排除范围内,则进行校验 if (!excludeParamList.contains(paramName)) { if (value == null) { throw new ParamBlankException(location + " Error : [" + paramName + "] is Null ,Type is [" + paramType + "]"); } } } private void notBlank(String location, List<String> excludeParamList, String paramName, Object value, String paramType) { // 如果该参数不在排除范围内,则进行校验 if (!excludeParamList.contains(paramName)) { if (value == null || StringUtils.isBlank(value.toString())) { throw new ParamBlankException(location + " Error : [" + paramName + "] is Blank ,Type is [" + paramType + "]"); } } } }
3、应用注解
只需要在有参数并且需要做非空判断的接口方法上打上 @HandleParams 注解就会自动检查了
@HandleParams @GetMapping("/request") public ApiResponse request(BigDecimal amount, Long bankCardId,String authCode,String code) {}
4、注解响应
当注解工作后,会抛出ParamBlankException 异常
package com.zyfycs.college.exception.runtime; import lombok.Getter; /** * @author Created by 谭健 on 2018/11/2 0002. 星期五. 10:02. * © All Rights Reserved. */ @Getter public class ParamBlankException extends RuntimeException { public ParamBlankException() { } public ParamBlankException(String message) { super(message); } }
异常抛出后,由全局异常处理器处理,通过Rest 方式返回给前端
并且在控制台打印具体的错误信息@ExceptionHandler(ParamBlankException.class) @ResponseBody public ApiResponse resolveException(HttpServletRequest request,ParamBlankException e){ log.error(e.getMessage()); return new ApiResponse(ErrorEnum.PARAM_BLANK); }
-
Jmockit对接口与基类的mock
2016-06-07 18:51:10Jmockit对接口与基类的mock对一个类或接口使用@Capturing,那么该类的所有子类或接口所有实现都将处于mocked状态,即使是临时定义的实现或子类也会是mocked状态接口示例://接口 public interface JInterface { ...Jmockit对接口与基类的mock
对一个类或接口使用@Capturing,那么该类的所有子类或接口所有实现都将处于mocked状态,即使是临时定义的实现或子类也会是mocked状态
接口示例:
//接口 public interface JInterface { public String methodA(String para); } //实现 public class ImplA implements JInterface { public String methodA(String para) { return "oringinal methodA " + para; } }
Mock测试
@Test public void test1(@Capturing final JInterface jInterface)//JInterface接口被mocked { JInterface i = new ImplA(); System.out.println(i.methodA("d"));//null 因为被mocked new NonStrictExpectations() { { jInterface.methodA(anyString); returns("first mocked impl method", "second mocked impl method");// } }; System.out.println(i.methodA("ohad")); //record的第一个结果first mocked impl method //新定义的实现也将处于mocked状态 JInterface i3 = new JInterface() { public String methodA(String para) { // TODO Auto-generated method stub return null; } }; System.out.println(i3.methodA("dpfiojaoifh")); //record的第二个结果second mocked impl method }
继承示例:
//父类 public abstract class Base { abstract public String methodA(); } //子类 public class ExtendA extends Base { @Override public String methodA() { return "original method"; }
Mock测试
@Test public void test4(@Capturing final Base base) { Base obj = new ExtendA(); System.out.println(obj.methodA());//null new NonStrictExpectations() { { base.methodA(); //这里相当于returns(Object firstValue, Object... remainingValues) result = "mocked method1"; result = "mocked method2"; } }; System.out.println(obj.methodA());//mocked method1 Base obj1 = new Base() { @Override public String methodA() { return null; } }; System.out.println(obj1.methodA());//mocked method2 }
-
关于spring aop对接口方法上的注解无法拦截问题
2018-06-08 20:53:23最近实现一个功能,在访问dao层方法前...由此做了以下总结:一、关于注解继承问题对于接口,在接口中的注解无论如何都不能被继承,不论是子接口继承父接口的情况还是接口的实现类的情况,不论是对接口上还是接口中的...最近实现一个功能,在访问dao层方法前需要切换数据源,通过自定义注解+AOP实现:AOP中拦截被注解的方法,实现数据源切换。Dao层用mybatis实现,注解加在Mapper接口中的方法上。但是AOP无法对加了自定义注解的方法进行拦截。由此做了以下总结:
一、关于注解继承问题
对于接口,在接口中的注解无论如何都不能被继承,不论是子接口继承父接口的情况还是接口的实现类的情况,不论是对接口上还是接口中的方法上的注解,都不能,以上经过测试所得。
对于类,若注解上使用@Inherited标注,类上的注解可以被继承。 @Inherited表示该类上的注解可以被注解,与方法上的注解的继承性无关。
对于类中方法上的注解,若子类覆写了父类带注解方法,从子类无法获取到注解。子类未覆写父类带注解方法,可以通过子类获得注解。与注解是否标注@Inherited无关。
其实,注解在方法中,没有所谓继承问题,只有重写问题。如果注解在父类方法中,如果方法没有被子类重写,那么调用的是父类的方法,那么注解是存在的,如果方法被子类重写,子类方法没有注解,那么调用子类方法就获取不了注解
二、关于在接口的方法中加注解作为拦截点,拦截失败的原因:
1、AOP使用jdk动态代理的情况
接口中的注解无法被实现类继承,AOP中的切点无法匹配上实现类,所以并不会为实现类创建代理(根据是否被满足注解条件来判断是否创建代理,标红部分经过测试所得),所以我们使用的还是原始的未被代理的对象,所以就不会被拦截到了。
2、AOP使用cglib动态代理的情况
在不存在切点注解继承的情况,AOP可进行有效拦截(cglib动态代理)。但是考虑以下存在注解继承的情况
有类Parent,类Sub,Sub继承自Parent。根据注解的继承原则,切点注解在父类方法,
若Sub覆写了父类所有带注解方法,实际Sub中并未被AOP标识,所有spring并不会为Sub创建代理类,也就不会被拦截。
若Sub覆写了父类部分带注解方法,spring会为Sub创建代理类,对于覆写了父类的方法,由于注解未被继承,不会被拦截;未覆写的方法,可以被拦截。
所以,对于我遇到的问题:在mybatis中,加在Mapper接口方法上的注解无法被拦截可以做以下解释
mybatis本身会使用jdk动态代理来为我们生成一个Mapper接口的实现类,实际上我们的aop是在对这个Mapper的实现类创建代理(使用cglib代理)。由注解继承规则,该实现类的方法并不能继承接口方法上的注解,因而spring也就无法为该实现类生成代理,aop也就拦截失败。
-
对接口参数进行加密调用接口获取信息
2017-04-13 16:02:37/// /// 调用接口获取信息 /// /// <param name="p_strID"></param> /// <returns></returns> public Dictionary, object> GetInformationService(stri -
react对接口-获取数据篇
2018-10-23 12:05:01一、在src目录下创建的api.js文件,里面写你需要对的接口,api文件名取名最好规范一点 import { stringify } from 'qs';//这里都是固定的 import request from '../utils/request';//这里都是固定的 // 接口调用 /... -
【C# interface接口】对接口的理解、接口的使用方式(最通俗的解释)
2019-05-16 11:01:20我们为什么需要使用接口 比如说,我定义了一个Animal父类。 class Animal { public virtual void likeFood() { Console.WriteLine("我是Animal类"); } } 现在,有3个子类。子类继承父类Animal,分别叫:Dog, ... -
接口自动化落地(二:HttpClient+testNG实现对接口的测试及校验)
2018-06-15 16:07:53在接口自动化落地(一:MySQL+MyBatis实现对测试用例数据的读取)中已经实现了基础配置和测试用例数据准备,本篇文章将以登录举例进行测试执行。 这是之前login接口的代码 @Test(groups = "loginTrue",... -
微信对账单接口的使用以及对接口数据的解析方式
2016-05-27 13:59:15最近公司在做对账单的功能,从来没做过三方接口的我荣幸承包此活,千辛万苦找到...我怀疑是拼接参数的时候有问题,为了方便后面有跟我遇到相同问题的同志们,我将我的经验写下来,一来帮助大家使用这个接口,而来帮 -
postman带上token对接口进行测试
2018-05-08 09:49:27根据验证码进行登陆,登录之后返回token、然后请求其他接口时在header头中带上token访问其他接口进行测试账户信息输入验证码登陆成功,看到返回的token我们这个项目可以刷新一下token,将上表中的token复制粘贴进... -
JMeter对接口进行压力测试
2016-05-09 14:49:19用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域。 它可以用于测试静态和动态资源,例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、数据库、FTP 服务器, 等等。JMeter 可以... -
Castle AOP 系列(二):对接口方法调用的拦截(有源码)
2012-11-08 16:10:12相比于对类方法的拦截,对接口方法的拦截为我们的架构设计方面提供了更大的自由度。 1. 接口CastleAOPTestB.Lib.IPerson的定义 using System; using System.Collections.Generic; using System.Linq; using System... -
怎么对接口做幂等性操作?
2019-06-21 15:04:02这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“getUsername()和setTrue()”函数就是一个幂等函数. 更复杂的操作幂等保证是利用唯一交易号(流水号)实现. 我的理解:幂等就是一个操作,... -
我对接口与抽象类的理解
2011-02-20 00:43:00一般情况下,上一层分类都是对下一层分类的分类。而接口表达的是一种标准,本身不具有分类学意义,但可以作为一种分类的属性。接口是从对象的局部特征或者功能来进行的,但它并不代表对象。因此类表述的是一种“是... -
如何设计接口的参数以减少对接口的修改
2013-03-19 15:19:53问题就是模版函数或模板类不适合作为模块接口,如果是在模块内用模版那是完美的设计,但如果在模块接口一级用模版,那就悲催了。因为上面说了,模块一般是以头文件+DLL的方式提供,而模版的一个特点就是不支持分离... -
Java代码模拟并发请求对接口进行压测
2018-05-18 21:40:45案例:编写一段代码,模拟并发请求为20,且总的请求数为1000,当1000个请求完成之后,打印“请求完成”。实现代码:/** * 目标:编写一段代码,模拟并发请求为20,且总的请求数为1000,当1000个请求完成后,打印... -
程序员对接口与插件深入形象理解
2013-06-20 12:19:50一个闷骚的程序员是如何理解接口与插件的,到底有什么不同呢?理解是何等的深入,使用女人的**与男人的**相当形象的描述了这两者之间的区别,形成了鲜明的对比。 接口就像女人的** 它外面一般比较好看,就是说... -
使用Mock对接口(controller层)进行单元测试
2016-11-21 16:33:24QueryInfoController.java文件提供查询数据的接口; QueryService.java调用Dao层查询数据; QueryInfoControllerTest.java对QueryInfoController.java进行单元测试; 现分情况对Mock进行说明: 1、对... -
python对接口访问常用的各个方法。get请求,post请求,put请求
2019-05-30 17:33:27首先,put请求的参数和地址是混合在一起上传的,类似于get请求 import requests url = 'www.test.com' data = {'version': '1.0'} put_url = 'www.test.com?version=1.0' 1.get请求 ...# 查看接口返回的json... -
面向对象设计三大原则(封装变化点,对接口进行编程,多使用组合而不是继承)
2008-04-22 12:45:00该三大原则应该算是OO的基础,很多OO设计原则和设计模式都是在此三大原则上面衍生发展而来。...很多设计模式的意图中都明显地指出了其对问题的解决方案,学习设计模式的要点是发现其解决方案中封装的变化点。 -
接口测试
2020-06-02 12:55:06开发所谓的接口是模块模块之间的一种连接,而测试眼中的接口是一种协议(对接口的功能的一种定义) 2.接口的种类和分类 外部接口,内部接口:上层服务于下层服务,同级服务。常见的接口分类http:get,post,... -
接口测试简介以及接口测试用例设计思路
2018-09-07 11:50:27接口测试简介 1.什么是接口 接口就是内部模块对模块,外部系统对其他服务提供的...开发所谓的接口是模块模块之间的一种连接,而测试眼中的接口是一种协议(对接口的功能的一种定义) 2.接口的种类和分类 外部接... -
对异步处理的http接口进行性能测试
2018-10-17 16:38:32以前对接口做性能测试,接口都是同步处理的,请求之后等待响应结果就知道处理结果了,这样只要看这个接口是否异常,如果无异常无报错记录这个接口的响应时间、TPS等性能指标进行分析就可以了,最近在工作中遇到了... -
对调用第三方接口的监控策咯
2018-03-15 18:07:12还有如何屏蔽CXF的time out日志 一个思路: 可以做个接口调用情况监控 对于第三方的接口 做一个实时统计,对接口A 调用开始前 对redis 对应的一个key interfaceA +1 ,调用完 -1 ,对第三方接口调用前... -
接口测试——fiddler对soapui请求返回信息抓取
2018-07-31 14:48:09背景:接口测试的时候,需要对接口的请求和返回信息进行查阅或者修改请求信息,可利用fiddler抓包工具对soapui的请求数据进行抓取或修改。下面是简单的对接口请求和返回数据的查看。 fiddler 设置 a.打开工具... -
接口和接口实现类、接口与抽象类
2013-07-09 18:23:24今天在朋友的指导下,动手写了点东西,对接口和接口实现类有了一些认识。 接口,只是在里面写一些方法名、参数等,不需要写接口的具体内容。 接口实现类,在类中写接口的对应的方法以及方法的具体内容。 Example: ... -
对面向接口编程的理解
2016-06-10 11:59:20什么是面向接口编程
-
MxsDoc运行环境(Windows)
-
记录10天刷完PAT的过程
-
376. 摆动序列
-
91. 解码方法
-
敏捷个人:内容框架之执行力
-
华为1+X认证——网络系统建设与运维(初级)
-
响应式编程入门与实战(Reactor、WebFlux、R2DBC)
-
group by的使用
-
MySQL 高可用(DRBD + heartbeat)
-
一场危险的赌博?马斯克斥巨资买比特币或致特斯拉损失惨重
-
百度网盘如何搭建搜索目录?
-
2021-02-27
-
目标检测之两阶段算法--Fast R-CNN详解
-
浅谈数据仓库建设中的数据建模方法
-
智能停车场云平台(附vue+SpringBoot前后端项目源码)
-
shockwave网站::rocket:ShockWave Inc.网站-源码
-
07-NDK开发提升性能
-
Bootstrap学习记录【1】
-
让IT与SOA解决方案中的卫生信息交换需求保持一致
-
小屏幕大世界“Next”背后的秘密