工厂模式,从第三方登录说起 (2)

这些该明白简单工厂模式了吧,虽然名字中带有简单两个字,但是按照常理来说,就算再简单,也该会有一些优点吧。既然你还好奇,那就继续来简单工厂模式有哪些优点吧。

简单工厂模式的优点

工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。

客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。

通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

第三方账号登陆功能上线后,你们公司平台的用户急速增强,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(); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzzysy.html