App中第三方登录和分享模块的实现
@
本文目的:“ 实现一套易于使用、维护的第三方登录和分享模块”
我们开发App有时为了吸引用户,会引入三方的授权登录降低用户的注册和登录操作,同时会根据业务需求引入三方的分享服务。目前可用的第三方授权登录和分享有很多,国内比较常用的有微信、QQ、支付宝、微博等,一般我们会尽可能的同时支持多种三方功能,因此我们在开发中,需要将多种第三方的登录和分享功能组合在一起,形成统一的数据和接口,方便以后的维护。
1 流程
第三方登录和分享的流程相对来说比较简单,不同的第三方登录流程可能略有区别,但整体流程差别不大。以下是具体流程:
登录流程
1)用户在app中点击第三方登录的按钮(微信,或支付宝),app调用相应的第三方sdk进行授权;
2)三方sdk一般会打开自己的app或网页(没安装app的情况下)进行登录授权;
3)授权成功后,第三方sdk会将access_token等信息回调给app,app拿着access_token在请求用户信息等其他接口;
4)app拿到用户数据后,再向自己的服务器进行用户登录或注册。
分享流程
分享的流程比较简单,一般集成sdk后,调用第三方sdk的分享接口,将数据传递给sdk,sdk会打开自己的app进行分享操作。
2 设计与实现
首先,方便方便调用,可以这样设计登录测试用例:1)创建对象,2)调用登录方法,3)登录成功接收用户信息,失败则返回错误信息。
//微信登录
new WeixinLogin().login(new Listener(){
void onSuccess(userInfo data){}
void onFailure(String msg){}
void onCancel(){}
})
//QQ登录
new QQLogin().login(new Listener(){
void onSuccess(userInfo data){}
void onFailure(String msg){}
void onCancel(){}
})
分析这个测试用例,我们发现 WeixinLogin,QQLogin 都是带有 login(listener) 方法的对象,因此我们需要2个接口:
//登录接口
interface SocaillLoginInterface {
//登录,参数为回调接口
void login(SocaillLoginListener listener);
}
//登录回调接口
interface SocaillLoginListener {
//成功,SocialLoginUserInfo为登录用户信息,根据根据业务需要一般包含uid,名称,性别,头像等。
void onSuccess(SocialLoginUserInfo userInfo);
//失败
void onFailure(String msg);
//取消
void onCancel();
}
接下来我们就需要分别创建微信登录,qq登录,支付宝登录的实现类,这些类都从接口 SocaillLoginInterface 继承:
class WeixinLogin implements SocaillLoginInterface {
public WeixinLogin(Activity activity){
}
void login(SocaillLoginListener listener){
}
}
class QQLogin implements SocaillLoginInterface {
public QQLogin(Activity activity){
}
void login(SocaillLoginListener listener){
}
}
具体的登录细节就不写了,各开放平台基本都有文档和demo。
实现这些细节以后我们就可以使用开始的测试用例来测试代码了。
3 优化
基于以上实现,我们基本可以实现了登录接口的统一调用,但是我们在实际开发中发现,在登录的地方我们需要引用 WeixinLogin,QQLogin 这些类,假如某一天qq登录的逻辑需要变更,我们要增加对象QQv2Login,这时引用 QQLogin 的地方都要修改为 QQv2Login,这就增加了代码的维护难度。
因此我们是进一步封装:
public class SocaillLoginBuilder{
SocaillLoginInterface weixin(Activity activity){
return new WeixinLogin(activity);
}
SocaillLoginInterface qq(Activity activity){
return new QQLogin(activity);
}
}
修改调用代码:
SocaillLoginBuilder.weixin(act).login(
new SocaillLoginListener(){
void onSuccess(SocialLoginUserInfo data){
}
void onFailure(String msg){
}
void onCancel(){
}
}
);
这样优化以后,每当有新实现类需要替换旧实现类的时候,只需要修改 SocaillLoginBuilder 类中的代码即可,调用方则不用关心具体是哪种实现。
下面用类图总结一下:
注:实际项目中我们使用了友盟社会化sdk,因此基于微信,微博,QQ的登录中间增加了抽象类 BaseUmengLogin。
第三方分享实现也是一样的思路,类图如下:
最后,不管用什么样的方式,能做到低耦合,易维护,易使用,就是好的设计。
END
本文的技术设计和实现都是基于作者工作中的经验总结,如有错误,请留言指正,谢谢。