[设计模式_01] 工厂模式和抽象工厂模式

设计模式分为:创建型,结构型,行为型

创建型:对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离。

结构型:关注于对象的组成以及对象之间的依赖关系,描述如何将类或者对象结合在一起形成更大的结构。

行为型:关注于对象的行为问题,是对在不同的对象之间划分责任和算法的抽象化;不仅仅关注类和对象的结构

本文主要分享如下设计模式:

  • 工厂模式
  • 工厂模式的变种(简单工厂模式)
  • 抽象工厂模式

以上三种都属于创建型。

工厂模式的几个角色说明:

产品:对接口【抽象类】进行声明。 对于所有由创建者及其子类构建的对象, 这些接口都是通用的。

具体产品:产品的不同实现。

创建者:声明返回产品对象的工厂方法。 该方法的返回对象类型必须与产品接口相匹配。创建者类的职责并不是返回产品,而是包含一些和业务相关的核心逻辑。

具体创建者:将会重写基础工厂方法, 使其返回不同类型的产品。

关系如下图:

工厂模式的使用场景:

  • 在编写代码的过程中, 如果无法预知对象确切类别及其依赖关系时, 可使用工厂方法。
  • 工厂方法将创建产品的代码与实际使用产品的代码分离, 从而能在不影响其他代码的情况下扩展产品创建部分代码。
  • 返回同一类产品的不同产品实现。

简单工厂模式

简单工厂模式:是工厂模式的简化版本,优点是简单、代码少。

如下场景:小明去手机店买手机,发现手机品牌太少,于是乎给老板建议增加手机种类,这样可以多个选择,于是老板最初就进了华为、荣耀的手机、只要告诉对应的品牌名称即可获取一台手机。

此时代码如下:

java 复制代码
// 定义一个product
public abstract class BaseMobile {
    public abstract void printlnMobileInfo();
}
// 具体实现:荣耀手机
public class HonorMobile extends BaseMobile {
    @Override
    public void printlnMobileInfo() {
        log.info("荣耀手机:干翻华为");
    }
}
@Slf4j
public class HuaWeiMobile extends BaseMobile{
    @Override
    public void printlnMobileInfo() {
        log.info("华为手机: 遥遥领先,我们还在领先,我们继续领先!");
    }
}
// 客户端:前台销售
public class MobileSimpleFactory {
    public BaseMobile getMobile(String type) {
        switch (type) {
            case "HUAWEI":
                return new HuaWeiMobile();
            case "HONOR":
                return new HonorMobile();
            default:
                return null;
        }
    }
}

上面实现的方式,如果老板想新增一种手机类型如小米,此时需要修改MobileSimpleFactory的代码。具体代码如下:

java 复制代码
public class XiaoMiMobile extends BaseMobile {
    @Override
    public void printlnMobileInfo() {
        log.info("小米手机: 这tm绝对是来捣乱的!");
    }
}
public BaseMobile getMobile(String type) {
  switch (type) {
      case "HUAWEI":
          return new HuaWeiMobile();
      case "HONOR":
          return new HonorMobile();
      case "XIAOMI":
          return new XiaoMiMobile();
      default:
          return null;
  }
}

客户端使用:只需要传入手机品牌类型即可。

java 复制代码
// 1.创建简单工厂
MobileSimpleFactory simpleFactory = new MobileSimpleFactory();
// 2.获取简单工厂创建的手机
BaseMobile huaWeiMobile = simpleFactory.getMobile("HUAWEI");
huaWeiMobile.printlnMobileInfo();
BaseMobile xiaomiMobile = simpleFactory.getMobile("XIAOMI");
xiaomiMobile.printlnMobileInfo();
BaseMobile honorMobile = simpleFactory.getMobile("HONOR");
honorMobile.printlnMobileInfo();

简单工厂模式,优点是代码简单,缺点是不符合开闭原则:即对扩展开放,对修改关闭。为了不修改现有工厂代码的情况下,

工厂模式

使用工厂模式实现:

java 复制代码
// 定义工厂方法
public interface IMobileFactory {
    BaseMobile createPhone();
}
public class XiaoMiFactory implements IMobileFactory {
    @Override
    public BaseMobile createPhone() {
      log.info("小米工厂:1998交个朋友~");
      return new XiaoMiMobile();
    }
}
@Slf4j
public class HuaWeiFactory implements IMobileFactory {
    @Override
    public BaseMobile createPhone() {
        log.info("华为工厂:遥遥领先,继续领先,领先同行一代!");
        return new HuaWeiMobile();
    }
}
@Slf4j
public class HonorFactory implements IMobileFactory {
    @Override
    public BaseMobile createPhone() {
        log.info("荣耀工厂:哦爸爸妈妈给的不少不多~");
        return new HonorMobile();
    }
}
​

客户端使用:多态的体现

java 复制代码
public static void main(String[] args) {
    IMobileFactory honorFactory = new HonorFactory();
    honorFactory.createPhone().printlnMobileInfo();
​
    IMobileFactory hwFactory = new HuaWeiFactory();
    hwFactory.createPhone().printlnMobileInfo();
​
    IMobileFactory xmFactory = new XiaoMiFactory();
    xmFactory.createPhone().printlnMobileInfo();
}

优点:符合开闭原则,如果有新的手机品牌加入只需要添加新的实现类和新的工厂类即可。不需要修改源代码。

缺点:如果子类越来越多则导致工厂类越来越多。会造成类爆炸。

初次之外,如果商品之间有联系或者存在需要分组分类别的情况下,也不利于扩展,此时需要考虑抽象工厂模式。

抽象工厂模式

抽象工厂模式:

抽象产品:一系列相关产品的定义,如一台智能手机相关的零件有:屏幕、电池、芯片、马达、摄像头模组。

具体产品:是一些相关抽象产品的不同实现,如小米手机的芯片和华为手机的芯片、苹果手机的芯片等。

抽象工厂:定义了同一组产品的各种抽象方法,如已小米手机为例:定义芯片、屏幕、电池、摄像头模组。

具体工厂:实现抽象工厂定义的方法。只能返回这一类型的产品。

抽象产品定义:

java 复制代码
public interface MobileScreen {
    void display();
}
public interface MobileChip {
    void printChip();
}
public interface MobileCamera {
    void printCamera();
}
public interface MobileBattery {
    void printBattery();
}
​

华为手机的具体产品实现:

java 复制代码
public class HuaWeiMobileBattery implements MobileBattery {
    @Override
    public void printBattery() {
      log.info("华为手机电池制造商:深圳市爱特来新能源科技股份有限公司");
    }
}
@Slf4j
public class HuaWeiMobileCamera implements MobileCamera {
    @Override
    public void printCamera() {
        log.info("华为手机摄像头:舜宇光学制造");
    }
}
@Slf4j
public class HuaWeiMobileChip implements MobileChip {
    @Override
    public void printChip() {
      log.info("华为手机芯片:麒麟自研,以前是台积电,现在未知!");
    }
}
@Slf4j
public class HuaWeiMobileScreen implements MobileScreen {
    @Override
    public void display() {
        log.info("华为手机屏幕: 京东方、天马、维信诺");
    }
}

小米手机的具体实现:

java 复制代码
public class XiaoMiMobileBattery implements MobileBattery {
    @Override
    public void printBattery() {
        log.info("Xiaomi Mobile Battery:欣旺达公司为小米供货手机电池");
    }
}
public class XiaoMiMobileCamera implements MobileCamera {
    @Override
    public void printCamera() {
        log.info("小米手机相机:中蓝、欧菲光、舜宇、豪威、三星、索尼");
    }
}
public class XiaoMiMobileChip implements MobileChip {
    @Override
    public void printChip() {
        log.info("小米手机芯片:高通设计,台积电代工 联合研发澎湃S1");
    }
}
public class XiaoMiMobileScreen implements MobileScreen {
    @Override
    public void display() {
        log.info("XiaoMiMobileScreen display: 三星,国产的华星光电新一代 C8");
    }
}

抽象工厂定义:负责定义这一系列存在关系的产品

java 复制代码
public interface IMobileFactory {
​
    MobileScreen createScreen();
​
    MobileBattery createBattery();
​
    MobileCamera createCamera();
​
    MobileChip createChip();
}

具体工厂实现:

java 复制代码
public class HuaWeiFactory implements IMobileFactory {
    @Override
    public MobileScreen createScreen() {
        return new HuaWeiMobileScreen();
    }
​
    @Override
    public MobileBattery createBattery() {
        return new HuaWeiMobileBattery();
    }
​
    @Override
    public MobileCamera createCamera() {
        return new HuaWeiMobileCamera();
    }
​
    @Override
    public MobileChip createChip() {
        return new HuaWeiMobileChip();
    }
}
public class XiaoMiFactory implements IMobileFactory {
    @Override
    public MobileScreen createScreen() {
        return new XiaoMiMobileScreen();
    }
​
    @Override
    public MobileBattery createBattery() {
        return new XiaoMiMobileBattery();
    }
​
    @Override
    public MobileCamera createCamera() {
        return new XiaoMiMobileCamera();
    }
​
    @Override
    public MobileChip createChip() {
        return new XiaoMiMobileChip();
    }
}
​

优点:不会有过多的工厂类,解决了类爆炸的情况。

缺点:新增一个品牌的话会修改很多代码,不利于分组子项的的扩展。如果新增一个马达信息,则需要在抽象产品接口定义新的马达方法,定义新的抽象产品、添加新的产品实现、在抽象工厂类里面添加新的抽象方法且需要改变各个生产工厂的代码实现。

参考资料:

相关推荐
郑道42 分钟前
Docker 在 macOS 下的安装与 Gitea 部署经验总结
后端
3Katrina44 分钟前
妈妈再也不用担心我的课设了---Vibe Coding帮你实现期末课设!
前端·后端·设计
汪子熙1 小时前
HSQLDB 数据库锁获取失败深度解析
数据库·后端
高松燈1 小时前
若伊项目学习 后端分页源码分析
后端·架构
没逻辑2 小时前
主流消息队列模型与选型对比(RabbitMQ / Kafka / RocketMQ)
后端·消息队列
倚栏听风雨2 小时前
SwingUtilities.invokeLater 详解
后端
Java中文社群2 小时前
AI实战:一键生成数字人视频!
java·人工智能·后端
王中阳Go3 小时前
从超市收银到航空调度:贪心算法如何破解生活中的最优决策谜题?
java·后端·算法
shepherd1113 小时前
谈谈TransmittableThreadLocal实现原理和在日志收集记录系统上下文实战应用
java·后端·开源
关山月3 小时前
使用 Ollama 和 Next.js 构建 AI 助手
后端