的用户急速增强,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)模式,它也是类创建型