当前位置: 首页 >  网技达人 >  工厂模式之工厂方法模式

工厂模式之工厂方法模式

导读:大家好,欢迎来到程序视点!.前言.在上一节的简单工厂模式中,我们知道简单工厂所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。.也就是说,类的创建依赖工厂类,如果想要拓展程序(添加新的类),必须对工厂类进行修改。这违背了开闭原则。.从设计角度考虑,有一定的

大家好,欢迎来到程序视点!

前言

在上一节的简单工厂模式中,我们知道简单工厂所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。

也就是说,类的创建依赖工厂类,如果想要拓展程序(添加新的类),必须对工厂类进行修改。这违背了开闭原则。

从设计角度考虑,有一定的问题,如何解决?

既然要遵循【开闭原则】,工厂类肯定是不能修改了。那就只能用新的工厂来创建新的类–具体的类由具体的工厂来创建.

新添加的“具体的类”可能是不确定的,可能是“XiaomiPhone”,也有可能是“OppoPhone”,还可能是未来会出现的“XXXPhone”…那它们对应的工厂类就应该有“XiaomiPhoneFactory”,“OppoPhoneFactory”,“XXXPhoneFactory”…

我们把这些工厂类进一步抽象,就形成了我们接下来要讲的工厂方法模式

工厂方法模式简介

定义一个创建对象的抽象方法,且可以创建多个不同的工厂类实现该抽象方法。要创建某个具体的类,就新增一个具体的工厂类;这个工厂类通过实现抽象方法来创建类。这就是我们说的工厂方法模式

这样的好处就是:想要新创建一个类,不用修改原来的类,而是自己新建一个属于自己的工厂类。

从上面的描述中,我们可以抽象出这么几个角色:

  • 抽象工厂:用来声明抽象方法的。 返回值就是产品抽象类。
  • 产品类工厂:专门生产某个具体产品的工厂类。
  • 产品抽象类:工厂类能创建出来的所有产品类的抽象。它负责描述所有实例所共有的公共接口。(这里必须要一个抽象类,不然不能保证返回的不同的产品类属于同一个类型)
  • 产品类:工厂类创建出来的目标。它(们)是产品抽象类的具体实现。

示例

抽象工厂:

public interface PhoneFactory {
  public Phone createPhone();
}

怎么是个接口呢?只有抽象方法的类,当然可以声明为接口呀!
产品类工厂:“HuaweiPhoneFactory”和“ApplePhoneFactory”

public class HuaweiPhoneFactory 
              implements PhoneFactory {
  public Phone createPhone() {
    return new HuaweiPhone();
  }
}



public class ApplePhoneFactory 
              implements PhoneFactory {
  public Phone createPhone() {
    return new ApplePhone();
  }
}

让我们来测试下:

public class Test {
  public static void main(String[] args) {
    PhoneFactory huaweiPhoneFactory = new HuaweiPhoneFactory();

    Phone phone1 = huaweiPhoneFactory.createPhone();
    System.out.println(phone1.info());

    PhoneFactory applePhoneFactory = new ApplePhoneFactory();
    Phone phone2 = applePhoneFactory.createPhone();
    System.out.println(phone2.info());
  }
}

输出:
我是华为手机
我是苹果手机

咿呀!和简单工厂模式一样的呐!

现在我们要创建“小米手机”啦
新增一个 XiaomiPhone 的实体类:

public class XiaomiPhone implements Phone{
  @Override
  public String info() {
    return "我是小米手机";
  }
}

新增一个创建 XiaomiPhone 对象的工厂类:

public class XiaomiPhoneFactory 
              implements PhoneFactory {
  public Phone createPhone() {
    return new XiaomiPhone();
  }
}

测试一下:

public class Test {
  public static void main(String[] args) {
    PhoneFactory xiaomiPhoneFactory = new XiaomiPhoneFactory();

    Phone phone3 = xiaomiPhoneFactory.createPhone();
    System.out.println(phone3.info());
  }
}

输出:
我是小米手机

哈哈!我们没有修改之前的HuaweiPhoneFactory或ApplePhoneFactory两个工厂类,通过新增XiaomiPhoneFactory工厂类的方式来生产新的XiaomiPhone

🆗,这样我们就完成了工厂方法模式创建和使用。

工厂方法模式的问题

工厂方法模式有什么问题呢?我们先来看一个场景:

现在“华为”和“苹果”都要开始生产电脑了。“华为”只能生产“华为电脑”,“苹果”只能生产“苹果电脑”。

按照上述的工厂方法模式,那就必然对应的抽象类、实体抽象类、实体类和实体工厂类。
抽象工厂:

public interface ComputerFactory {
  public Computer createComputer();
}



public abstract class Computer {
  public abstract String getName();
}



public class HuaweiComputer extends Computer{
  @Override
  public String getName() {
    return "我是华为电脑";
  }
}



public class AppleComputer extends Computer{
  @Override
  public String getName() {
    return "我是苹果电脑";
  }
}

产品类工厂:“HuaweiComputerFactory”和“AppleComputerFactory”

public class HuaweiComputerFactory
              implements ComputerFactory {
  public Computer createComputer() {
    return new HuaweiComputer();
  }
}



public class AppleComputerFactory 
              implements ComputerFactory {
  public Computer createComputer() {
    return new AppleComputer();
  }
}

🆗,Cool!我们一下就搞定了!

接着,“华为”和“苹果”都要开始生产智能手表了。“华为”只能生产“华为手表”,“苹果”只能生产“苹果手表”。

再接着,“华为”和“苹果”都要开始生产音响了。“华为”只能生产“华为音响”,“苹果”只能生产“苹果音响”。

…耳机,服务器,汽车等等

哇!随着产品类的增多,我们的工厂类似乎也增加了。这还不重要的,问题出在下面:

突然,我们要进行手机和电脑配对链接了!

public class Test {
  public static void main(String[] args) {
    PhoneFactory huaweiPhoneFactory = new HuaweiPhoneFactory();
    Phone phone1 = huaweiPhoneFactory.createPhone();

    PhoneFactory applePhoneFactory = new ApplePhoneFactory();
    Phone phone2 = applePhoneFactory.createPhone();

    ComputerFactory huaweiComputerFactory = new HuaweiComputerFactory();
    Computer computer1 = huaweiComputerFactory.createComputer();

    ComputerFactory appleComputerFactory = new AppleComputerFactory();
    Computer computer2 = appleComputerFactory.createComputer();

    // 匹配
    match(phone1, computer2);
  }

  public static void match(Phone p, Computer c) {
   System.out.println(p.info() + "===" + c.getName()) 
  }
}

输出:
我是华为手机===我是苹果电脑

看到了?华为手机匹配连接到苹果电脑上了!

大家知道问题了吗?怎么解决这个问题呢?我们下期见!

更多信息,请关注同名公众号【程序视点】,提前预览~

内容
  • RocketMQ消费者是如何负载均衡的
    RocketMQ消费者是如何负载
    2023-12-09
    摘要:RocketMQ 支持两种消息模式:集群消费( Clustering )和广播消费( Broadcasting )
  • 2分钟快速上手流水线的创建与运行
    2分钟快速上手流水线的创建与运行
    2023-12-09
    摘要: 通过流水线新手体验模板,体验一条含代码检查、构建阶段、部署发布常用流水线的创建与执行。.本文分享自华为云社区《2
  • FlashDuty Changelog 2023-09-07 | 新增深色模式与主题配置
    FlashDuty Change
    2023-12-04
    FlashDuty:一站式告警响应平台,前往此地址免费体验!.FlashDuty.现在已经全面支持了深色模式,这为您提供
  • 云存储解决方案
    云存储解决方案
    2024-01-10
    云存储解决方案.随着互联网技术的不断发展,越来越多的企业开始意识到数据存储和管理的重要性。传统的本地存储方式已经不能满足
  • ***容灾与高可用解决方案
    ***容灾与高可用解决方案
    2024-01-15
    ***容灾与高可用解决方案.在当今数字化时代,***无疑是企业信息技术基础设施中最为关键的一环。因此,***容灾与高可用
  • ***集群架构规划与设计
    ***集群架构规划与设计
    2023-12-16
    ***集群架构规划与设计.概述.随着互联网和大数据技术的快速发展,企业对***的性能和稳定性要求越来越高。为了满足这些需
  • ***安全加固与防护方案
    ***安全加固与防护方案
    2024-01-10
    ***安全加固与防护方案.随着互联网的快速发展,***安全问题日益凸显。一旦***遭受攻击,可能导致数据泄露、服务中断甚
  • ***虚拟化技术咨询服务
    ***虚拟化技术咨询服务
    2023-12-21
    ***虚拟化技术咨询服务.在当今数字化时代,***虚拟化技术越来越受到企业和个人用户的青睐。虚拟化技术通过将物理***划
  • ***监控与报警服务
    ***监控与报警服务
    2023-12-06
    ***监控与报警服务.在当今互联网时代,***监控与报警服务变得至关重要。随着互联网技术的不断发展,***已成为企业运营
  • 高温高压电子元件生产
    高温高压电子元件生产
    2023-12-21
    高温高压电子元件生产.随着科技的不断发展,高温高压电子元件在现代电子设备中扮演着*益重要的角色。在工业、航空航天、汽车等
  • ***迁移与升级解决方案
    ***迁移与升级解决方案
    2024-01-05
    ***迁移与升级解决方案.随着业务的不断扩大和发展,很多企业逐渐意识到原有的***已经不能满足日益增长的需求,因此需要进
  • 定制化电子元件解决方案
    定制化电子元件解决方案
    2024-01-15
    定制化电子元件解决方案.在现代科技发展迅速的时代,电子元件的需求日益增加,同时对于定制化的需求也在不断提升。定制化电子元
  • 全球电子元件市场趋势分析
    全球电子元件市场趋势分析
    2023-12-31
    全球电子元件市场趋势分析.近年来,全球电子元件市场呈现出不断增长的趋势。随着科技的不断发展和智能设备的普及,电子元件市场