工厂模式和抽象工厂的区别是什么

今天聊一聊你们最耳熟能详的设计模式,『工厂模式』。实际上这个设计模式有三个变种,分别是『简单工厂模式』、『工厂方法模式』以及『抽象工厂模式』,可能大部人所熟知的是前两种,抽象工厂模式有必定的场景限制,不多出如今你们的视野中,不过今天咱们一并谈一谈。java

简单工厂模式

简单工厂说白了就是一个超级工厂,他能够生产各类各样的产品,产品之间无关联,好比:git

public interface SimpleFactory {

    //生产一个冰箱
    Refrigerator createRefiger();

    //生产一个空调
    AirConditioning createAirConditioning();

    //生产一个 TV
    TV createTV();
}
复制代码

通常也会有一个默认的实现:程序员

public class DefaultSimpleFactory implements SimpleFactory{

    @Override
    public Refrigerator createRefiger() {
        return new Refrigerator();
    }

    @Override
    public AirConditioning createAirConditioning() {
        return new AirConditioning();
    }

    @Override
    public TV createTV() {
        return new TV();
    }
}
复制代码

这就是一个简单工厂模式,很是的简单,尚未很强的抽象性。github

Spring 的 BeanFactory 其实就是一个简单工厂模式,他定义了一个 BeanFactory 工厂,而后会有 DefaultListableBeanFactory 去实现这个工厂声明的全部能力。面试

工厂方法模式

其实理论上来讲,能够把简单工厂模式理解为工厂方法模式的一种特例,将他的那个超级大工厂拆分红多个工厂就是工厂方法模式了。设计模式

一样有一个抽象接口表述一个工厂:微信

public interface MethodFactory {

    //生产一个冰箱
    Refrigerator createRefiger();

    //生产一个空调
    AirConditioning createAirConditioning();

    //生产一个 TV
    TV createTV();
}
复制代码

简单工厂是用一个 DefaultFactory 完成了工厂全部的能力要求。可是如今咱们的厂家变多了,有格力冰箱、海尔冰箱、海信冰箱等等,他们生产的冰箱或空调都不同,若是用简单工厂的话,就须要作区分,增长更多的方法,生产格力冰箱的,生产海尔冰箱的,很是的丑陋。markdown

工厂方法模式,须要区分不一样的工厂,这里咱们建立格力工厂、海尔工厂和海信工厂。ide

public class GeliFactory implements MethodFactory {

    @Override
    public Refrigerator createRefiger() {
        return new GeliRefrigerator();
    }

    @Override
    public AirConditioning createAirConditioning() {
        return new GeliAirConditioning();
    }

    @Override
    public TV createTV() {
        return new GeliTV();
    }
}
复制代码

格力工厂返回的是格力的空调、格力的冰箱以及格力的电视机,海尔和海信也都会返回他们本身品牌的产品,这里就不贴他们的代码了,相似。oop

这样,咱们的工厂方法对外提供了生产产品的能力,具体产生何种类型的产品,将由具体的工厂决定。这就是工厂方法模式,相信大部分人应该都不陌生。

Logpack 中就有一个典型的工厂方法,工厂抽象类 ILoggerFactory:

public interface ILoggerFactory {
    Logger getLogger(String var1);
}
复制代码

他有两个具体的工厂实现这个 getLogger 方法,

public class NOPLoggerFactory implements ILoggerFactory {
    public NOPLoggerFactory() {
    }

    public Logger getLogger(String name) {
        return NOPLogger.NOP_LOGGER;
    }
}
复制代码
public class SubstituteLoggerFactory 
            implements ILoggerFactory {
    //省略
    public synchronized Logger getLogger(String name) {
        SubstituteLogger logger = (SubstituteLogger)this.loggers.get(name);
        if (logger == null) {
            logger = new SubstituteLogger(name, this.eventQueue, this.postInitialization);
            this.loggers.put(name, logger);
        }

        return logger;
    }//省略。。。。。
}
复制代码

抽象工厂模式

抽象工厂模式可能不如前二者常见,可是确是为了补充前二者的,有特定的场景。

想象这么一种状况,你使用了工厂方法模式,你的工厂提供的能力很是多,能够生产冰箱、电视、空调、洗衣机、电脑以及桌子等等,这样你就会产生不少的工厂。

抽象工厂的做用就是在必定前提下,帮你分类这些工厂,好比按品牌分类,或者按照价格等级分类,这样会大大缩减系统中的工厂数量。

这个前提就是你的这些工厂须要在两个维度上具有共性:

image

专业术语就是『产品等级』和『产品族』两个概念,说人话就是,这些工厂须要至少具备两个共性,好比均可以按照类型区分红三类,电视机、冰箱和空调,也能够按照品牌区分红海尔、海信和 TCL。

这样他们就具有抽象工厂的前提条件,你能够按照产品族合并工厂,正如我上面使用到的例子同样,工厂对外提供生产电视、冰箱和空调三种能力,而系统按品牌存在三个工厂,因此从准确来讲,我在工厂方法中使用的例子其实也是增强版的抽象工厂模式。

代码例子就不举例了,抽象工厂其实就是帮助减小系统的工厂数量的,但前提条件就是这些工厂要具有两个及以上的共性

但愿你被面试官问道工厂方法和抽象工厂的区别的时候,能想起这一句话。


关注公众不迷路,一个爱分享的程序员。

公众号回复「1024」加做者微信一块儿探讨学习!

公众号回复「面试题」送你一份面试题以及做者的做答答案

每篇文章用到的全部案例代码素材都会上传我我的 github

github.com/SingleYam/o…

欢迎来踩!

相关文章
相关标签/搜索