Now many platforms landing time, there will be a row following options can be selected micro letter, QQ, Weibo account number landing, which accounts for a third-party platform for both accounts. Third-party account login popular in recent years, third-party account login are generally based on OAuth2.0
protocol development. If you do not know OAuth2.0
the protocol, you can own Baidu, you may find reading this article helpful.
Now that the company give platform to introduce traffic, in order to reduce the threshold for registration, to allow more people to use your platform, the leadership decided to access third-party account login function on your platform. First stage micro-channel access, Alipay, QQ, GitHub four third-party account login. This task also falls smoothly over your head, because you understand the OAuth2.0
agreement, you know this is a fixed three-stage operation, the first step to Authorization Code
the second step to obtain Access Token
the third pace with the interface, but each platform return to the field or data format may be different, so you based on your experience in the development, third-party account login module extracted an IdentityProvider
abstract class that interfaces mentioned above there are three steps required IdentityProvider
class code as follows:
public abstract class IdentityProvider {
// 获取Authorization Code
abstract void authorizationCode();
// 获取 Access Token
abstract void accessToken();
// 获取用户信息
abstract void getUserInfo();
}
Every inherited a third-party account platform IdentityProvider
, to achieve these three interfaces in accordance with the rules of each third-party account platform, we have to pay Po, for example, we define a AliPayIdentityProvider
class that inherits the IdentityProvider
class, AliPayIdentityProvider
class code is as follows:
/**
* 支付宝 第三方登陆具体实现
*/
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
}
}
Four third-party account login accordance with the above platforms are the way to do a specific implementation, in addition, you also create a IdentityFactory
class, which is the only entrance to create an instance of, which provides a static create
method, create
the method is the role of return to a third party account platform of the corresponding instance according to the parameters passed. IdentityFactory
Class code as follows:
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;
}
}
Just call when the client calls the create()
method which can obtain the corresponding instance, for example, to use the GitHub
account login, just call us IdentityProvider identityProvider = IdentityFactory.create(4);
, get to GitHub
the IdentityProvider
, after obtaining objects, you can be GitHub
specific operations account login. Submit, deployment, testing, on-line, perfect to complete the task.
In the implementation of the third-party account platform accessibility, you used to design a model, called the simple factory pattern , this time sure your heart shouted, FML, which were using design patterns? Yes, yes, this is design mode. Since you're curious, then we take a look at a simple factory pattern.
Define simple factory pattern
Simple factory pattern (Simple Factory Pattern): also known as static factory method (Static Factory Method) mode, is a creational pattern. In a simple factory pattern, there is a factory class is responsible for other instances of the class is created, the instance of the class being created have a common parent class, in our third-party account login in AliPayIdentityProvider
, WeChatIdentityProvider
are instantiated class, they have a common parent class IdentityProvider
, in a simple factory pattern, the factory class can be returned in accordance with the parameters passed a different instance, in our IdentityFactory
classes, we provide a static create(int type)
, it can be returned depending on the type of incoming instance. So our factory is the standard mode of simple examples.
Above this large segment difficult to understand? It does not matter, that we look at in the abstract, simple factory pattern mainly in the following three members:
- Abstract Products: Abstract product role is the parent of all objects created, responsible for describing common to all instances of common interfaces, such as
IdentityProvider
- Specific products: the goal is to create the role of specific products, all objects created are serving as an example of a specific class of this role, for example,
AliPayIdentityProvider
- Factory class: responsible for implementing the internal logic all create instances, for example,
IdentityFactory
Let us look at a simple factory pattern UML diagram:
These should understand a simple factory pattern, even though the name with a simple word, but according to common sense, simple and even then, it should also have some advantages. Since you are also curious, it would continue to be a simple factory pattern What are the advantages of it.
The advantage of simple factory pattern
- Factory class contains the necessary logic judgment, can decide which instance of a product class is created at what time the client may be exempted from the responsibility to create product objects directly, but only "consumer" product; a simple factory pattern achieved through the practice of responsibility the division, which provides specialized factory class for creating objects.
- Clients do not need to know the class name specific product category created only need to know the specific product class corresponding parameters can be, for some complex class name, a simple factory pattern can reduce the amount of user memory.
- By introducing the configuration file, you can change and add new specific product category without modifying any client-side code and improve the flexibility of the system to some extent.
After a third-party on-line account login function, the user platform rapidly enhance your company, boss very happy, so gave you arrange to live here, the boss tell you to add microblogging account login, implemented using the microblogging account login your platform, after previous experience with this thing for you too simple. You give the system added a WeiBoIdentityProvider
class that implements microblogging account login, WeiBoIdentityProvider
type the following:
/**
* 微博账号登陆
*/
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() {
}
}
In the IdentityFactory
Add Class in the case 5
branch, to return microblogging account login instance, after changing the IdentityFactory
class as follows ::
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;
}
}
Deployment, testing microblogging account login, no problem, packaged on-line, off from work. After on-line, a lot of user feedback GitHub account not on the landing. Young man, come out to accept the pot, so you have to work overtime to change the company ran back Pidianpidian bug, hard to force the programmer. You Zhaoyazhaoya, finally found, case 4
the break
statement is that you deleted, so use GitHub account login, IdentityFactory
examples of the plant has been returned WeiBoIdentityProvider
, resulting in GitHub account login will fail. A small mistake inadvertently, caused an accident online. Production have an accident, you know the consequences. While this accident was, but your weaknesses caused by human activity is a simple factory pattern, every time you add third-party account login platform, we need to change the factory class, which inevitably case of such accidental deletion will appear. Simple factory pattern is simple, but there are many shortcomings, then we take a look at a simple factory pattern what are the disadvantages of it.
Drawback simple factory pattern
- Contrary to the "Open - Closed Principle", once adding a new product would have to modify the logic of the factory class, so it is easy to cause mistake, as we have above, accidentally cause an accident online
- Factory class centralizes all instances (products) to create a logical, once the factory is not working properly, the whole system will be affected
- Simple factory pattern due to the use of static factory method, resulting in the role of the factory can not form a hierarchy based on inheritance.
After the accident, you bent to prove himself, to regain the leadership of her, you are determined to third-party account login module reconstructed. Good old saying: Where would fall in where to get up. So you want to think ah ah, finally a eureka moment, the need for IdentityFactory
classes reconstruction, the factory class is also required as providers as to extract an abstract class, and each provider has its own factories, so you can avoid new changes to the original system when the module. So you abstract out of a IdentityProviderFactory
class, used to define the interfaces required for the plant. IdentityProviderFactory
Classes are as follows:
/**
* 第三方登陆抽象工厂
*/
public abstract class IdentityProviderFactory<T> {
// 创建具体的IdentityProvider
public abstract IdentityProvider create();
}
Each third-party accounts platform needs to have its own production plant, the plant must inherit IdentityProviderFactory
the class, and then override the create()
method, the create()
method in the examples of their identityProvider
implementation class, we have to pay for treasure factory, for example, we need to create a AliPayIdentityProviderFactory
class, AliPayIdentityProviderFactory
the class code as follows:
/**
* 支付宝第三方登陆工厂类
*/
public class AliPayIdentityProviderFactory extends IdentityProviderFactory<AliPayIdentityProvider> {
@Override
public IdentityProvider create() {
//支付宝登录实现实例
return new AliPayIdentityProvider();
}
}
In the create()
return process AliPayIdentityProvider
instance, each plant may return the corresponding instance, when calling a client, but also the appropriate changes, not passing parameters to obtain an instance, but to obtain a corresponding instance by calling the factory. For example, we use Alipay account login
// 调用支付宝工厂
IdentityProviderFactory providerFactory = new AliPayIdentityProviderFactory();
// 获取IdentityProvider
IdentityProvider provider = providerFactory.create();
// 一些列第三方认证操作
After the reconstruction, we certainly will not again on the problems, because now every third-party account providers have their own factories, build each product run are independent. Boy, congratulations, you are not far from promotion and pay rise.
In the course of your remodeling, you will also be simple factory pattern has been upgraded, and now it is not called a simple factory pattern, because it has not simple, and now the model is called the factory method pattern (Factory's Method, Pattern) . Since we were using the factory method pattern, it may wish to take a look at the factory method pattern of it.
Factory method defined pattern
Factory method model (Factory Method Pattern), also known as factory mode, also called virtual constructor (Virtual Constructor) mode or a polymorphic plant (Polymorphic Factory) mode, it is also for creating a class in the schema. The difference between simple factory method pattern and factory pattern is that the factory method pattern, create an instance is not concentrated in one factory, but the factory extracted a parent, the parent class factory object is responsible for defining the public interface to create a product, and subclasses factory is responsible for generating specific target products, the aim is to instantiate operation of the plant to the product category subclass delay completion, i.e. to determine exactly which specific product class through the factory to instantiate subclasses. Just like our IdentityProviderFactory
class and AliPayIdentityProviderFactory
class.
Like simple factory pattern, factory method pattern we also look at the abstract factory pattern method has the following four members:
- Abstract product: good products with defined properties methods, such as
IdentityProvider
- Specific products: specific product realization, for example,
AliPayIdentityProvider
- Abstract Factory: good abstract methods defined in the factory, for example,
IdentityProviderFactory
- Specific plant: specific production plants, e.g.
AliPayIdentityProviderFactory
Old practice, take a look at UML diagram factory method pattern, a deeper impression:
Factory Method pattern when we reconstruct the benefits of third-party account login module, we have experienced the benefits of factory method pattern can be more than a bit, take a look at what advantages the factory method pattern there?
Advantage of factory methods
- Factory Method pattern scalability is very strong, when adding new products in the system, no need to modify the interface abstraction abstract factory and products, and just add a concrete plant and concrete products, they can embrace change, just as if we are going to take nails into account login, we only need to create
DingDingIdentityProviderFactory
andDingDingIdentityProvider
like - 良好的封装性,代码结构清晰。调用者需要一个具体的产品对象时,只需要知道这个产品的类名就可以了,不需要知道具体的创建过程,降低的模块之间的耦合
- 屏蔽产品类,产品类的实现如何变化,调用者不需要关系,它只关系产品的接口,只要接口保持不变,系统中的上层模块就不需要变化。所以工厂方法模式经常用来解耦,高层模块只需要知道产品的抽象类,实现类不需要关系,这符合迪米特法则,也符合依赖倒置原则。
工厂方法模式虽然有诸多好处,但是它也有不少缺点,因为不可能有完美无缺的设计模式,那我们一起来看看工厂方法模式的缺点。
工厂方法模式的缺点
- 增加了系统复杂度,我们将工厂类拆分出来,无形之中给我们的系统带来了复杂性
- 增加了开发量,在使用简单工厂模式时,我们只想要添加一个
case
分支,现在则需要创建类 - 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度
总结
本文主要简单的介绍了一下简单工厂模式和工厂方法模式这两种设计模式,通过第三方账号登陆这个案例,从简单工厂模式开始,一步一步的到了工厂方法模式。想要更深入的了解工厂模式,需要参考大量的案例,spring
等开源框架中应用了大量的设计模式,工厂模式自然少不了,不管学习哪种设计模式,我们都可以去参考这些开源框架,它能够加深你对设计模式的理解。
文章不足之处,望大家多多指点,共同学习,共同进步
最后
打个小广告,欢迎扫码关注微信公众号:「平头哥的技术博文」,一起进步吧。