Learn not so utilitarian, two brothers with you easily read the source code ~

A brief introduction to the article

NACOS source analysis series articles, at the beginning of the mentioned, writing goals have two: first, to be able to systematically learn the knowledge of NACOS; Secondly, the knowledge points or aspects involved can be learned based on NACOS.

In order to facilitate your study, the corresponding title of the article will be different, and the naming of the principle part of NACOS will be carried out in accordance with the normal number. Extras, or technical points, will be prefixed with “EXT-“. This way, if you just want to learn about the principle of NaCos, you can skip the text with the EXT prefix.

In this article we will look at the use of the factory pattern in the Nacos Client. This is a two-step process, first looking at what the standard factory pattern looks like, and then comparing the implementation in NaCos to the standard implementation.

Overview of Factory Pattern

Among the 23 design patterns, the factory pattern includes two: the factory method pattern and the abstract factory pattern. These are all creation patterns, and there is a simple factory pattern, which is often used, but may be too simple to be included in the 23 design patterns.

Simple Factory Pattern

Let’s start with the simple factory pattern, and compare its use in NaCos, and think about why it was designed the way it was.

Brief introduction to the simple factory pattern

The Simple Factory pattern, also known as the Static Factory Method pattern. The simple factory pattern consists of a factory object that returns different instances according to different parameter types. The Simple Factory pattern is the simplest and most practical pattern in the family of factory patterns and can be understood as a special implementation of a different factory pattern.

For the simple factory pattern, the problem is to encapsulate the instance creation process. If you need a class, you can simply pass in a corresponding parameter and get the object you want. The caller does not need to know how to create the instance. Instances that are created usually have a common parent class.

The structure of the simple factory pattern

The UML diagram is shown as follows:

A simple factory usually consists of three parts:

  • Factory (Factory) : The core part is responsible for the internal logic of creating all products. The Factory class can be directly called by the outside world to create the required objects.
  • AbstractProduct: A parent class of all objects created by the factory class that encapsulates the public methods of the product object. All concrete products are subclass objects.
  • ConcreteProduct: The creation target of the simple factory pattern, which implements an abstract product class. All objects created are instances of a concrete class.

An abstract product class can be an interface or an abstract class.

Implementation of the simple factory pattern

It is assumed that both the configuration center service and the naming service of NACOS inherit from the unified NACOSService, and both need to provide a registration method.

The abstract product class is defined as follows:

Public void register() {public void register(); public void register() {public void register(); }

The specific implementation of namingService:

public class NamingService implements NacosService { @Override public void register(Object object) { System.out.println(" Naming service registered successfully "); }}

ConfigService ConfigService ConfigService

public class ConfigService implements NacosService { @Override public void register(Object object) { System.out.println(" Configuration Center instance registered successfully "); }}

Provide a factory class, NacosFactory:

public class NacosFactory { public static NacosService getService(String name) { if ("naming".equals(name)) { return new  NamingService(); } else { return new ConfigService(); }}}

According to the parameters passed in, the specific implementations of different types of NacosService are generated.

At this point, the client can call the factory directly:

public class Client { public static void main(String[] args) { NacosService nacosService = NacosFactory.getService("naming"); nacosService.register(new Object()); }}

As you can see, the client does not need to pay attention to how the concrete implementation class of NacosService is created at this time, but only through the NacosFactory. In this way, the more complex creation process is encapsulated in the factory class.

The pros and cons of the simple factory pattern

Advantages of the simple factory pattern:

  • The factory class can contain the necessary logical judgments to determine different parameters to create instances of different products. Separation of creation responsibilities;
  • The client does not need to know the class name of the specific product to be created, only needs to know the parameters.
  • By introducing configuration files, new specific product classes can be changed and added without modifying any client code, which improves the flexibility of the system to a certain extent.

Disadvantages of the simple factory model:

  • The factory class integrates product creation logic and is overloaded with responsibilities;
  • Increase the number of classes in the system, increase the complexity of the system and the difficulty of understanding;
  • It violates the Open Closed Principle in the design mode, and the factory logic needs to be modified for new products.
  • The simple factory pattern uses a static factory approach, which prevents factory roles from forming hierarchies based on inheritance.

Simple factory pattern for the Nacos Client

In the Nacos Client, a factory class of the NacosFactory is provided. This class provides a unified instantiation method for creating ConfigService, NamingService, and NamingMaintainService.

You can see in the source code that the NamingService is created as follows:

NamingService namingService = NacosFactory.createNamingService(properties);

Part of the NacosFactory source code:

public class NacosFactory { public static ConfigService createConfigService(Properties properties) throws NacosException  { return ConfigFactory.createConfigService(properties); } public static NamingService createNamingService(Properties properties) throws NacosException { return NamingFactory.createNamingService(properties); } / /... Omit other methods}

At first glance, from the name of the class, you might recognize it as one of the factory patterns. But on closer examination, neither seems to be the case.

First, let’s look at the resulting NamingService and ConfigService, which are independent of each other and do not belong to the same abstract product class. Is it called a simple factory pattern when it is created like this?

Note that when we defined the simple factory pattern earlier, we said that “instances that are created usually have a common parent class.” The term “usually” here means that it does so in most cases, and also allows for not implementing from the same interface or abstract class.

Second, we’ll notice that instead of creating different objects based on method parameters, the NacosFactory directly provides multiple methods to create different object instances. Why is that?

This design may serve three purposes:

First, both NamingService and ConfigService already have corresponding factory classes. If you need to create a separate factory class, you can call the corresponding factory class directly.

Second, the purpose of NacosFactory itself is to achieve the function of “aggregation”, that is, to provide all the Nacos-related service instances to the public. For example, the NacosFactory is used in the Spring Cloud integration to create the NamingService. Instead of creating it through the NamingFactory.

Third, business creation is relatively simple. For Nacos, the current version will only provide these three services and no more, so the Open Closed Principle is not as important. So we simplified it.

Therefore, when using the factory pattern, it does not have to be defined in a standard way, but implemented in a dogmatic way. It can be applied flexibly according to specific scenarios. Basically all design patterns have similar characteristics.

Simple factory pattern for the Nacos API

The above is a simple implementation of the factory pattern in the Nacos Client project. Going a step further, let’s look at the nested NamingFactory within the factory pattern:

public class NamingFactory {

    public static NamingService createNamingService(Properties properties) throws NacosException {
        try {
            Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService");
            Constructor constructor = driverImplClass.getConstructor(Properties.class);
            return (NamingService) constructor.newInstance(properties);
        } catch (Throwable e) {
            throw new NacosException(NacosException.CLIENT_INVALID_PARAM, e);
        }
    }
    // ...
}

The implementation in NamingFactory is much closer to the standard simple factory pattern. Because it provides the createEnamingService method, it returns the abstract product class NamingService (interface). Inside the method, the implementation class is actually created, even though there is only one implementation class.

summary

Learning this article actually wants to convey two points to you: first, when reading the source code, we can actually think a step further, such as to see what design patterns or knowledge points it uses; Second, when learning design patterns, we must learn and apply them flexibly. The real practice environment changes completely, so there is no need to rigidly follow the concept. Live learning and use, flexible change, to achieve the highest level of learning.

Source address: https://github.com/secbr/naco…

If you have any questions about the content of the article or want to discuss the technology, please contact me (WeChat: Zhuan2quan, remarks Nacos). If you think the article is good and worth learning together, then pay attention to it.

Author of the technical book SpringBoot Inside Technology, loves to dig into technology and write good articles about technology.

Public number: “Program new horizon”, the public number of bloggers, welcome to pay attention to ~

Technical exchange: please contact the blogger WeChat ID: zhuan2quan