【设计模式 03】抽象工厂模式

news2024/12/23 16:47:44

一个具体的工厂,可以专门生产单一某一种东西,比如说只生产手机。但是一个品牌的手机有高端机、中端机之分,这些具体的属于某一档次的产品都需要单独建立一个工厂类,但是它们之间又彼此关联,因为都共同属于一个品牌。我们说这种叫做“多类”对象

除了手机之外,还有比如沙发、茶几、椅子,不同于手机的高端型号和低端型号,取而代之的可以是不同的样式风格,比如古典风格的和现代风格的。每一种风格的产品都需要单独建立一个工厂类,但是他们本质上都属于同一样东西。我们可以从这个角度理解“多类对象”,即,就是同一对象的多种类别。

图中包含以下元素:

  • 抽象产品接口:AbstractProduct
  • 具体产品类:ConcreteProduct
  • 抽象工厂接口:AbstractFactory
  • 具体工厂类:ConcreateFactory

 Java代码:

// 1. 定义抽象产品
// 抽象产品A
interface ProductA {
    void display();
}

// 抽象产品B
interface ProductB {
    void show();
}

// 2. 实现具体产品类
// 具体产品A1
class ConcreteProductA1 implements ProductA {
    @Override
    public void display() {
        System.out.println("Concrete Product A1");
    }
}

// 具体产品A2
class ConcreteProductA2 implements ProductA {
    @Override
    public void display() {
        System.out.println("Concrete Product A2");
    }
}

// 具体产品B1
class ConcreteProductB1 implements ProductB {
    @Override
    public void show() {
        System.out.println("Concrete Product B1");
    }
}

// 具体产品B2
class ConcreteProductB2 implements ProductB {
    @Override
    public void show() {
        System.out.println("Concrete Product B2");
    }
}

// 3. 定义抽象工厂接口
interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}

// 4. 实现具体工厂类
// 具体工厂1,生产产品A1和B1
class ConcreteFactory1 implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ConcreteProductA1();
    }

    @Override
    public ProductB createProductB() {
        return new ConcreteProductB1();
    }
}

// 具体工厂2,生产产品A2和B2
class ConcreteFactory2 implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ConcreteProductA2();
    }

    @Override
    public ProductB createProductB() {
        return new ConcreteProductB2();
    }
}

// 客户端代码
public class AbstractFactoryExample {
    public static void main(String[] args) {
        // 使用工厂1创建产品A1和产品B1
        AbstractFactory factory1 = new ConcreteFactory1();
        ProductA productA1 = factory1.createProductA();
        ProductB productB1 = factory1.createProductB();
        productA1.display();
        productB1.show();

        // 使用工厂2创建产品A2和产品B2
        AbstractFactory factory2 = new ConcreteFactory2();
        ProductA productA2 = factory2.createProductA();
        ProductB productB2 = factory2.createProductB();
        productA2.display();
        productB2.show();
    }
}

为了避免跟之前的工厂方法模式混淆,这里做一个区别:

  • 简单工厂模式:一个工厂方法创建所有具体产品
  • 工厂方法模式:一个工厂方法创建一个具体产品
  • 抽象工厂模式:一个工厂方法创建一个具体产品的某一类

典型的应用场景是,使用抽象工厂模式来创建与不同数据库的连接对象。

总结一下就是抽象工厂模式特别适用于一系列相关或相互依赖的产品被一起创建的情况。

当需要增加新产品时(是新产品而不是某一产品的新型号),则需要增加新的具体产品类,然后修改抽象工厂接口以及所有的具体工厂类,扩展性相对较差。

【设计模式专题之抽象工厂模式】3. 家具工厂

CPP版代码:

#include <iostream>
#include <string>
 
// 抽象椅子接口
class Chair {
public:
    virtual void showInfo() = 0;
};
 
// 具体现代风格椅子
class ModernChair : public Chair {
public:
    void showInfo() override {
        std::cout << "modern chair" << std::endl;
    }
};
 
// 具体古典风格椅子
class ClassicalChair : public Chair {
public:
    void showInfo() override {
        std::cout << "classical chair" << std::endl;
    }
};
 
// 抽象沙发接口
class Sofa {
public:
    virtual void displayInfo() = 0;
};
 
// 具体现代风格沙发
class ModernSofa : public Sofa {
public:
    void displayInfo() override {
        std::cout << "modern sofa" << std::endl;
    }
};
 
// 具体古典风格沙发
class ClassicalSofa : public Sofa {
public:
    void displayInfo() override {
        std::cout << "classical sofa" << std::endl;
    }
};
 
// 抽象家居工厂接口
class FurnitureFactory {
public:
    virtual Chair* createChair() = 0;
    virtual Sofa* createSofa() = 0;
};
 
// 具体现代风格家居工厂
class ModernFurnitureFactory : public FurnitureFactory {
public:
    Chair* createChair() override {
        return new ModernChair();
    }
 
    Sofa* createSofa() override {
        return new ModernSofa();
    }
};
 
// 具体古典风格家居工厂
class ClassicalFurnitureFactory : public FurnitureFactory {
public:
    Chair* createChair() override {
        return new ClassicalChair();
    }
 
    Sofa* createSofa() override {
        return new ClassicalSofa();
    }
};
 
int main() {
    // 读取订单数量
    int N;
    std::cin >> N;
 
    // 处理每个订单
    for (int i = 0; i < N; i++) {
        // 读取家具类型
        std::string furnitureType;
        std::cin >> furnitureType;
 
        // 创建相应风格的家居装饰品工厂
        FurnitureFactory* factory = nullptr;
        if (furnitureType == "modern") {
            factory = new ModernFurnitureFactory();
        } else if (furnitureType == "classical") {
            factory = new ClassicalFurnitureFactory();
        }
 
        // 根据工厂生产椅子和沙发
        Chair* chair = factory->createChair();
        Sofa* sofa = factory->createSofa();
 
        // 输出家具信息
        chair->showInfo();
        sofa->displayInfo();
 
        // 释放动态分配的对象
        delete chair;
        delete sofa;
        delete factory;
    }
 
    return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1489493.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据可视化原理-腾讯-散点图

在做数据分析类的产品功能设计时&#xff0c;经常用到可视化方式&#xff0c;挖掘数据价值&#xff0c;表达数据的内在规律与特征展示给客户。 可是作为一个产品经理&#xff0c;&#xff08;1&#xff09;如果不能够掌握各类可视化图形的含义&#xff0c;就不知道哪类数据该用…

白银期货开户交割规则有哪些?

白银期货交割是指期货合约到期时&#xff0c;交易双方通过该期货合约所载商品所有权的转移&#xff0c;了结到期未平仓合约的过程。小编在此为大家详细介绍白银期货的交割规则有哪些。白银期货的交割规则有哪些&#xff1f;白银期货的交割规则主要有&#xff1a; 一、交割商品…

echarts如何实现3D饼图(环形图)?

一、实现的效果 二、具体步骤 1.安装依赖 npm install echarts 2.引入echarts import * as echarts from echarts; 注意&#xff1a;这里需要用到echarts-gl&#xff0c;必须单独引入才可以 import echarts-gl; 3.echarts部分代码 我知道这部分内容很多&#xff0c;但只要cv…

【ES入门一:基础概念】

集群层面上的基础概念 集群 由多个es实例组成的叫做集群 节点 单个ES的服务实例叫做节点。每个实例都有自己的名字&#xff0c;就是在配置文件中配置的‘node.name’中的内容。为了标识每个节点&#xff0c;每个节点启动后都会分配一个UID&#xff0c;存储在data目录。每个…

第七十四天漏洞发现-Web框架中间件插件BurpSuite浏览器被动主动探针

第74天 漏洞发现-Web框架中间件插件&BurpSuite&浏览器&被动&主动探针 最近几天都是演示工具如何使用如&#xff1a;AWVS、Nessus、nexpose等综合性利用工具。 Burp插件和漏扫工具的区别 知识点&#xff1a; 1、浏览器插件&BurpSuite插件 2、Hack-Tools&…

基于协同过滤的旅游推荐系统设计与实现

基于协同过滤的旅游推荐系统设计与实现 在当今旅游业蓬勃发展的背景下&#xff0c;人们对于旅游体验的需求日益增加&#xff0c;如何为用户提供更加个性化、精准的旅游推荐成为了旅游行业的一个重要课题。为解决这一问题&#xff0c;我们设计并实现了一个基于协同过滤的旅游推…

“互动+消费”时代,借助华为云GaussDB重构新零售中消费逻辑

场与人的关系 “人—货—场”是零售中重要的三要素&#xff0c;我们一直在追求&#xff0c;将零售中的人、货、场进行数字化并在云端进行整合&#xff0c;形成属于我们自己的云平台。 随着互联网技术为信息提供的便利&#xff0c;消费者的集体力量正在逐渐形成一股强大的反向…

RabbitMQ的整体架构是怎么样的?

RabbitMQ是一个开源的消息中间件&#xff0c;用于在应用程序之间传递消息。它实现了AMQP(高级消息队列协议)并支持其他消息传递协议&#xff0c;例如STOMP(简单文本定向消息协议)和MQTT&#xff08;物联网协议&#xff09; 他的整体架构大致如下&#xff1a; Producer&#xf…

【NVCC,CUDA,NVIDIA驱动】装了pytorch,nvcc -V不能用,但能正常使用gpu

这里写目录标题 问题描述问题原理为什么anaconda安装的Pytorch&#xff0c;其能够直接在gpu上运行NVCC是什么&#xff0c;怎么查看装没装 如果没有NVCC文件夹&#xff0c;应该如何安装NVCC&#xff1f;CUDNN&#xff1a;Local Installer for Linux x86_64和Local Installer for…

小程序开通流量主

开发小程序有一段时间了&#xff0c;误打误撞开通了流量主。到现在有2400人访问了&#xff0c;当然这是累计的&#xff0c;每天访问人数也就是平均七八十左右。 当然&#xff0c;每日还是有一些收入的&#xff0c;虽然比较低&#xff0c;一块钱上下&#xff1a; 感觉做小程序&…

hnust 湖南科技大学 2022 数据挖掘课设 完整代码+报告+图源文件+指导书

hnust 湖南科技大学 2022 数据挖掘课设 完整代码报告图源文件指导书 目录 实验一 Apriori算法设计与应用 - 1 - 一、 背景介绍 - 1 - 二、 实验内容 - 1 - 三、 实验结果与分析 - 2 - 四、 小结与心得体会 - 3 - 实验二 KNN算法设计与应用 - 4 - 一、 背景介绍 - 4 - 二、 实…

NLP评价指标

一、分类任务常见评估&#xff1a; 准确度(Accuracy) 评估预测正确的比例&#xff0c;精确率(Precision) 评估预测正例的查准率&#xff0c;召回率(Recall) 评估真实正例的查全率。如果是多分类&#xff0c;则每个类别各自求P、R最终求平均值。 TP&#xff08;True Positives…

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:分布式迁移标识)

组件的分布式迁移标识&#xff0c;指明了该组件在分布式迁移场景下可以将特定状态恢复到对端设备。 说明&#xff1a; 从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 restoreId restoreId(value: number) 标记支持分布式…

Java_二叉树

文章目录 一、二叉树1.树型结构2.概念&#xff08;重要&#xff09;3.树的表示形式&#xff08;了解&#xff09;4.树的应用5.二叉树的概念6.两种特殊的二叉树7.二叉树的性质练习 8.二叉树的存储9.二叉树的遍历手动创建二叉树1、前中后遍历2、层序遍历3、二叉树的基本操作获取树…

什么是Vue的过渡效果?如何使用Vue的过渡效果?

Vue的过渡效果是Vue.js框架中提供的一种动画效果&#xff0c;可以让元素在插入、更新或移除时拥有更流畅的视觉切换效果。使用Vue的过渡效果可以为页面增添动感和交互性&#xff0c;让用户体验更加友好。 下面我们来看一下如何使用Vue的过渡效果。首先&#xff0c;我们需要在V…

什么是SpringCloud,有哪些组件?

spring Cloud 是基于spring boot的分布式系统开发工具,它提供了一系列开箱即用的,针对分布式系统开发的特性和组件。用于帮助开发人员快速构建和管理云原生应用程序。 Spring Cloud 的主要目标是解决分布式系统中的常见问题,例如服务发现,负载均衡,配置管理,断路器,消息总…

【鸿蒙 HarmonyOS 4.0】应用状态:LocalStorage/AppStorage/PersistentStorage

一、介绍 如果要实现应用级的&#xff0c;或者多个页面的状态数据共享&#xff0c;就需要用到应用级别的状态管理的概念。 LocalStorage&#xff1a;页面级UI状态存储&#xff0c;通常用于UIAbility内、页面间的状态共享。AppStorage&#xff1a;特殊的单例LocalStorage对象&…

ElasticSearch之数据分片和故障转移

写在前面 基础环境可以参考ElasticSearch之分布式模型介绍&#xff0c;选主&#xff0c;脑裂 。 本文看下es的数据分片和故障转移相关内容。 1&#xff1a;数据分片 分片&#xff0c;英文是shard&#xff0c;存储在data node &#xff0c;分为主分片和副本分片&#xff0c;英…

数据治理实战——翼支付金融板块业务数仓建设和数据治理之路

目录 一、数据治理背景 二、数据治理建设内容 2.1 组织协同 2.2 平台建设 2.3 数据应用治理 2.4 数据规范 2.5 数据安全 三、企业级数仓建设 3.1 调研阶段 2.2 平台护航 2.3 数仓分层 2.4 维度建模 2.4.1 维度建模四步曲 2.4.2 命名规范 2.4.3 资产沉淀 2.4.4 …

【JS】WebSocket:实现实时通信功能。

【JS】WebSocket:实现实时通信功能。 一、WebSocket是什么&#xff1f;二、为什么需要WebSocket?三、WebSocket的优势四、WebSocket实现方式五、示例1&#xff1a;实时数据展示六、示例2&#xff1a;实现简易聊天室 如果想需要websocket实现功能&#xff0c;后端也要进行对应的…