如今的不少平臺在登錄的時候,下面都會有一排選項,能夠選擇微信、QQ、微博帳號等登錄,這些帳號對平臺來講都是第三方帳號。第三方帳號登錄是最近幾年流行起來的,第三方帳號登陸通常都是基於OAuth2.0
協議開發的。若是你不瞭解OAuth2.0
協議,能夠自行百度,也許會對你看這篇文章有所幫助。java
如今因爲公司要給平臺引入流量,爲了下降註冊門檻,讓更多的人來使用大家的平臺,領導決定在大家的平臺上接入第三方帳號登錄功能。現階段先接入微信、支付寶、QQ、GitHub 這四個第三方帳號登錄。這個任務也順利的落到你的頭上,因爲你瞭解OAuth2.0
協議,你知道這個是一個固定的三段式操做,第一步獲取Authorization Code
,第二步獲取Access Token
,第三步調用信息接口,可是每一個平臺返回來的數據字段或者格式可能會不同,因此你根據你的開發經驗,爲第三方帳號登陸模塊抽取出來了一個IdentityProvider
抽象類,該類主要有上面提到的三步須要的接口,IdentityProvider
類的代碼以下:git
public abstract class IdentityProvider {
// 獲取Authorization Code
abstract void authorizationCode();
// 獲取 Access Token
abstract void accessToken();
// 獲取用戶信息
abstract void getUserInfo();
}
複製代碼
每個第三方帳號平臺都繼承IdentityProvider
,根據每一個第三方帳號平臺的規則去實現這三個接口,咱們已支付寶爲例,咱們定義一個AliPayIdentityProvider
類,該類繼承了IdentityProvider
類,AliPayIdentityProvider
類代碼以下:程序員
/** * 支付寶 第三方登錄具體實現 */
public class AliPayIdentityProvider extends IdentityProvider{
private static final String APPID = "你申請的運用id";
private static final String APPKEY = "你的私鑰";
public AliPayIdentityProvider() {
System.out.println("我是支付寶第三方登錄具體實現");
}
@Override
abstract void getUserInfo(){
// 獲取用戶信息
}
@Override
public void authorizationCode() {
//獲取authorization Code
}
@Override
public void accessToken() {
//獲取access Token
}
}
複製代碼
四個第三方帳號登陸平臺都按照上面的方式作了具體的實現,除此以外,你還建立了一個IdentityFactory
類,該類是建立實例的惟一入口,裏面提供了一個靜態create
方法,create
方法的做用是根據傳入的參數返回對應的第三方帳號平臺實例。IdentityFactory
類代碼以下:github
public class IdentityFactory {
/** * 第三方登錄實例獲取 * @param type 標識符,1:支付寶登錄 2:微信登錄 3:QQ登陸 4:github登錄 */
public static IdentityProvider create(int type){
IdentityProvider identityProvider = null;
switch (type){
case 1:
identityProvider = new AliPayIdentityProvider();
break;
case 2:
identityProvider = new WeChatIdentityProvider();
break;
case 3:
identityProvider = new QQIdentityProvider();
break;
case 4:
identityProvider = new GitHubIdentityProvider();
break;
}
return identityProvider;
}
}
複製代碼
客戶端調用時只須要調用create()
方法便可以獲取對應的實例,好比要使用GitHub
帳號登錄,咱們只要調用IdentityProvider identityProvider = IdentityFactory.create(4);
,獲取到GitHub
的IdentityProvider
,獲取到對象以後,能夠進行GitHub
帳號登錄的具體操做。提交、部署、測試、上線,完美完成任務。spring
在第三方帳號平臺登錄功能的實現中,你使用到了一種設計模式,叫做簡單工廠模式,此時你內心確定大喊一聲,臥槽,這就用上了設計模式?是的,沒錯,這就是設計模式。既然你好奇,那咱們就一塊兒來看看簡單工廠模式。設計模式
簡單工廠模式(Simple Factory Pattern):又稱爲靜態工廠方法(Static Factory Method)模式,是建立型模式的一種。在簡單工廠模式中,有一個工廠類來負責其餘類的實例建立,這些被建立的實例類都有一個共同的父類,在咱們的第三方帳號登錄中AliPayIdentityProvider
、WeChatIdentityProvider
都是被實例化的類,它們都有一個共同的父類IdentityProvider
,在簡單工廠模式中,工廠類中能夠根據傳入的參數返回不一樣的實例,在咱們的IdentityFactory
類中,咱們提供了一個靜態的create(int type)
,能夠根據傳入的類型返回不一樣的實例。因此咱們這個是標準的簡單工廠模式的實例。微信
上面這一大段很差理解?不要緊,那咱們在抽象一下,簡單工廠模式主要有如下三個成員:框架
IdentityProvider
AliPayIdentityProvider
IdentityFactory
咱們再來看一下簡單工廠模式的UML圖: ide
這些該明白簡單工廠模式了吧,雖然名字中帶有簡單兩個字,可是按照常理來講,就算再簡單,也該會有一些優勢吧。既然你還好奇,那就繼續來簡單工廠模式有哪些優勢吧。學習
第三方帳號登錄功能上線後,大家公司平臺的用戶急速加強,boss甚是高興,因而又給你安排活來了,此次boss叫你把微博帳號登錄加上,實現使用微博帳號登錄到大家的平臺,有了前面的經驗以後,這事對你來講太簡單的。你給系統新增了一個WeiBoIdentityProvider
類,用來實現微博帳號登陸,WeiBoIdentityProvider
類以下:
/** * 微博帳號登錄 */
public class WeiBoIdentityProvider extends IdentityProvider{
private static final String APPID = "你申請的運用id";
private static final String APPKEY = "你的私鑰";
public WeiBoIdentityProvider() {
System.out.println("我是微博第三方登錄具體實現");
}
@Override
abstract void getUserInfo(){
// 獲取用戶信息
}
@Override
public void authorizationCode() {
//
}
@Override
public void accessToken() {
}
}
複製代碼
在IdentityFactory
類中添加了case 5
分支,用來返回微博帳號登錄實例,變動以後IdentityFactory
類以下::
public class IdentityFactory {
/** * 第三方登錄驗證 * @param type 標識符,1:支付寶登錄 2:微信登錄 3:QQ登陸 4:github登錄 5:微博帳號 */
public static IdentityProvider crete(int type){
IdentityProvider identityProvider = null;
switch (type){
case 1:
identityProvider = new AliPayIdentityProvider();
break;
case 2:
identityProvider = new WeChatIdentityProvider();
break;
case 3:
identityProvider = new QQIdentityProvider();
break;
case 4:
identityProvider = new GitHubIdentityProvider();
case 5:
identityProvider = new WeiBoIdentityProvider();
break;
}
return identityProvider;
}
}
複製代碼
部署、測試微博帳號登錄,沒有問題,打包上線,關機下班。上線以後,大量用戶反饋GitHub帳號登錄不上。小夥子,出來接鍋了,因而你又要屁顛屁顛的跑回公司加班改 bug ,苦逼的程序員。你找呀找呀,最後發現了,case 4
的break
語句被你刪掉了,因此在使用GitHub帳號登錄時,IdentityFactory
工廠返回的實例一直都是WeiBoIdentityProvider
,致使GitHub帳號登錄會失敗。不經意間的一個小失誤,形成了一次線上事故。生產上都出事了,後果你懂的。雖然這事故是你人爲形成的,但這也是簡單工廠模式的缺點,你每新增第三方帳號登入平臺時,都須要去改動工廠類,這不免會出現這種誤刪的狀況。簡單工廠模式雖然簡單,可是也有很多缺點,那咱們一塊兒看看簡單工廠模式有哪些缺點吧。
通過了此次事故以後,你一心想證實本身,從新得到領導的賞識,你下定決心要對第三方帳號登錄模塊進行重構。老話說的好:在哪裏跌倒就要在哪裏爬起來。因而你想呀想呀,最後靈光一現,須要對IdentityFactory
類進行重構,工廠類也須要像提供方同樣,提取出一個抽象類,而後每一個提供方有本身的工廠,這樣就能夠避免新增時對原有系統模塊的改動。因而你抽象出來一個IdentityProviderFactory
類,用來定義工廠須要的接口。IdentityProviderFactory
類以下:
/** * 第三方登錄抽象工廠 */
public abstract class IdentityProviderFactory<T> {
// 建立具體的IdentityProvider
public abstract IdentityProvider create();
}
複製代碼
每一個第三方帳號平臺都須要有本身的生產工廠,這個工廠必須繼承IdentityProviderFactory
類,而後重寫create()
方法,在create()
方法裏實例化本身的identityProvider
實現類,咱們以支付寶工廠爲例,咱們須要建立一個AliPayIdentityProviderFactory
類,AliPayIdentityProviderFactory
類代碼以下:
/** * 支付寶第三方登錄工廠類 */
public class AliPayIdentityProviderFactory extends IdentityProviderFactory<AliPayIdentityProvider> {
@Override
public IdentityProvider create() {
//支付寶登陸實現實例
return new AliPayIdentityProvider();
}
}
複製代碼
在create()
方法中返回AliPayIdentityProvider
實例,每一個工廠都返回對應的實例就能夠,客戶端在調用時,也要發生相應的改變,不在傳入參數來獲取實例,而是經過調用對應的工廠來獲取實例。好比咱們使用支付寶帳號登錄
// 調用支付寶工廠
IdentityProviderFactory providerFactory = new AliPayIdentityProviderFactory();
// 獲取IdentityProvider
IdentityProvider provider = providerFactory.create();
// 一些列第三方認證操做
複製代碼
重構以後,咱們確定不會再出現上一次的問題,由於如今每一個第三方帳號提供方都有本身的工廠,每一個產品的構建運行都是獨立的。小夥子,恭喜你,你離升職加薪不遠了。
在你重構的過程當中,你也將簡單工廠模式進行了升級,如今它不叫簡單工廠模式了,由於它已經不簡單了,如今的模式叫做工廠方法模式(Factory Method Pattern)。既然咱們都用上了工廠方法模式,那就不妨一塊兒來了解一下工廠方法模式吧。
工廠方法模式(Factory Method Pattern)又稱爲工廠模式,也叫虛擬構造器(Virtual Constructor)模式或者多態工廠(Polymorphic Factory)模式,它也是類建立型模式的一種。工廠方法模式與簡單工廠模式的區別在於,在工廠方法模式中,實例的建立不是集中在一個工廠中,而是抽取出來了一個工廠父類,工廠父類負責定義建立產品對象的公共接口,而工廠子類則負責生成具體的產品對象,這樣作的目的是將產品類的實例化操做延遲到工廠子類中完成,即經過工廠子類來肯定究竟應該實例化哪個具體產品類。就像咱們的IdentityProviderFactory
類和AliPayIdentityProviderFactory
類。
跟簡單工廠模式同樣,咱們對工廠方法模式也進行抽象一下,工廠方法模式有下面四個成員:
IdentityProvider
AliPayIdentityProvider
IdentityProviderFactory
AliPayIdentityProviderFactory
老慣例,一塊兒看看工廠方法模式的UML圖,加深印象:
工廠方法模式好處在咱們重構第三方帳號登陸模塊的時候,咱們已經體驗到了,工廠方法模式的好處可不止那麼一點,一塊兒來看看工廠方法模式有哪些優勢?
DingDingIdentityProviderFactory
和DingDingIdentityProvider
就行了工廠方法模式雖然有諸多好處,可是它也有很多缺點,由於不可能有天衣無縫的設計模式,那咱們一塊兒來看看工廠方法模式的缺點。
case
分支,如今則須要建立類本文主要簡單的介紹了一下簡單工廠模式和工廠方法模式這兩種設計模式,經過第三方帳號登錄這個案例,從簡單工廠模式開始,一步一步的到了工廠方法模式。想要更深刻的瞭解工廠模式,須要參考大量的案例,spring
等開源框架中應用了大量的設計模式,工廠模式天然少不了,無論學習哪一種設計模式,咱們均可以去參考這些開源框架,它可以加深你對設計模式的理解。
文章不足之處,望你們多多指點,共同窗習,共同進步
打個小廣告,歡迎掃碼關注微信公衆號:「平頭哥的技術博文」,一塊兒進步吧。