在之前我们已经详细的设计出了这个接口鉴权功能的需求和思路
那么我们将进行实际的开发,在面向对象的开发环节,我们主要的设计产出是类,我们就是将需求的描述以及整体的方案是转化为具体的类.
那么整体的流程就是划分职责并进而识别出有哪些类,
定义类中的属性和方法,
定义类和类之间的关系,
将类与类之间进行组合
1.识别出有哪些类?
一般来说识别类的方法有
将需求描述中的名词罗列出来,作为可能的候选类,然后进行罗列筛选,这个方法比较简单.
或者将需求描述中可能的功能点进行罗列,然后将功能点之间的相同处找出,进而组合成了一个类.
那么我们这个接口所需要实现的功能主要有
1.将URL,APPID,密码,时间戳拼接为一个字符串
2.对这个字符串进行Token算法的加密
3.将APPID,token 时间戳拼接到URL当中形成新的URL
4.解析URL,获取APPID,token,时间戳等信息
5.从储存层获取到APPID及密码
6. 先判断时间戳是否在范围内
7.进行账号密码的匹配
这样我们可以将步骤1267归为一类,这一类我们称之为Token类
然后将3 4归为URL类,将步骤5归为数据存储类
我们这个接口鉴权的功能比较简单,在完成方案设计之后,整体来说思路也比较清晰,所以识别出来的类并不是很多,如果是更加复杂的需求,那么我们就没法直接去获得功能点,这就需要我们先进行模块化的划分,然后根据模块再仔细罗列出功能点,进而获取到类
2.定义出类及其属性,方法
我们通过上面的识别,识别出了三个核心力,分别为token URL以及数据存储,那么我们可以看一下每个类都有哪些属性和方法
token类主要的方法有4个,将URL,APPID,密码和时间戳进行拼接以及利用加密算法进行加密和解密token,然后判断token是否过期,以及验证两个token是否匹配,具体实现如下
URL的类实现
对于URL类主要需要实现的功能点有两个
1.利用时间戳APPID和token进行生成url
2,利用URL解析,得到token,APPID和时间戳的信息
由于请求方式可能进行变化,于是乎我们将其抽象出来,形成了一个更加抽象的接口类,称为APIRequest,于是我们对于APIRequestt的定义如
对于数据存储类那么就很简单了
只需要提供一个根据APPID获取到其密码的接口就可以了,接口类如下:
3.定义类和类之间的交互关系
文件的类和类之间的交互方式有6种,分别是泛化,实现,关联,聚合,组合,依赖
泛化,就是在Java中的继承关系
实现,就是面向对象当中的抽象类到实现类的关系
聚合,就是一种包容关系,a类对象包容b类对象,但是b类的对象生命周期跟a类没有关系
组合,则与聚合相反,a类包含b类,而且b类的生命周期依赖于a类,也就是b类不可以单独存在,必须依赖于a类存在
关联是一种非常弱的关系,它只要b类是a类的成员变量,那么就认为他是关联关系
依赖是一种更加弱的关系,只要有任何关系就可以认为是依赖
我们简化一下,将组合代替聚合,关联关系,从而简化为四种关系
4.组合类和类之间
我们设计一个ApiAuthenticator接口类,暴露给外部调用着使用,作为鉴权的接口
具体如上,传入账号密码,来调用鉴权功能
具体的实现如下
public interface ApiAuthenticator {
void auth(String url); void auth(ApiRequest apiRequest); } public class DefaultApiAuthenticatorImpl implements ApiAuthenticator { private CredentialStorage credentialStorage; public DefaultApiAuthenticator() { this.credentialStorage = new MysqlCredentialStorage(); } public DefaultApiAuthenticator(CredentialStorage credentialStorage) { this.credentialStorage = credentialStorage; } @Override public void auth(String url) { ApiRequest apiRequest = ApiRequest.buildFromUrl(url); auth(apiRequest); } @Override public void auth(ApiRequest apiRequest) { String appId = apiRequest.getAppId(); String token = apiRequest.getToken(); long timestamp = apiRequest.getTimestamp(); String originalUrl = apiRequest.getOriginalUrl(); AuthToken clientAuthToken = new AuthToken(token, timestamp); if (clientAuthToken.isExpired()) { throw new RuntimeException(“Token is expired.”); } String password = credentialStorage.getPasswordByAppId(appId); AuthToken serverAuthToken = AuthToken.generate(originalUrl, appId, password, timestamp); if (!serverAuthToken.match(clientAuthToken)) { throw new RuntimeException(“Token verfication failed.”); } } } |
我总结一下,我们的开发环节可以分为下面4个部分
一,根据不同功能划分出不同的类
二定义类和属性获得总结方法
定义类和类之间的交互
将内组装起来并提供外部接口