在之前我们已经详细的设计出了这个接口鉴权功能的需求和思路

那么我们将进行实际的开发,在面向对象的开发环节,我们主要的设计产出是类,我们就是将需求的描述以及整体的方案是转化为具体的类.

那么整体的流程就是划分职责并进而识别出有哪些类,

定义类中的属性和方法,

定义类和类之间的关系,

将类与类之间进行组合

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个部分

一,根据不同功能划分出不同的类

二定义类和属性获得总结方法

定义类和类之间的交互

将内组装起来并提供外部接口

发表评论

邮箱地址不会被公开。 必填项已用*标注