设计模式----工厂模式

news2024/11/15 11:40:13

设计模式----工厂模式

文章目录

    • 设计模式----工厂模式
      • 一.简介
        • 1. 什么是工厂模式?
        • 2. 工厂模式的类型?
        • 3. 工厂模式的使用场景?
      • 二. 使用
        • 1. 简单工厂模式
        • 2. 工厂方法模式
        • 3. 抽象工厂模式


一.简介

1. 什么是工厂模式?

工厂模式(Factory Pattern)是 Java中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

2. 工厂模式的类型?

  1. 简单工厂模式:
    用来生产同一等级结构中得任意产品(对于增加新得产品,需要修改已有代码)
  2. 工厂模式:
    用来生产同一等级结构中得固定产品(支持增减任意产品)
  3. 抽象工厂模式:
    围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂得工厂

3. 工厂模式的使用场景?

  1. 当一个类不知道它所必须创建的对象的类的时候。
  2. 当一个类希望由它的子类来指定它所创建的对象的时候。
  3. 当类将创建对象的职责委托给多个帮忙子类的中的某一个,并且你希望将哪一个帮助子类是代理者者一信息局部化时。

一个类不知道它所需要的对象类,在工厂方法模式中,客户端不需要指定具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体的工厂类创建客户端只需要知道创建具体产品的工厂即可

二. 使用

1. 简单工厂模式

简单工厂模式属于创建型设计模式。它不在 GoF 23 种设计模式之列。

简单工厂包括如下角色:

  1. 抽象产品:定义了产品的规范,描述了产品的主要特性和功能。
  2. 具体功能:实现或继承抽象产品的子类。
  3. 具体工厂:提供了创建产品的方法,调用者通过该方法来创建产品。

具体代码如下:

1. 抽象产品:定义了产品的规范,描述了产品的主要特性和功能。

public interface Phone {

    // 创建手机(定义产品的主要特性和功能)
    public void creatPhone();
}

2. 具体功能:实现或继承抽象产品的子类。

public class HuaWei implements Phone {

    public HuaWei() {
        this.creatPhone();
    }

    @Override
    public void creatPhone() {
        System.out.println("生产华为手机");
    }
}
public class Apple implements Phone {

    public Apple() {
        this.creatPhone();
    }
    @Override
    public void creatPhone() {

        System.out.println("生产苹果手机");
    }
}

3. 具体工厂:提供了创建产品的方法,调用者通过该方法来创建产品。

public class PhoneFactory {

    public Phone makePhone(String phoneType){

        if("apple".equals(phoneType)){
            return new Apple();
        }
        if("huawei".equals(phoneType)){
            return new HuaWei();
        }
        return null;
    }

}

测试代码:

public class TestFectory {

    public static void main(String[] args) {

        PhoneFactory phoneFactory = new PhoneFactory();
        Phone apple = phoneFactory.makePhone("apple");
        Phone huawei = phoneFactory.makePhone("huawei");
    }
}

运行结果:

生产苹果手机
生产华为手机

Process finished with exit code 0

优缺点:

  • 优点:封装了创建对象的过程,将对象的创建和具体业务逻辑分开,如果想要增加对象或者修改对象只需要进入工厂类进行修改即可,增加了可扩展性。
  • 缺点:增加新产品时候还需修改工厂中的代码,违反开闭原则。

应用场景

对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。

2. 工厂方法模式

概念:定义一个用于创建对象的接口,让子类决定实例化哪个产品对象,工厂方法使一个产品的实例化延迟到其工厂的子类。

针对上述简单工厂模式中的缺点,工厂方法模式就可以解决。

工厂方法模式角色:

  1. 抽象工厂:提供创建产品的接口,调用者通过它访问具体工厂的的工厂方法来创建产品。
  2. 具体工厂:实现抽象工厂的工厂方法,完成具体产品的创建。
  3. 抽象产品:定义产品的规范,描述了产品的主要特性和功能。
  4. 具体产品:实现抽象产品角色所定义的接口,由具体工厂来创建,同具体工厂一一对应。
    代码实现:

2.1. 抽象工厂

//抽象工厂角色
public interface PhoneFactory {

    // 创建手机对象方法
    Phone creatPhone();
}

2.2 具体工厂

创建苹果手机工厂

@Component
public class AppleFactory implements PhoneFactory{

    @Override
    public Phone creatPhone() {
        return new Apple();
    }

创建华为手机工厂

@Component
public class HuaWeiFactory implements PhoneFactory {
    
    @Override
    public Phone creatPhone() {
        return new HuaWei();
    }
}

2.3 抽象产品

public interface Phone {

    // 创建手机(定义产品的主要特性和功能)
    public void creatPhone();
    // 创建耳机
    public void creatHeadset();
}

2.4 具体产品

public class Apple implements Phone {

    public Apple() {
        this.creatPhone();
    }
    @Override
    public void creatPhone() {
        System.out.println("生产苹果手机");
    }

    @Override
    public void creatHeadset() {
        System.out.println("生产苹果耳机");
    }
    
}

测试使用苹果工厂

@Component
public class CreatPhone {

    @Autowired
    private AppleFactory appleFactory;

    public Phone getApplePhone(){

        Phone phone = appleFactory.creatPhone();
        //生产手机
        phone.creatPhone();
        //生产耳机
        phone.creatHeadset();

        return phone;
    }
}

工厂方法模式的优缺点:

  • 优点:完全遵循开闭原则,代码可扩展性强。
  • 由于每一个产品都需要一个工厂类生产,使类过多显得复杂。

3. 抽象工厂模式

抽象工厂模式是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

应用实例:

工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产品)、时尚装(成套,一系列具体产品),甚至对于一个家庭来说,可能有商务女装、商务男装、时尚女装、时尚男装,这些也都是成套的,即一系列具体产品。假设一种情况(现实中是不存在的,要不然,没法进入共产主义了,但有利于说明抽象工厂模式),在您的家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然要从这个衣柜中取出了。用OOP的思想去理解,所有的衣柜(具体工厂)都是衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。

实现思路:

我们将创建 Shape 和 Color 接口和实现这些接口的实体类。下一步是创建抽象工厂类 AbstractFactory。接着定义工厂类ShapeFactory 和 ColorFactory,这两个工厂类都是扩展了AbstractFactory。然后创建一个工厂创造器/生成器类 FactoryProducer。

AbstractFactoryPatternDemo 类使用 FactoryProducer 来获取 AbstractFactory对象。它将向 AbstractFactory 传递形状信息 Shape(CIRCLE / RECTANGLE /SQUARE),以便获取它所需对象的类型。同时它还向 AbstractFactory 传递颜色信息 Color(RED / GREEN /BLUE),以便获取它所需对象的类型。

在这里插入图片描述

实现步骤:

3.1 分别为形状和颜色创建一个接口

// 形状接口
public interface Shape {
   void draw();
}
// 颜色接口
public interface Color {
   void fill();
}

3.2 创建实现接口的实现类

形状接口实现类:

public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}
public class Square implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}
public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}

颜色接口实现类:

public class Red implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Red::fill() method.");
   }
}
public class Green implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Green::fill() method.");
   }
}
public class Blue implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Blue::fill() method.");
   }
}

3.3 为 Color 和 Shape 对象创建抽象类来获取工厂。

public abstract class AbstractFactory {
   public abstract Color getColor(String color);
   public abstract Shape getShape(String shape);
}

3.4 创建扩展了 AbstractFactory 的工厂类,基于给定的信息生成实体类的对象。

创建形状工厂:

public class ShapeFactory extends AbstractFactory {
    
   @Override
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }        
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      return null;
   }
   
   @Override
   public Color getColor(String color) {
      return null;
   }
}

创建颜色工厂:

public class ColorFactory extends AbstractFactory {
    
   @Override
   public Shape getShape(String shapeType){
      return null;
   }
   
   @Override
   public Color getColor(String color) {
      if(color == null){
         return null;
      }        
      if(color.equalsIgnoreCase("RED")){
         return new Red();
      } else if(color.equalsIgnoreCase("GREEN")){
         return new Green();
      } else if(color.equalsIgnoreCase("BLUE")){
         return new Blue();
      }
      return null;
   }
}

3.4 创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂

public class FactoryProducer {
   public static AbstractFactory getFactory(String choice){
      if(choice.equalsIgnoreCase("SHAPE")){
         return new ShapeFactory();
      } else if(choice.equalsIgnoreCase("COLOR")){
         return new ColorFactory();
      }
      return null;
   }
}

3.5 使用 FactoryProducer 来获取 AbstractFactory,通过传递类型信息来获取实体类的对象。

public class AbstractFactoryPatternDemo {
   public static void main(String[] args) {
 
      //获取形状工厂
      AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
 
      //获取形状为 Circle 的对象
      Shape shape1 = shapeFactory.getShape("CIRCLE");
 
      //调用 Circle 的 draw 方法
      shape1.draw();
 
      //获取形状为 Rectangle 的对象
      Shape shape2 = shapeFactory.getShape("RECTANGLE");
 
      //调用 Rectangle 的 draw 方法
      shape2.draw();
      
      //获取形状为 Square 的对象
      Shape shape3 = shapeFactory.getShape("SQUARE");
 
      //调用 Square 的 draw 方法
      shape3.draw();
 
      //获取颜色工厂
      AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
 
      //获取颜色为 Red 的对象
      Color color1 = colorFactory.getColor("RED");
 
      //调用 Red 的 fill 方法
      color1.fill();
 
      //获取颜色为 Green 的对象
      Color color2 = colorFactory.getColor("GREEN");
 
      //调用 Green 的 fill 方法
      color2.fill();
 
      //获取颜色为 Blue 的对象
      Color color3 = colorFactory.getColor("BLUE");
 
      //调用 Blue 的 fill 方法
      color3.fill();
   }
}

优缺点:

  • 优点:当一个产品族被设计成一起工作时,方便快捷,避免类过多。
  • 缺点:产品族中增加产品,需要修改原有工厂代码。

抽象工厂模式参考链接:抽象工厂模式

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

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

相关文章

【SpringBoot项目】SpringBoot项目-瑞吉外卖【day03】分类管理

文章目录前言公共字段自动填充问题分析代码实现功能测试功能完善新增分类需求分析模型代码开发功能测试分类信息分页查询需求分析代码开发功能测试删除分类需求分析代码开发功能完善修改分类需求分析代码实现结尾🌕博客x主页:己不由心王道长&#x1f315…

11.17 - 每日一题 - 408

每日一句: 世上没有侥幸的成功,只有加倍的努力。 数据结构 1 一棵左右子树均不空的二叉树在先序线索化后,其中空的链域的个数是______ A. 0B. 1C 2D.不确定答案:B 解析:线索二叉树利用了二叉链表中的空的左右孩子指…

高通导航器软件开发包使用指南(3)

高通导航器软件开发包使用指南(3)3.2 实时数据查看3.3 日志分析3.4 其他日志记录系统信息3.4.1查看数据记录选项3.4.2确保日志存储3.4.3获取snav_vector版本3.2 实时数据查看 snav_sinspector控制台应用程序允许以人工方式查看日志文件中的二进制数据 …

java项目-第142期ssm美食推荐系统-ssm毕业设计_计算机毕业设计

java项目-第142期ssm美食推荐系统-ssm毕业设计_计算机毕业设计 【源码请到资源专栏下载】 今天分享的项目是《ssm美食推荐系统》 该项目分为2个角色,管理员和用户。 用户可以浏览前台,包含功能有: 首页、热门美食、美食教程、美食店铺 、美食社区、美食资…

Arthas教程

Linux环境安装 下载地址:https://alibaba.github.io/arthas/arthas-boot.jar java -jar arthas-boot.jar 运行 quit 退出 stop 停止Arthas快速入门 一.执行一个jar包 二.通过arthas来attach(黏附) 三.常用命令操作 诊断demo下载http…

Oracle Primavera Unifier活动管理器(Activity Manager)

目录 一、简要介绍 二、其他相关 一、简要介绍 Oracle Primavera Unifier Activity“活动”被定义为必须按计划完成的工作或事件的一部分。 Activity也就是以上的活动,它从映射的 P6 项目中捕获计划数据,从公司级主费率表(默认&#xff0…

大数据必学Java基础(一百零二):连接池的使用

文章目录 连接池的使用 一、连接池基础知识扩展 二、代码实战 1、定义连接池

信道划分介质访问控制ALOHA协议CSMA协议CSMA/CD协议轮询访问MAC协议

注:最后有面试挑战,看看自己掌握了吗 文章目录传输数据两种链路点对点链路广播式链路介质访问控制静态划分信道动态划分信道轮询访问介质访问控制随机访问介质访问控制---所有用户都可以随机发送信息ALOHA协议------想说就说CSMA协议------先听再说1-坚持…

【保姆级】新机器部署RabbitMQ

1、登录服务器,如果非root用户则切root用户 sudo su - 2、在/usr/tmp目录上传erlang、rabbitmq安装包 3、将安装包移到/usr/local/目录 mv /usr/tmp/erlang-21.3.8.2-1.el7.x86_64.rpm /usr/local/ mv /usr/tmp/rabbitmq-server-3.7.15-1.el7.noarch.rpm /usr/lo…

基础知识:临界阻尼

任何一个振动系统,当阻尼增加到一定程度时,物体的运动是非周期性的,物体振动连一次都不能完成,只是慢慢地回到平衡位置就停止了。当阻力使振动物体刚好能不作周期性振动而又能最快地回到平衡位置的情况,称为“临界阻尼…

JS高级(三):严格模式、闭包、递归、深拷贝和浅拷贝

JavaScript高级(三)一、严格模式1.开启严格模式(1)为脚本开启严格模式(2)为某个函数开启严格模式2.严格模式的一些规定(1)禁止变量未声明就赋值(2)禁止删除已…

AMD发布22.11.1驱动,支持《使命召唤:战区2.0》

他来了他来了,带着迷人的脚步走来了! 《使命召唤:战区2.0》正式上线了。有Steam周榜三连冠的《使命召唤19》在前,《战区2.0》可以说是备受瞩目,免费大逃杀,谁不期待? (图源自steam&…

一句话生成图片,FlagAI使用(附页面操作代码) | 机器学习

目录 前言 项目结构 页面交互调整 总结 前言 最近Text-To-Image是一个很火的话题,甚至更进一步的Text-To-Video话题度也在不断上升。最近看到一个开源项目FlagAI,是目前我觉着效果比较好的项目之一。安装操作简单,支持中英文,…

疫情防控管理系统

1、项目介绍 疫情防控管理系统拥有两种角色:管理员和用户 管理员:医护信息管理、物资管理、疫苗管理、疫站管理等 用户:登录注册、物资、疫苗、疫站查看 2、项目技术 后端框架: Servlet、mvc模式 前端技术:Bootst…

yolov5剪枝实战1: 论文及yolov5剪枝实战项目介绍

本系列博客介绍yolov5剪枝方法 1. 介绍 神经网络一般都存在过参数化(over-parameterized)的问题,存在冗余的神经元或权重,所以可以进行剪枝。 其实对网络可以针对不同的颗粒度进行剪枝,可以进行权重、神经元级别的剪枝,也可以基于channel, shape,filter以及layer级别的剪枝…

卷积神经网络基础

由于篇幅所限,本章将重点介绍计算机视觉的经典模型(卷积神经网络)和两个典型任务(图像分类和目标检测)。主要涵盖如下内容: 卷积神经网络:卷积神经网络(Convolutional Neural Netwo…

Nginx知识汇总

一、Nginx的简介 nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器;同时也是一个IMAP、POP3、SMTP代理服务器;nginx可以作为一个HTTP服务器进行网站的发布处理,另外nginx可以作为反向代理进行负载均衡的实现。 二、Nginx的优…

基于微信小程序的沁园健身房预约管理系统设计与实现-计算机毕业设计源码+LW文档

小程序开发说明 开发语言:Java 框架:ssm JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Mave…

[附源码]Python计算机毕业设计 楼盘销售管理系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

【Linux】第十二章 多线程(线程概念+线程控制)

🏆个人主页:企鹅不叫的博客 ​ 🌈专栏 C语言初阶和进阶C项目Leetcode刷题初阶数据结构与算法C初阶和进阶《深入理解计算机操作系统》《高质量C/C编程》Linux ⭐️ 博主码云gitee链接:代码仓库地址 ⚡若有帮助可以【关注点赞收藏】…