设计模式 - 抽象工厂模式

news2024/9/22 9:34:42

学完工厂模式,才发现还有一个抽象工厂模式;学习后发现不论是通过接口方式、还是继承方式,都可以使用抽象工厂模式;但是个人建议更多的时候,我们可以优先考虑接口方式,毕竟 单继承,多实现

设计模式分为三种类型,共23种

  • 创建型模式:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式
  • 结构型模式:代理模式、装饰模式、外观模式、享元模式、桥接模式、组合模式、适配器模式
  • 行为型模式:观察者模式、策略模式、中介者模式、模版方法模式、命令模式、迭代器模式、职责链模式(责任链模式)、备忘录模式、解释器模式(Interpreter模式)、状态模式、访问者模式

每个人的理解方式、理解程度都不相同,怎么去理解有时候并不太关键,主要最终结果一致即可,以下仅代表个人学习观点,如有错误,欢迎指出,共同进步

    • 基础认知
    • Demo结构、效果
      • 分类结构
      • 效果
    • 基础实现
      • 抽象产品类
      • 具体产品类
      • 抽象工厂类
      • 具体工厂类
      • 使用方式
    • 项目实现
      • 抽象产品
      • 具体产品
      • 抽象工厂
      • 具体工厂
      • 使用方式

基础认知

简单工厂模式针对的是单一对象+综合行为管理的(同等级产品),抽象工厂模式针对的是同类行为管理(同族产品)

取个简单的例子来说明一下工厂模式和抽象工厂模式,思维上可以稍微跳跃一下去想象

简单工厂模式更多的针对是单类产品:以生活中随处可见的车为例,通常车的组成发动机、轮胎、方向盘等等,如果我们写一个工厂模式,那么首先我们需要做以下几步

  1. 写一个抽象产品类(主要用于说明车的组成,内部包含发动机、轮胎、方向盘等等)
  2. 写一个或多个具体产品类继承、实现抽象类的方法(他们内部的实现有所不同,例如发动机可能有v4,v6的)
  3. 写一个工厂管理类去动态创建所需要的具体类

在上面条件下,其实生活中有各种品牌的车,例如奥迪、宝马等等,它们也都具由发动机、轮胎、方向盘等等组成,在这种场景下又改如何去写工厂模式?难道像之前一样,写一个抽象产品类,然后写具体产品类(汽车的组成类),然后用工厂吗?

你可能会发现中间好像少了一层管理类(奥迪、宝马分化),这时候就用到了抽象工厂模式, 这种模式可以说是换了一个维度是分类组装,需要用到一个抽象工厂类~

  1. 抽象产品类
  2. 具体产品类
  3. 抽象工厂类
  4. 具体工厂类

抽象工厂模式 相比于 简单工厂模式,个人认为主要区别有以下几点

  • 简单工厂模式,一般只有一个工厂类用于管理各抽象类下具体类的创建
  • 抽象工厂模式,多了一层抽象层用于管理各具体工厂类,同时多个具体工厂并行
  • 针对每个具体产品行为做了统一管理

采用接口、基础方式实现工厂模式、工厂抽象模式(“单继承,多实现”)的区别

继承方式

  • 缺点:相对而言扩展性有限,大部分只对当前的某一类型进行扩展使用
  • 优点:耦合性降低

接口方式

  • 缺点:加入工厂管理者类太多,对于后期不太方便维护
  • 优点:扩展性强,较灵活

Demo结构、效果

分类结构

在这里插入图片描述

效果

在这里插入图片描述


基础实现

如果将抽象工厂模式细化的话,可以用类似这种方式去学习;如果不理解,我建议直接看项目实现

抽象产品类

ProductName

package com.example.kotlindemo.factory;

public interface ProductName {
    public void carName();
}

ProductYield

package com.example.kotlindemo.factory;

public interface ProductYield {
    public void carYield();
}

具体产品类

AdNameModel

package com.example.kotlindemo.factory;

import android.util.Log;

public class AdNameModel implements ProductName {

    @Override
    public void carName() {
        Log.e("tag", "奥迪 A4");
    }
}

AdYieldModel

package com.example.kotlindemo.factory;

import android.util.Log;

public class AdYieldModel implements ProductYield {

    @Override
    public void carYield() {
        Log.e("tag","奥迪 A4 出产于:2008");
    }
}

BmNameModel

package com.example.kotlindemo.factory;

import android.util.Log;

public class BmNameModel implements ProductName {

    @Override
    public void carName() {
        Log.e("tag", "宝马 X1");
    }
}

BmYieldModel

package com.example.kotlindemo.factory;

import android.util.Log;

public class BmYieldModel implements ProductYield {

    @Override
    public void carYield() {
        Log.e("tag", "宝马 X1 出产于:2006");
    }
}

抽象工厂类

行为管理者:共性行为,拥有相同的组成部分

CarFactory

package com.example.kotlindemo.factory;

public interface CarFactory {
    public ProductName name();

    public ProductYield yield();
}

具体工厂类

以单产品为维度,内部涵盖抽象多个具体类

具体工厂类 AdFactory

package com.example.kotlindemo.factory;

public class AdFactory implements CarFactory {

    @Override
    public ProductName name() {
        return new AdNameModel();
    }

    @Override
    public ProductYield yield() {
        return new AdYieldModel();
    }
}

具体工厂类 BmFactory

package com.example.kotlindemo.factory;

public class BmFactory implements CarFactory {

    @Override
    public ProductName name() {
        return new BmNameModel();
    }

    @Override
    public ProductYield yield() {
        return new BmYieldModel();
    }
    
}

使用方式

  AdFactory adFactory = new AdFactory();
  adFactory.name().carName();
  adFactory.yield().carYield();

  BmFactory bmFactory = new BmFactory();
  bmFactory.name().carName();
  bmFactory.yield().carYield();

项目实现

基础实现有时候反倒把人绕晕… 不如直接以这样的方式说明

抽象产品

ProductN

package com.example.kotlindemo.factoryN;

public interface ProductN {
    public void carName();

    public void carYield();
}

具体产品

每一个产品都相对独立,具有共性行为

AdModelN

package com.example.kotlindemo.factoryN;

import android.util.Log;

public class AdModelN implements ProductN {

    @Override
    public void carName() {
        Log.e("tag", "奥迪 A4");
    }

    @Override
    public void carYield() {
        Log.e("tag","奥迪 A4 出产于:2008");
    }

}

BmModelN

package com.example.kotlindemo.factoryN;

import android.util.Log;

public class BmModelN implements ProductN {

    @Override
    public void carName() {
        Log.e("tag", "宝马 X1");
    }

    @Override
    public void carYield() {
        Log.e("tag", "宝马 X1 出产于:2006");
    }

}

抽象工厂

package com.example.kotlindemo.factoryN;

public interface CarFactoryN {
    public ProductN model();
}

具体工厂

每一个具体的工厂都可以返回该对象的不同模型,例如同为奥迪车型可以返回 奥迪A4、奥迪A6、奥迪Q5等等

AdFactoryN

package com.example.kotlindemo.factoryN;

public class AdFactoryN implements CarFactoryN {

    @Override
    public ProductN model() {
        return new AdModelN();
    }
}

BmFactoryN

package com.example.kotlindemo.factoryN;

public class BmFactoryN implements CarFactoryN {

    @Override
    public ProductN model() {
        return new BmModelN();
    }
}

使用方式

  AdFactoryN adFactoryN = new AdFactoryN();
  adFactoryN.model().carName();
  adFactoryN.model().carYield();

  BmFactoryN bmFactoryN = new BmFactoryN();
  bmFactoryN.model().carName();
  bmFactoryN.model().carYield();

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

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

相关文章

HTML5基础语法与标签

一、 HTML5介绍 HTML5是什么&#xff1f; HTML5是超文本标记语言&#xff08;HTML&#xff09;的第五个主要版本&#xff0c;用于描述网页结构和呈现内容。它是到目前为止最新且最强大的HTML版本。 HTML5语法约定 1.标签是HTML语法中的基本单位&#xff0c;由尖括号 ​<>…

QT分屏按钮

效果&#xff1a;按钮弹出分屏选择 // gridpopwidget.h #ifndef GRIDPOPWIDGET_H #define GRIDPOPWIDGET_H#include <QWidget> #include <QMouseEvent>class GridPopWidget : public QWidget {Q_OBJECT public:explicit GridPopWidget(QWidget *parent nullptr);~…

MySQL第二天

MySQL第二天 文章目录 MySQL第二天一、第一题 题目二、第二题题目 一、第一题 题目 1、先创建该customers表 create table customers ( c_num int primary key auto_increment, c_name varchar(50), c_contact varchar(50), c_city varchar(50),c_birth datetime not null);2、…

java IO流(一) File类

File对象只能对文件进行操作&#xff0c;不能操作文件中的内容。 1 File对象的创建 要注意的是&#xff1a;路径中"“要写成”\“进行转义&#xff0c; 路径中”/"可以直接用&#xff0c;但是最好的是使用File.separator&#xff0c;它会根据系统的不同进行转化&a…

ROS:分布式通信

目录 一、前言二、方案2.1准备2.2配置文件修改2.3配置主机IP2.4配置从机IP2.5测试 一、前言 ROS是一个分布式计算环境。一个运行中的ROS系统可以包含分布在多台计算机上多个节点。根据系统的配置方式&#xff0c;任何节点可能随时需要与任何其他节点进行通信。 因此&#xff…

小白开酒吧前要做好的三件事

一、进行市场调研当你有开酒吧的想法时&#xff0c;首先要做的第一步就是市场调研&#xff0c;进行市场调研可以让你了解到该地区酒吧市场是否良好&#xff0c;对未来的经营&#xff0c;有着决定成败的帮助&#xff0c;同时市场调研也可以让你了解到周边什么类型酒吧最受欢迎&a…

PMP证书有什么用,考试条件是什么?

很多关注项目经理岗位的朋友都知道&#xff0c;一些企业的招聘信息经常会发布&#xff0c;很多招聘项目经理岗/PMO岗的岗位要求中都会有一条&#xff1a;持有PMP/软考等证书的优先。 其实面试的时候&#xff0c;可能两个候选人的经历、经验、期望薪资都差不多&#xff0c;那么…

ESP32(掌控板) 图片显示与幻灯片

ESP32&#xff08;掌控板&#xff09; 图片显示与幻灯片 本程序通过按键改变变量的值&#xff0c;从而切换4组图片&#xff0c;通过触摸按键切换每组图片中的不同图片&#xff0c;同时按下两个按键开启幻灯片功能。 图形化程序如下 Arduino代码如下 /*!* MindPlus* mpython**…

sqoop笔记——一次从Hive到PostgreSql的数据迁移

写在开头 sqoop&#xff0c;想必进来围观的小伙伴们已经很熟悉了&#xff0c;笔者想把一些在实际使用sqoop过程中遇到的问题和注意事项记录并分析给大家&#xff0c;希望能帮助有需要的同学。随着对sqoop不断深入的了解&#xff0c;笔者会不断的以文章的形式记录并分析给大家&…

2023年05月份青少年软件编程Scratch图形化等级考试试卷二级真题(含答案)

2023-05 Scratch二级真题 题数&#xff1a;37 分数&#xff1a;100 测试时长&#xff1a;60min 一、单选题(共25题&#xff0c;共50分) 1.运行下列哪段程序&#xff0c;可以让狗狗走到木屋门口&#xff1f;&#xff08; &#xff09;(2分) A. B. C. D. 2.下列哪个选项…

陪诊软件源码|医院陪诊软件开发|陪诊师接单APP定制

陪诊小程序具有以下功能优势&#xff1a;   预约挂号&#xff1a;陪诊小程序可以提供在线预约挂号功能&#xff0c;患者可以通过小程序选择就诊时间、医生和科室&#xff0c;避免排队和等待时间&#xff0c;提高就医效率。   陪诊服务&#xff1a;陪诊小程序可以提供陪诊服…

SDN实训报告-基于SDN的Qos差分服务

1 实训概述 本次为期一周的实训旨在通过基于SDN架构的实现差分服务需求来提升我们的技能。我们在实训中广泛运用了一些重要的技术手段&#xff0c;包括Django、QOS、OpenDaylight和OpenvSwitch等。 在实训过程中&#xff0c;我们将重点放在SDN的基本操作上&#xff0c;通过实际…

Introduction to linear optimization exercise 第二章课后题答案 6-10

文章目录 2.62.7 2.6 解答&#xff1a; (a) 设 y y y 是 C C C 中的一点&#xff0c;多面体 Λ { ( λ 1 , … , λ n ) ∈ R n ∣ ∑ i 1 n λ i A i y , λ 1 , … , λ n ≥ 0 } \Lambda\left\{(\lambda_1, \dots, \lambda_n)\in R^n\mid \sum_{i1}^n \lambda_i\textb…

【企业架构设计模式】MITRE 设计模式

定义&#xff1a; 软件中的设计模式&#xff08;通常&#xff09;是简短的描述&#xff0c;用于捕捉过去证明是成功的实践。它们不是具体的软件&#xff0c;而是在某些情况下应用的一种模板。它们通常不是规定性的&#xff0c;而是建议性的&#xff0c;并且包括关于何时最适合使…

Vue组件库Element-常见组件-对话框

Dialog 对话框 在保留当前页面信息的状态下&#xff0c;直接弹出对话框&#xff0c;告知用户并承载相关操作 具体代码关键如下&#xff1a; <template><div><el-row><!-- button 按钮 --><el-button>默认按钮</el-button><el-button…

Windows下编译安装VTK

本文旨在记录在Windows下编译安装VTK的流程。 零、环境 操作系统Windows 10编译器Visual Studio 2019 CommunityCMake3.24.2 一、下载代码 git clone https://github.com/Kitware/VTK.git cd ./VTK/ git checkout -b v9.0.0 v9.0.0 二、编译安装 Where is the source cod…

Redis【实战篇】---- 用户签到

Redis【实战篇】---- 用户签到 1. 用户签到 - BitMap功能演示2. 用户签到 - 实现签到功能3. 用户签到 - 签到统计4. 额外加餐 - 关于使用BitMap来解决缓存穿透的方案 1. 用户签到 - BitMap功能演示 我们针对签到功能完全可以通过mysql来完成&#xff0c;比如说以下这张表 用户…

1.数据类型

1、课后作业 1.给同桌讲讲交换两个变量的值 算法&#xff08;不管他愿不愿听&#xff09; 2.依次咨询问并获取用户的姓名、年龄、性别&#xff0c;并打印用户信息 可以先自己写一下&#xff0c;在参考一下我的代码&#xff1a; <!DOCTYPE html> <html lang"en&q…

【SLAM14讲】05 李群与李代数

在 SLAM 中位姿是未知的&#xff0c;而我们需要解决什么样的相机位姿最符合当前观测数据这样的问题。 一种典型的方式是把它构建成一个优化问题&#xff0c;求解最优的 R, t&#xff0c;使得误差最小化。 旋转矩阵自身是带有约束的&#xff08;正交且行列式为 1&#xff09;。它…

Zhong__Linux系统磁盘空间扩容和转移

时间&#xff1a;2023.07.07 环境&#xff1a;Ubuntu/Centos 目的&#xff1a;分配闲置空间到指定分区/将分区空间转移到指定分区 说明&#xff1a; 作者&#xff1a;Zhong QQ交流群&#xff1a;121160124 欢迎加入&#xff01; 在安装Ubuntu/Centos/Stream等系统时 有时对…