《跟二师兄学Nacos吧》EXT-01篇 看看Nacos是怎么活学活用简单工厂模式的!

简介: 《跟二师兄学Nacos吧》EXT-01篇 看看Nacos是怎么活学活用简单工厂模式的!

学习不用那么功利,二师兄带你一起轻松读源码~


番外篇简介

Nacos源码分析系列文章,在开篇已经提到过,写作的目标有两个:第一,能够系统的学习Nacos知识;第二,能够基于Nacos学到涉及到的知识点或面。


为了方便大家学习,相对应的文章标题会有所区别,Nacos原理部分命名按照正常编号进行。而番外篇,也就是技术点的讲解则会在文章编号上添加“EXT-”的前缀。这样,如果大家只想学习Nacos原理知识,则可跳过EXT前缀的文章。


这篇文章我们来看看Nacos Client中对工厂模式的使用。这里分两个步骤来了解,首先看看标准的工厂模式是什么样子的,然后再对比一下Nacos中的实现与标准实现有什么区别。


工厂模式概述

在23种设计模式当中,工厂模式包含两种:工厂方法模式和抽象工厂模式。它们都属于创建型模式,而还有一种简单工厂模式,虽然经常被用到,但可能是过于简单,未被纳入23种设计模式当中。


简单工厂模式

下面先介绍一下,简单工厂模式,并对Nacos中的使用进行对比,并思考为什么会这样设计。


简单工厂模式简介

简单工厂模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂对象根据不同的参数类型返回不同实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。


对于简单工厂模式,要解决的问题便是封装实例创建的过程。需要什么类,只需传入一个对应的参数,就可以获得所需的对象,调用者无需知道实例的创建过程。被创建的实例通常都具有共同的父类。


简单工厂模式的结构

UML图展示如下:



image.png简单工厂通常包括三部分:


Factory(工厂):核心部分,负责实现创建所有产品的内部逻辑,工厂类可以被外界直接调用,创建所需对象;

AbstractProduct(抽象产品类):工厂类所创建的所有对象的父类,封装了产品对象的公共方法,所有的具体产品为其子类对象;

ConcreteProduct(具体产品):简单工厂模式的创建目标,实现了抽象产品类,所有被创建的对象都是某个具体类的实例;

其中抽象产品类可以是接口,也可以说抽象类。


简单工厂模式的实现

这里假设Nacos的配置中心服务和命名服务都继承自统一的NacosService,同时都需要提供一个注册方法。


抽象产品类定义如下:


public interface NacosService {

  /**

   * 注册实例信息

   * @param object 实例信息,这里用Object代替

   */

  void register(Object object);

}

1

2

3

4

5

6

7

命名服务NamingService的具体实现:


public class NamingService implements NacosService {


  @Override

  public void register(Object object) {

     System.out.println("注册命名服务成功");

  }

}

1

2

3

4

5

6

7

配置服务ConfigService的具体实现:


public class ConfigService implements NacosService {


  @Override

  public void register(Object object) {

     System.out.println("配置中心实例注册成功");

  }

}

1

2

3

4

5

6

7

提供一个工厂类NacosFactory:


public class NacosFactory {


  public static NacosService getService(String name) {

     if ("naming".equals(name)) {

        return new NamingService();

     } else {

        return new ConfigService();

     }

  }

}

1

2

3

4

5

6

7

8

9

10

其中根据传入的参数,生成不同类型的NacosService具体实现。


此时,客户端就可以直接调用该工厂:


public class Client {


  public static void main(String[] args) {


     NacosService nacosService = NacosFactory.getService("naming");

     nacosService.register(new Object());

  }

}

1

2

3

4

5

6

7

8

可以看出,此时客户端并不需要关注NacosService的具体实现类是如何被创建的,只需要通过NacosFactory来创建即可。这样,就把比较复杂的创建过程封装在了工厂类中。


简单工厂模式的优缺点

简单工厂模式的优点:


工厂类可包含必要的逻辑判断,可决定不同参数创建不同产品的实例。实现了创建职责的分离;

客户端无需知道所创建具体产品的类名,只需知道参数即可;

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

简单工厂模式的缺点:


工厂类集成了产品创建逻辑,职责过重;

增加系统中类的个数,增加系统复杂度和理解难度;

违反了设计模式中的开闭原则,新增产品需修改工厂逻辑;

简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

Nacos Client的简单工厂模式

在Nacos的client中,提供了一个NacosFactory的工厂类,该类统一提供了创建ConfigService(配置中心服务)、NamingService(注册中心服务)和NamingMaintainService(注册中心实例操作服务)的实例化方法。


在源码中可以看到是通过如下方式创建NamingService的:


NamingService namingService = NacosFactory.createNamingService(properties);

1

NacosFactory的部分源码:


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);
    }
    // ... 省略其他方法
}

乍一看该类的名字,你可能已经意识到它是工厂模式中的一种。但仔细对比会发现,哪一种好像都不是。


首先,我们来看最终创建出来的NamingService和ConfigService,它们各自独立,并不属于同一个抽象产品类。那这样创建出来也叫简单工厂模式吗?


这里要注意前面定义简单工厂模式时说过“被创建的实例通常都具有共同的父类”,这里的“通常”也就是说大多数情况下是这样的,也允许不实现自同一个接口或抽象类。


其次,我们会发现,NacosFactory中也没有根据方法参数进行不同的对象进行创建,而是直接提供了多个方法来创建不同的对象实例。这又是为什么呢?


这样设计可能出于三个目的:


第一,无论NamingService还是ConfigService,它们本身已经对应的工厂类ConfigFactory和NamingFactory了,如果需要单独创建其实是可以直接调用对应的工厂类的;


第二,NacosFactory存在的目的,本身就是为了达到“聚合”的作用,也就是把所有Nacos相关的服务实例集中对外提供,比如Spring Cloud集成时使用的NacosFactory来创建NamingService,而不是通过NamingFactory来创建。


第三,业务创建比较简单。也就是对于Nacos来说,目前版本中只会提供这三个Service,而不会再多出来其他的,因此开闭原则也就没那么重要了。于是就进行了简化处理。


因此,在使用工厂模式时并不一定非要按标准定义,教条式的进行实现,根据具体的场景可以灵活运用。基本上所有的设计模式都有类似的特点。


Nacos API的简单工厂模式

上面看到的是Nacos Client项目中的简单工厂模式实现,再进一步,我们看看该工厂模式中嵌套的NamingFactory:


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);
        }
    }
    // ...
}

在NamingFactory中的实现,才更接近标准的简单工厂模式。因为它提供的createNamingService方法,返回的是抽象产品类NamingService(接口)。而在该方法内部呢,才真正创建了它的实现类,虽然实现类只有一个。


小结

学习本文其实想给大家传递两个观点:第一,阅读源码时,其实我们可以多思考一步,比如看看它用到了什么设计模式或知识点;第二,学习设计模式时一定要活学活用,真实的实践环境变化完全,没必要刻板的按照概念来。活学活用,灵活变动,才达到了学习的最高境界。



目录
相关文章
|
1月前
|
JSON SpringCloudAlibaba Java
Springcloud Alibaba + jdk17+nacos 项目实践
本文基于 `Springcloud Alibaba + JDK17 + Nacos2.x` 介绍了一个微服务项目的搭建过程,包括项目依赖、配置文件、开发实践中的新特性(如文本块、NPE增强、模式匹配)以及常见的问题和解决方案。通过本文,读者可以了解如何高效地搭建和开发微服务项目,并解决一些常见的开发难题。项目代码已上传至 Gitee,欢迎交流学习。
143 1
Springcloud Alibaba + jdk17+nacos 项目实践
|
1月前
|
Java Nacos 开发工具
Nacos入门到精通
本文详细介绍了Nacos的基本概念、安装过程、配置管理功能,并通过具体代码示例展示了如何使用Java SDK和Spring Boot拉取和监听Nacos中的配置信息。
55 0
Nacos入门到精通
|
5月前
|
网络协议 Cloud Native Java
Nacos怎么用
【6月更文挑战第29天】Nacos怎么用
114 1
|
6月前
|
运维 负载均衡 算法
Nacos必知必会:这些知识点你一定要掌握!
Nacos必知必会:这些知识点你一定要掌握!
1313 0
|
存储 Java Nacos
Nacos服务注册与发现源码剖析
本文通过Nacos源码了解服务注册与发现原理。
206 0
Nacos服务注册与发现源码剖析
|
网络协议 Java 测试技术
配置中心原理和选型:Disconf、Apollo、Spring Cloud Config 和 Nacos
学完注册中心,再看配置中心这块,感觉简单很多,因为很多知识原理是相辅相成的
6055 0
配置中心原理和选型:Disconf、Apollo、Spring Cloud Config 和 Nacos
|
负载均衡 Cloud Native Dubbo
二.SpringCloudAlibaba极简入门-服务注册与发现Nacos
在《Spring Cloud 极简入门》中我们学习了netflix 的 Eureka 组件作为微服务的服务发现。Nacos和Eureka有着相同的能力,甚至更为强大,作为Dubbo 生态系统中重要的注册中心实现。官方对它有如下定义: Nacos致力于帮助您发现,配置和管理微服务。它提供了一组简单有用的功能,使您能够实现动态服务发现,服务配置,服务元数据和流量管理。 Nacos使构建,交付和管理微服务平台变得更容易,更快捷。它是通过微服务或云原生方法支持以服务为中心的现代应用程序体系结构的基础架构。 这里我们看到Nacos不仅是服务发现组件,同时也是一个配置管理组件,也就是说它不仅可以用来取
|
负载均衡 网络协议 Java
Nacos极简教程
Nacos是服务发现与注册,服务配置中心。 Nacos 具有如下特性: 服务发现和服务健康监测:支持基于DNS和基于RPC的服务发现,支持对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求; 动态配置服务:动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置; 动态 DNS 服务:动态 DNS 服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单DNS解析服务; 服务及其元数据管理:支持从微服务平台建设的视角管理数据中心的所有服务及元数据。 Nacos 为 C/S 架构,服务端 NacosServ
525 0
|
Java 程序员 Nacos
Nacos细节篇
Nacos细节篇
278 0
|
Java Nacos 数据安全/隐私保护
都2023了,为什么选择Nacos,这篇文章让你入门Nacos
2023了,为什么选择Nacos,这篇文章让你入门Nacos.Nacos算是阿里的巅峰之作了 , 集万千优点与一身, 比Eureka更便捷,更优秀,更完美而且Nacos的社区非常的活跃因为它使用简单,易操作,易上手而且比Eureka有着更加优秀的控制台界面.下面来简单认识一下今天的主角Nacos吧
230 0
下一篇
无影云桌面