几分钟时刻,试着学一下笼统工厂形式

简介

本文准备介绍一下,工厂形式中的最终一种形式——笼统工厂形式。之前介绍了,工厂办法形式感兴趣的童鞋能够看下这篇文章,讲个故事,看看能不能了解工厂办法形式。

本文经过讲故事的办法,来解说笼统工厂形式,其中包含了许多的代码,可是代码内容都不难,很简单了解。期望您能耐性看完。

工厂形式的品种

几分钟时间,试着学一下抽象工厂模式

界说

提取产品的共同特征,并将其分类。具有相同特征的产品为同一产品族。同一个产品族共用一个工厂类。即一切产品能够经过多个维度进行分类。
比较于工厂办法形式,削减了详细工厂类的数量。

光看界说肯定太笼统了。接下经过详细需求,来了解一下笼统工厂形式的运用场景。

新的需求

2023年,新能源轿车市场前景一片大好。毕业生小白经过组长的协助,学会了工厂办法形式的运用。同时写了一篇文章,讲个故事,看看能不能了解工厂办法形式。

这次,组长又把他叫了过来,跟他说,丰田最近新出了一款电动车叫做BZ4X。比亚迪也新出了电动车汉EV和唐DMI。你啊,把这几款车,连同卡罗拉双擎,一起录入到程序里。让用户能够快速的查询到这几款车的相关信息。

处理办法

由于小白之前已经学会了工厂办法形式,这次直接现学现用,写出了工厂办法形式的写法。

工厂办法的处理办法

笼统产品 ICar

小白抽取了一切轿车产品中的共同特性(价格,名称,品种),将他们笼统到了一个接口ICar中。

/**
 * Author(作者):jtl
 * Date(日期):2023/2/14 17:39
 * Detail(概况):笼统产品
 */
public interface ICar {
    void name();
    void price();
    void kind();
    default void detail(){
        System.out.println("-------分割线-------");
        name();
        kind();
        price();
    }
}

详细产品 丰田BZ4X

让丰田的电动车BZ4X,完成了ICar接口。

/**
 * Author(作者):jtl
 * Date(日期):2023/2/14 18:02
 * Detail(概况):丰田BZ4X,电动车
 */
public class BZ4X implements ICar {
    @Override
    public void name() {
        System.out.println("丰田-BZ4X");
    }
    @Override
    public void price() {
        System.out.println("23.48w");
    }
    @Override
    public void kind() {
        System.out.println("电动轿车");
    }
    public void biggestContinueVoyageCourse(){
        System.out.println("最大续航:615km");
    }
}

详细产品 丰田卡罗拉双擎

让丰田的混动车卡罗拉双擎,完成了ICar接口。

/**
 * Author(作者):jtl
 * Date(日期):2023/2/14 18:08
 * Detail(概况):丰田卡罗拉双擎,混动车
 */
public class CorollaHybrid implements ICar {
    @Override
    public void name() {
        System.out.println("丰田-卡罗拉双擎");
    }
    @Override
    public void price() {
        System.out.println("13.98w");
    }
    @Override
    public void kind() {
        System.out.println("混动轿车");
    }
    public void fuelConsumption(){
        System.out.println("油耗4.2L/100km");
    }
}

详细产品 比亚迪唐DMI

让比亚迪的混动车唐DMI,完成了ICar接口。

/**
 * Author(作者):jtl
 * Date(日期):2023/2/14 17:59
 * Detail(概况):比亚迪唐DMI,混动车
 */
public class TangDMI implements ICar {
    @Override
    public void name() {
        System.out.println("比亚迪-唐DMI");
    }
    @Override
    public void price() {
        System.out.println("28.18w");
    }
    @Override
    public void kind() {
        System.out.println("混动轿车");
    }
    public void fuelConsumption(){
        System.out.println("油耗3.64L/100km");
    }
}

详细产品 比亚迪汉EV

让比亚迪的电动车汉EV,完成了ICar接口。

/**
 * Author(作者):jtl
 * Date(日期):2023/2/14 17:39
 * Detail(概况):比亚迪汉EV,电动车
 */
public class HanEV implements ICar {
    @Override
    public void name() {
        System.out.println("比亚迪-汉EV");
    }
    @Override
    public void price() {
        System.out.println("23w");
    }
    @Override
    public void kind() {
        System.out.println("电动轿车");
    }
    public void biggestContinueVoyageCourse(){
        System.out.println("最大续航:605km");
    }
}

笼统工厂 IFactory

有了产品,就要有相对应的轿车工厂。笼统出一个接口,让这个接口能够生成ICar。

/**
 * Author(作者):jtl
 * Date(日期):2023/2/14 18:17
 * Detail(概况):笼统工厂接口
 */
public interface IFactory {
    ICar buildCar();
}

详细工厂,BZ4X工厂

完成了笼统工厂接口的详细工厂,用来出产BZ4X。

/**
 * Author(作者):jtl
 * Date(日期):2023/2/14 18:23
 * Detail(概况):BZ4X,详细工厂
 */
public class BZ4XFactory implements IFactory{
    @Override
    public ICar buildCar() {
        return new BZ4X();
    }
}

详细工厂,丰田卡罗拉工厂

完成了笼统工厂接口的卡罗拉工厂,用来出产丰田卡罗拉双擎。

/**
 * Author(作者):jtl
 * Date(日期):2023/2/14 18:19
 * Detail(概况):丰田卡罗拉,详细工厂
 */
public class CorollaFactory implements IFactory {
    @Override
    public ICar buildCar() {
        return new CorollaHybrid();
    }
}

详细工厂,汉EV工厂

完成了笼统工厂接口的汉EV工厂,用来出产汉EV。

/**
 * Author(作者):jtl
 * Date(日期):2023/2/14 18:19
 * Detail(概况):汉EV,详细工厂
 */
public class HanEVFactory implements IFactory {
    @Override
    public ICar buildCar() {
        return new HanEV();
    }
}

详细工厂,唐DMI工厂

唐DMI工厂,用来出产唐DMI。

/**
 * Author(作者):jtl
 * Date(日期):2023/2/14 18:19
 * Detail(概况):唐DMI,详细工厂
 */
public class TangDMIFactory implements IFactory {
    @Override
    public ICar buildCar() {
        return new TangDMI();
    }
}

客户端代码

/**
 * Author(作者):jtl
 * Date(日期):2023/2/14 18:26
 * Detail(概况):客户端
 */
public class Client {
    public static void main(String[] args) {
        // 我要获取一辆汉EV
        IFactory hanEVFactory = new HanEVFactory();
        hanEVFactory.buildCar().detail();
        // 我要获取一辆唐DMI
        IFactory tangDMIFactory = new TangDMIFactory();
        tangDMIFactory.buildCar().detail();
        // 我要获取一辆卡罗拉
        IFactory corollaFactory = new CorollaFactory();
        corollaFactory.buildCar().detail();
        // 我要获取一辆BZ4X
        IFactory bz4XFactory = new BZ4XFactory();
        bz4XFactory.buildCar().detail();
    }
}

工厂办法客户端运转成果

上述代码的运转成果如下。

几分钟时间,试着学一下抽象工厂模式

工厂办法的窘境

小白,看着自己的代码,感觉很满意。这时组长大宇过来看了一眼,略带欣慰的说道,不错上次刚教你的工厂办法形式,这么快就学会了。
不过你这么写有一个小坏处,便是市面上那么多的车,你这得写多少个工厂啊?
小白听到这话,下意识的答复到,有多少车就写多少个工厂呗。刚说完这句话,他就明白为什么组长会问这个问题了。
过多的产品会导致呈现过的工厂。会形成Class类文件过多,包的体积会变大。刚刚对自己很满意的小白,瞬间陷入了深思。

特别的工厂办法——笼统工厂

组长看着紧皱眉头的小白,笑着说道。”小白你先别急,工厂形式里,除了工厂办法形式不是还有一个笼统工厂呢嘛。笼统工厂便是为了处理你碰到的这个问题,而发生的。“

”你能够把这些轿车啊,进行分类,比如说把一切车经过品牌进行分类。这样你例子中的车就被分红比亚迪品牌(唐DMI和汉EV),丰田品牌(卡罗拉双擎,BZ4X)。“

”你再观察下,这4辆车中,唐DMI和卡罗拉双擎是混动车。BZ4X和汉EV是电动车。那么我们就能够根据他们的品种进行详细区分。“

”比亚迪品牌下的车能够区分为电动车(EV)和混动车(HEV)。丰田品牌下的车也能够分为电动车(EV)和混动车(HEV)。“

”接下来,我们能够把同一品牌下不同品种的车型,看作一个产品族。这么说或许有点绕,我把代码发给你,你直接看代码了解下吧。“

笼统工厂代码

小白拿到代码后,对比着方才大宇组长的话,思索起来。

笼统电动轿车接口 IEV

将一切产品进行分类,电动车笼统到IEV接口中。

public interface IEV {
    void name();
    void price();
    default void kind(){
        System.out.println("EV 电动车");
    }
    void biggestContinueVoyageCourse();
    default void detail(){
        System.out.println("-------分割线-------");
        name();
        kind();
        biggestContinueVoyageCourse();
        price();
    }
}

笼统混动轿车产品 IHEV

将一切产品进行分类,混动车笼统到IHEV接口中。

public interface IHEV {
    void name();
    void price();
    default void kind(){
        System.out.println("HEV(混动轿车)");
    }
    void fuelConsumption();
    default void detail(){
        System.out.println("-------分割线-------");
        name();
        kind();
        fuelConsumption();
        price();
    }
}

详细产品 丰田BZ4X

详细产品要完成笼统产品接口。丰田BZ4X是电动车,所以完成IEV接口。

public class BZ4X implements IEV {
    @Override
    public void name() {
        System.out.println("丰田-BZ4X");
    }
    @Override
    public void price() {
        System.out.println("23.48w");
    }
    @Override
    public void kind() {
        System.out.println("电动轿车");
    }
    @Override
    public void biggestContinueVoyageCourse(){
        System.out.println("最大续航:615km");
    }
}

详细产品 丰田卡罗拉双擎

丰田卡罗拉双擎是混动车,所以完成IHEV接口。

public class CorollaHybrid implements IHEV {
    @Override
    public void name() {
        System.out.println("丰田-卡罗拉双擎");
    }
    @Override
    public void price() {
        System.out.println("13.98w");
    }
    @Override
    public void kind() {
        System.out.println("混动轿车");
    }
    public void fuelConsumption(){
        System.out.println("油耗4.2L/100km");
    }
}

详细产品 比亚迪唐DMI

比亚迪唐DMI是混动车,所以完成IHEV接口。

public class TangDMI implements IHEV {
    @Override
    public void name() {
        System.out.println("比亚迪-唐DMI");
    }
    @Override
    public void price() {
        System.out.println("28.18w");
    }
    @Override
    public void kind() {
        System.out.println("混动轿车");
    }
    @Override
    public void fuelConsumption(){
        System.out.println("油耗3.64L/100km");
    }
}

详细产品 比亚迪汉EV

比亚迪汉EV是电动车,所以完成IEV接口。

public class HanEV implements IEV {
    @Override
    public void name() {
        System.out.println("比亚迪-汉EV");
    }
    @Override
    public void price() {
        System.out.println("23w");
    }
    @Override
    public void kind() {
        System.out.println("电动轿车");
    }
    @Override
    public void biggestContinueVoyageCourse(){
        System.out.println("最大续航:605km");
    }
}

笼统工厂接口

笼统出一个IFactory工厂接口,接口中能够出产EV车型和HEV车型。

/**
 * Author(作者):jtl
 * Date(日期):2023/2/14 18:17
 * Detail(概况):笼统工厂接口
 */
public interface IFactory {
    IEV creatEV();
    IHEV creatHEV();
}

详细工厂,BYD工厂

让详细工厂,BYDFactory完成IFactory接口。出产的EV产品为HanEV。出产的HEV产品为TangDMI。

public class BYDFactory implements IFactory{
    @Override
    public IEV creatEV() {
        return new HanEV();
    }
    @Override
    public IHEV creatHEV() {
        return new TangDMI();
    }
}

详细工厂,Toyota工厂

让详细工厂,ToyotaFactory完成IFactory接口。出产的EV产品为BZ4X。出产的HEV产品为CorollaHybrid。

public class ToyotaFactory implements IFactory{
    @Override
    public IEV creatEV() {
        return new BZ4X();
    }
    @Override
    public IHEV creatHEV() {
        return new CorollaHybrid();
    }
}

客户端代码

public class Client {
    public static void main(String[] args) {
        // 获取BYD工厂联系方式
        IFactory bydFactory = new BYDFactory();
        // BYD工厂出产电动车-汉EV
        bydFactory.creatEV().detail();
        // BYD工厂出产混动车-唐DMI
        bydFactory.creatHEV().detail();
        // 获取丰田工厂联系方式
        IFactory toyotaFactory = new ToyotaFactory();
        // 丰田工厂出产电动车-BZ4X
        toyotaFactory.creatEV().detail();
        // 丰田工厂出产混动车-卡罗拉双擎
        toyotaFactory.creatHEV().detail();
    }
}

笼统工厂运转成果

几分钟时间,试着学一下抽象工厂模式

看着运转成果,小白一脸佩服的看着大宇组长对他说道,这样就能够削减许多的工厂类了。大宇组长答复到,是的这样会削减许多工厂类。削减打包后的程序的体积。可是笼统工厂的前提,有必要是在一切的产品能够进行区分,分出产品族的基础上。假如方才的例子里,多了一个比亚迪的自行车,笼统工厂是不是就没法用了。小白恍然大明白的答复道,组长你说的好有道理啊。

工厂办法与笼统工厂的差异

工厂办法形式人物

经过上述例子能够看出,工厂办法形式中有4个人物。

  1. 笼统产品ICar
  2. 笼统工厂IFactory
  3. 实践产品BZ4XTangDMIHanEV等。实践产品完成了ICar接口
  4. 实践工厂BZ4XFactoryHanEVFactory等。实践工厂完成了IFactory接口

工厂办法形式特点

每新增一个产品,就会呈现一个相对应的工厂。这样的好处是,每次新增产品不会修正已有代码,满意了开闭准则
可是缺点便是会形成太多的类冗余:比如说,我要新增一个小鹏P7的类,就会呈现一个XiaoPengP7目标,和一个XiaoPengP7Factory工厂
假如我要新增10000个产品,就会呈现10000个相关类和10000个相对应的工厂。这样会形成Class文件太多。


笼统工厂形式人物

相较于工厂办法形式许多产品类,类的总数过多的状况。笼统工厂形式能够必定程度上的处理这个问题。

  1. 笼统产品IEVIHEV
  2. 笼统工厂IFactory
  3. 实践产品BZ4XTangDMIHanEV等。实践产品中根据品种差异,分别完成了IEV接口以及IHEV接口
  4. 实践工厂BYDFactoryToyotaFactory等。实践工厂完成了IFactory接口

笼统工厂将一切产品进行了更细一步的划分,将车型分红了电动车EV混动车HEV。并且呈现了产品族的概念。

一切比亚迪的电动车混动车能够看作是一个比亚迪轿车产品族

丰田的电动车混动车是一个丰田轿车的产品族

同一品牌的轿车共用一个Factory工厂,这个Factory中能够出产EV车型HEV车型

总结

笼统工厂能够必定程度上的处理工厂办法形式类数量过多的问题。所以能够把它看作工厂办法形式在特定状况下的一种特别写法。
产品族的概念,便是将一切产品进行分类的一种方式。这个产品族没有特别的界说,能够根据实践状况进行分类。
比如上面例子中,我是以车企进行的分类。可是换个思路,也能够经过电动车或许混动车进行分类。那样的话,呈现的就不是BYDFactoryToyotaFactory而是EVFactoryBYDFactory了。
详细代码不再细写,大家了解就好。

后记

接下来是讨口儿环节。

本文收录在学习规划形式的办法,少走弯路,这篇文章中。
相关代码在Github:DesignPattern, 假如感兴趣能够给项目一个Star重视一下。

写文章不易,假如您觉得对您有那么一丢丢的协助的话,期望您能点赞支撑下哈。感谢您的支撑。下篇文章我们不见不散。