《跟二师兄学Nacos吧》EXT-02篇 面试官问工厂模式,你理解的对吗

梦叶草789
发布于 2022-8-30 11:11
浏览
0收藏

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

在上篇文章中,我们学习了Nacos中是如何灵活运用《简单工厂模式》的。而设计模式在面试过程中也经常会出现。当面试官问到:说说工厂模式是如何实现的?他问的工厂模式指的是什么?

这篇文章属于扩展篇的扩展,我们基于简单工厂模式,再来聊聊工厂模式。

 

工厂方法模式
先来回答上面的问题,如果笼统的讲工厂模式,通常包括:简单工厂/静态工厂、工厂方法模式和抽象工厂模式。上节讲了简单工厂模式,而抽象工厂模式一般应用在比较复杂的大型应用中,也不太常见。

因此,如果工厂模式只是指某一个模式的话,那么说的就是工厂方法模式。

 

工厂方法模式简介
工厂方法模式(Factory Method Pattern)又称工厂模式、多态工厂模式和虚拟构造器模式。

在讲简单工厂模式时,已经知道该模式存在一些缺点,比如工厂类业务逻辑过于复杂,违背了开闭原则和高内聚低耦合的原则。同时,还由于方法是静态的,还无法形成继承的层级结构。

那么,我们是否可以将工厂类进行抽象,提供一个公共的接口,而工厂类的子类负责创建具体的产品对象,这样不就达到了解耦的目标了吗?

因此,在工厂方法模式中,工厂父类定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,通过工厂子类来确定究竟应该实例化哪一个具体的产品类。

 

工厂方法模式结构图
在看工厂方法模式的结构图之前,先来回顾一下简单工厂模式的结构图:

《跟二师兄学Nacos吧》EXT-02篇 面试官问工厂模式,你理解的对吗-鸿蒙开发者社区简单工厂模式

我们对此结构图进行扩展,将Factory这个工厂类进行抽象化处理,于是就得到工厂方法模式:

《跟二师兄学Nacos吧》EXT-02篇 面试官问工厂模式,你理解的对吗-鸿蒙开发者社区

工厂方法模式

上图中被虚线框起来的部分便是变化的部分,第一个变化是工厂类被抽象化了,提供了一个抽象的AbstractFactory。既然抽象了,必定会有具体的工厂实现类,这个实现类与产品相对照。这样,便达到了修改一个产品的创建逻辑,并不会影响到其他产品的创建,达到了解耦的效果。

下面再梳理一下工厂方法模式的核心角色:

 ● 抽象产品(Product):产品的抽象类或接口,负责定义产品的特征和共性。
 ● 具体产品(Concrete Product):具体的产品类。
 ● 抽象工厂(AbstractFactory):产品的创建类,工厂接口。
 ● 具体工厂(ConcreteFactory):具体的创建类,工厂实现。


工厂方法模式实现
这里的实例我们还以Nacos的配置服务和命名服务为例。假设配置服务和命名服务都集成自同一个NacosService,同时呢,它们的创建又通过不同的子工厂进行创建。

定义抽象产品类及其实现类:

// 抽象产品类
public interface NacosService {
   /**
    * 注册实例信息
    * @param object 实例信息,这里用Object代替
    */
   void register(Object object);
}

// 配置中心服务实现
public class ConfigService implements NacosService {
   @Override
   public void register(Object object) {
      System.out.println("配置中心实例注册成功");
   }
}

// 命名服务注册实现
public class NamingService implements NacosService {
   @Override
   public void register(Object object) {
      System.out.println("注册命名服务成功");
   }
}

定义抽象工厂类及其实现类:

// 抽象工厂类,定义统一的方法
public interface NacosFactory {
    NacosService getService();
}

// 配置服务的工厂类实现
public class ConfigNacosFactory implements NacosFactory {
    @Override
    public NacosService getService() {
        return new ConfigService();
    }
}

// 命名服务的工厂类实现
public class NamingNacosFactory implements NacosFactory {
    @Override
    public NacosService getService() {
        return new NamingService();
    }
}

客户端实现:

public class Client {

    public static void main(String[] args) {

        // 配置中心
        ConfigNacosFactory configNacosFactory = new ConfigNacosFactory();
        NacosService configService = configNacosFactory.getService();
        configService.register(new Object());

        // 注册中心
        NamingNacosFactory namingNacosFactory = new NamingNacosFactory();
        NacosService namingService = namingNacosFactory.getService();
        namingService.register(new Object());
    }
}

客户端可根据需要,创建不同的工程子类,然后通过具体的工厂子类实现具体的产品创建。关于工厂方法模式的实现,建议对照参考简单工厂模式,这样更方便理解和学习。

 

工厂方法模式的优缺点
工厂方法模式对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。

优点:

 ● 客户端只需知道具体工厂就可得到所要的产品,无须知道产品的具体创建过程;
 ● 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类;
 ● 符合开闭原则、符合单一职责原则、解决类简单工厂模式无法继承等级结构问题。
缺点:

 ● 类数量增多,新增新产品时还需要新增对应的工厂实现类;
 ● 增加了系统的抽象性和理解难度;
 ● 抽象产品只能生产一种产品,如果换一个产品的话,还是需要修改产品类的。此弊端可使用抽象工厂模式解决。


工厂方法模式的应用场景
应用场景:

 ● 客户只知道创建产品的工厂名,而不知道具体的产品名;
 ● 创建对象的任务由多个具体工厂中的某一个完成,而抽象工厂只提供创建产品的接口。
 ● 客户不关心创建产品的细节,只关心产品的品牌;


小结
就工厂模式本身而言并不难,但我们在学习设计模式时最头痛的事就是学完就忘。如果像本文这样,深刻理解了设计模式设计的初衷、使用场景以及进化历程,便更有利于记忆。本文的重点便是进行这方面思维的引导,你学到了吗?

如果文章内容有问题或想技术讨论请联系我(微信:zhuan2quan,备注Nacos),如果觉得写的还不错,值得一起学习,那就关注一下吧。

 

 

 

文章转载自公众号:程序员新视界

已于2022-8-30 11:11:35修改
收藏
回复
举报
回复
    相关推荐