设计模式(二)工厂模式

文章目录

  • 工厂模式简介
  • 简单工厂(Simple Factory)
    • 结构
    • 具体实现
    • 优缺点
  • 工厂方法(Factory Method)
    • 结构
    • 具体实现
    • 优缺点
  • 抽象工厂(Abstract Factory)
    • 结构
    • 具体实现
    • 优缺点

工厂模式简介

工厂模式是一种创建型模式,主要有三种:简单工厂(Simple Factory)、工厂方法(Factory Method)、抽象工厂(Abstract Factory)

整个博客例子:设计一个咖啡点餐系统:设计一个咖啡类(Coffee),并定义两个子类,美式咖啡(AmericanCoffee)和拿铁咖啡(LatteCoffee),在设计一个咖啡店类(CoffeeStore),咖啡店具有点咖啡的功能。

简单工厂(Simple Factory)

结构

  • 抽象产品:例如Abstract Class Coffee
  • 具体产品:例如American Coffee
  • 具体工厂: CoffeeSimpleFactory

具体实现

根据定义,为Coffee添加一个Coffee简单工厂类CoffeeSimpleFactory用于Coffee的生产,在CoffeeStore中先创建CoffeeSimpleFactory对象,然后根据该对象进行咖啡创建。

  • UML类图
    在这里插入图片描述
  • 咖啡抽象类
package com.xxliao.pattern.creational.factory.simple_factory.demo;

/**
 * @author xxliao
 * @description: 咖啡类
 * @date 2024/5/23 22:02
 */
public abstract class Coffee {

    private String name;

    public abstract String getName();
}
  • 美式咖啡类(继承Coffee类)
package com.xxliao.pattern.creational.factory.simple_factory.demo;

/**
 * @author xxliao
 * @description: 美式咖啡
 * @date 2024/5/23 22:04
 */

public class AmericanCoffee extends Coffee {
    
    private String name = "AmericanCoffee";

    @Override
    public String getName() {
        return name;
    }
}
  • 拿铁咖啡类(继承Coffee类)
package com.xxliao.pattern.creational.factory.simple_factory.demo;

/**
 * @author xxliao
 * @description: 拿铁咖啡
 * @date 2024/5/23 22:05
 */
public class LatteCoffee extends Coffee{

    private String name = "LatteCoffee";

    @Override
    public String getName() {
        return name;
    }
}
  • 咖啡工厂类
package com.xxliao.pattern.creational.factory.simple_factory.demo;

/**
 * @author xxliao
 * @description: 咖啡简单工厂类
 * @date 2024/5/23 22:07
 */
public class CoffeeSimpleFactory {

    /**
     * @description  生产咖啡
     * @author  xxliao
     * @date  2024/5/23 22:07
     */
    public Coffee createCoffee(String type){
        Coffee coffee = null;
        switch (type) {
            case "american":
                coffee = new AmericanCoffee();
                break;
            case "lattee":
                coffee = new LatteCoffee();
                break;
            default:
                break;
        }
        return coffee;
    }
}
  • 咖啡店类
package com.xxliao.pattern.creational.factory.simple_factory.demo;

/**
 * @author xxliao
 * @description: 咖啡店类
 * @date 2024/5/23 22:10
 */
public class CoffeeStore {

    /**
     * @description  咖啡点餐
     * @author  xxliao
     * @date  2024/5/23 22:12
     */
    public Coffee orderCoffee(String type) {
        // 创建简单工厂对象
        CoffeeSimpleFactory coffeeSimpleFactory = new CoffeeSimpleFactory();
        return coffeeSimpleFactory.createCoffee(type);
    }
}
  • 测试类
package com.xxliao.pattern.creational.factory.simple_factory;

import com.xxliao.pattern.creational.factory.simple_factory.demo.Coffee;
import com.xxliao.pattern.creational.factory.simple_factory.demo.CoffeeStore;

/**
 * @author xxliao
 * @description: 工厂设计模式-简单工厂模式-测试客户端
 * @date 2024/5/23 22:00
 */
public class SimpleFactoryClient {

    public static void main(String[] args) {
        CoffeeStore coffeeStore = new CoffeeStore();
        Coffee coffee = coffeeStore.orderCoffee("american");
        System.out.println(coffee.getName());
    }
}

优缺点

  • 优点:封装了创建对象的过程,可以根据参数等直接获取对象,将对象的创建和业务逻辑层分开,易于扩展。
  • 缺点:当Coffee种类增加时候CoffeeSimpleFactory的createCoffee方法需要修改,违背了开闭原则(对扩展开放,对修改关闭)

工厂方法(Factory Method)

根据简单工厂的工厂类方法扩展时需要修改代码的缺点,可以使用工厂方法模式解决。定义一个抽象工厂,为每个对象创建一个具体产品类工厂,对象的创建在工厂子类中进行。

结构

  • 1.抽象工厂(abstract factory): 提供创建产品的接口,调用者通过它访问具体工厂的工厂方法类创建产品。
  • 2.具体工厂(Concrete factory): 实现抽象工厂的具体类,完成具体产品的创建。
  • 3.抽象产品: 例如:Coffee。
  • 4.具体产品:例如:AmericanCoffee。

具体实现

  • UML图
    在这里插入图片描述
  • 咖啡类(抽象产品类)
package com.xxliao.pattern.creational.factory.factory_method.demo;

/**
 * @author xxliao
 * @description: 咖啡类
 * @date 2024/5/23 22:02
 */
public abstract class Coffee {

    private String name;

    public abstract String getName();
}
  • 美式咖啡类(具体产品类)
package com.xxliao.pattern.creational.factory.factory_method.demo;

/**
 * @author xxliao
 * @description: 美式咖啡
 * @date 2024/5/23 22:04
 */
public class AmericanCoffee extends Coffee {
    
    private String name = "AmericanCoffee";

    @Override
    public String getName() {
        return name;
    }
}
  • 拿铁咖啡(具体产品类)
package com.xxliao.pattern.creational.factory.factory_method.demo;

/**
 * @author xxliao
 * @description: 拿铁咖啡
 * @date 2024/5/23 22:05
 */
public class LatteCoffee extends Coffee {
    private String name = "LatteCoffee";

    @Override
    public String getName() {
        return name;
    }
}
  • 咖啡抽象工厂类
package com.xxliao.pattern.creational.factory.factory_method.demo;

/**
 * @author xxliao
 * @description: 咖啡的抽象工厂类
 * @date 2024/5/23 22:29
 */

public interface CoffeeFactory {

    public Coffee createCoffee();
}
  • 美式咖啡工厂类(具体工厂类)
package com.xxliao.pattern.creational.factory.factory_method.demo;

/**
 * @author xxliao
 * @description: 美式咖啡工厂类
 * @date 2024/5/23 22:07
 */
public class AmericanCoffeeFactory implements CoffeeFactory{

    /**
     * @description  生产咖啡
     * @author  xxliao
     * @date  2024/5/23 22:07
     */
    public Coffee createCoffee(){

        return new AmericanCoffee();
    }
}
  • 拿铁工厂类(具体工厂类)
package com.xxliao.pattern.creational.factory.factory_method.demo;

/**
 * @author xxliao
 * @description: 拿铁咖啡工厂类
 * @date 2024/5/23 22:07
 */
public class LatteCoffeeFactory implements CoffeeFactory{

    /**
     * @description  生产咖啡
     * @author  xxliao
     * @date  2024/5/23 22:07
     */
    public Coffee createCoffee(){

        return new LatteCoffee();
    }
}
  • 咖啡店类
package com.xxliao.pattern.creational.factory.factory_method.demo;

/**
 * @author xxliao
 * @description: 咖啡店类
 * @date 2024/5/23 22:10
 */

public class CoffeeStore {

   private CoffeeFactory coffeeFactory;

   public CoffeeStore(CoffeeFactory coffeeFactory) {
       this.coffeeFactory = coffeeFactory;
   }

    /**
     * @description  咖啡点餐
     * @author  xxliao
     * @date  2024/5/23 22:12
     */
    public Coffee orderCoffee() {
       return coffeeFactory.createCoffee();
    }
}
  • 测试客户端
package com.xxliao.pattern.creational.factory.factory_method;

import com.xxliao.pattern.creational.factory.factory_method.demo.AmericanCoffeeFactory;
import com.xxliao.pattern.creational.factory.factory_method.demo.Coffee;
import com.xxliao.pattern.creational.factory.factory_method.demo.CoffeeStore;

/**
 * @author xxliao
 * @description: 工厂设计模式-工厂方法 - 测试客户端
 * @date 2024/5/23 22:19
 */

public class FactoryMethod {

    public static void main(String[] args) {
        CoffeeStore coffeeStore = new CoffeeStore(new AmericanCoffeeFactory());
        Coffee coffee = coffeeStore.orderCoffee();
        System.out.println(coffee.getName());
    }
}

优缺点

  • 优点:封装了创建对象的具体过程,将对象创建和业务逻辑层进行分离,用户只需要知道具体的工厂就可以创建对应的对象,新增产品时,只需要添加对应产品类和具体工厂子类就行,无需其它代码进行修改。
  • 缺点:没新增一个产品,就需要增加一个产品类以及对应的工厂类,增加了系统复杂度。

抽象工厂(Abstract Factory)

抽象工厂模式是 工厂方法的升级版,工厂方法是一个产品就有一个具体的工厂类,抽象工厂是顶级抽象工厂可以生产多种产品,然后子类工厂实现类可以生产
产品一类。
例如:定义工厂定义可以生产coffee和dessert,子类AmericanDessertFacTory可以生产AmericanCoffee和AmericanDessert。

结构

  • 1.抽象工厂(abstract factory): 提供创建产品的接口,包含多个产品的拆创建方法,可以创建多个不同维度的产品。
  • 2.具体工厂(Concrete factory): 实现抽象工厂的具体类,完成具体一系列产品的创建。
  • 3.抽象产品: 例如:Coffee。
  • 4.具体产品:例如:AmericanCoffee.

具体实现

  • UML图
    在这里插入图片描述

  • 咖啡类(抽象产品类)

package com.xxliao.pattern.creational.factory.abstract_factory.demo;

/**
 * @author xxliao
 * @description: 咖啡类
 * @date 2024/5/23 22:02
 */
public abstract class Coffee {

    private String name;

    public abstract String getName();
}
  • 中国咖啡类(具体产品类)
package com.xxliao.pattern.creational.factory.abstract_factory.demo;

/**
 * @author xxliao
 * @description: 国产中式咖啡
 * @date 2024/5/23 22:05
 */
public class ChineseCoffee extends Coffee {

    private String name = "ChineseCoffee";

    @Override
    public String getName() {
        return name;
    }
}

-美式咖啡类(具体产品类)

package com.xxliao.pattern.creational.factory.abstract_factory.demo;

/**
 * @author xxliao
 * @description: 美式咖啡
 * @date 2024/5/23 22:04
 */
public class AmericanCoffee extends Coffee {

    private String name = "AmericanCoffee";

    @Override
    public String getName() {
        return name;
    }
}
  • 甜品类(抽象产品类)
package com.xxliao.pattern.creational.factory.abstract_factory.demo;

/**
 * @author xxliao
 * @description: 甜品抽象类
 * @date 2024/5/23 23:07
 */
public abstract class Dessert {

    private String name;

    public abstract String getName();
}
  • 中式甜品类(具体产品类)
package com.xxliao.pattern.creational.factory.abstract_factory.demo;

/**
 * @author xxliao
 * @description: 中式甜品
 * @date 2024/5/23 23:10
 */
public class ChineseDessert extends Dessert{

    private String name = "ChineseDessert";

    public String getName() {
        return name;
    }
}
  • 美式甜品类(具体产品类)
package com.xxliao.pattern.creational.factory.abstract_factory.demo;

/**
 * @author xxliao
 * @description: 美式甜品
 * @date 2024/5/23 23:10
 */
public class AmericanDessert extends Dessert{

    private String name = "AmericanDessert";

    public String getName() {
        return name;
    }
}
  • 烘培饮品工厂(抽象工厂类)
package com.xxliao.pattern.creational.factory.abstract_factory.demo;

/**
 * @author xxliao
 * @description: 烘培饮品工厂
 * @date 2024/5/23 22:29
 */
public interface DessertFactory {

    // 生产咖啡
    Coffee createCoffee();

    // 生产甜品
    Dessert createDessert();
}
  • 中国烘培饮品工厂(具体工厂类)
package com.xxliao.pattern.creational.factory.abstract_factory.demo;

/**
 * @author xxliao
 * @description: 中国烘培饮品工厂
 * @date 2024/5/23 22:07
 */
public class ChineseDessertFactory implements DessertFactory {

    /**
     * @description  生产咖啡
     * @author  xxliao
     * @date  2024/5/23 22:07
     */
    public Coffee createCoffee(){

        return new ChineseCoffee();
    }

    @Override
    public Dessert createDessert() {
        return new ChineseDessert();
    }
}
  • 美国烘培饮品工厂(具体工厂类)
package com.xxliao.pattern.creational.factory.abstract_factory.demo;

/**
 * @author xxliao
 * @description: 美国烘培饮品工厂
 * @date 2024/5/23 22:07
 */
public class AmericanDessertFactory implements DessertFactory {

    /**
     * @description  生产咖啡
     * @author  xxliao
     * @date  2024/5/23 22:07
     */
    public Coffee createCoffee(){

        return new AmericanCoffee();
    }

    @Override
    public Dessert createDessert() {
        return new AmericanDessert();
    }
}
  • 测试客户端
package com.xxliao.pattern.creational.factory.abstract_factory;

import com.xxliao.pattern.creational.factory.abstract_factory.demo.AmericanDessertFactory;
import com.xxliao.pattern.creational.factory.abstract_factory.demo.ChineseDessertFactory;
import com.xxliao.pattern.creational.factory.abstract_factory.demo.Coffee;
import com.xxliao.pattern.creational.factory.abstract_factory.demo.Dessert;

/**
 * @author xxliao
 * @description: 设计模式-工厂模式-抽象工厂模式 - 测试客户端
 * @date 2024/5/23 22:59
 */

public class AbstractFactory {

    public static void main(String[] args) {
        // 拿到工厂类
        AmericanDessertFactory americanDessertFactory = new AmericanDessertFactory();
        // 生产一系列产品
        Coffee americanCoffee = americanDessertFactory.createCoffee();
        Dessert americanDessert = americanDessertFactory.createDessert();
        System.out.println(americanDessert.getName());
        System.out.println(americanCoffee.getName());
        System.out.println("==========================================");
        // 拿到工厂类
        ChineseDessertFactory chineseDessertFactory = new ChineseDessertFactory();
        // 生产一系列产品
        Coffee chineseCoffee = chineseDessertFactory.createCoffee();
        Dessert chineseDessert = chineseDessertFactory.createDessert();
        System.out.println(chineseCoffee.getName());
        System.out.println(chineseDessert.getName());
    }
}

优缺点

  • 优点:当一个产品族中多个对象被设计一起生产时,抽象工厂模式可以保证客户端始终只使用同一个产品族中的对象。
  • 缺点:产品族中新增一个产品时候,所有的工厂类都需要修改。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[数据集][目标检测]焊接处缺陷检测数据集VOC+YOLO格式3400张8类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):3400 标注数量(xml文件个数):3400 标注数量(txt文件个数):3400 标注…

能源SCI期刊,中科院4区,审稿快,IF=3.858

一、期刊名称 Frontiers in Energy Research 二、期刊简介概况 期刊类型:SCI 学科领域:能源 影响因子:3.858 中科院分区:4区 三、期刊征稿范围 能源研究前沿出版了整个领域的严格同行评审研究,重点是可持续和环境…

YOLOv8 深度详解!一文看懂,快速上手

YOLOv8 深度详解!一文看懂,快速上手 原文:YOLOv8 深度详解!一文看懂,快速上手 - 知乎 (zhihu.com) YOLOv8 是 ultralytics 公司在 2023 年 1月 10 号开源的 YOLOv5 的下一个重大更新版本,目前支持图像分类…

Low Memory Killer in Android

目录 低内存管理(Linux vs Android) Linux内存回收 shrink_slab原理 shrink_zone原理 oom killer oom killer设计原则 OOM killer具体实现 android的lmk(Low Memory Killer) Android系统特点 oom killer在android中的不足 ​​​​​​​LMK概…

乡村振兴与农村环境整治:加强农村环境治理,改善农村人居环境,打造干净整洁、生态宜居的美丽乡村

目录 一、引言 二、农村环境整治的重要性 1、提升农民生活质量 2、促进农村经济发展 3、保护农村生态环境 三、当前农村环境面临的问题 1、垃圾处理不当 2、污水处理设施缺乏 3、农业面源污染严重 四、加强农村环境治理的措施 1、完善农村垃圾处理体系 2、加强农村…

2010-2015 年阿拉斯加北坡苔原植物功能类型连续覆盖图

ABoVE: Tundra Plant Functional Type Continuous-Cover, North Slope, Alaska, 2010-2015 2010-2015 年阿拉斯加北坡苔原植物功能类型连续覆盖图 简介 文件修订日期:2021-08-27 数据集版本: 1 摘要 该数据集以 30 米的分辨率提供了阿拉斯加北坡约 12.5 万平方…

CodeMirror 创建标签计算编辑器

在日常开发中对于一些数据计算场景可能会遇到标签计算的需求&#xff0c;下面关于如何使用CodeMirror实现标签计算编辑功能。 1&#xff0c;结果图 2&#xff0c;主体代码逻辑 大家只需要复制粘贴主要codeMirror使用逻辑即可 <template><el-dialogref"dialogRe…

7.2 Go 使用error类型

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

godot.bk

1.搜索godot国内镜像&#xff0c;直接安装&#xff0c;mono是csharp版本 2.直接解压&#xff0c;50m&#xff0c;无需安装&#xff0c;直接运行 3.godot里分为场景&#xff0c;节点 主场景用control场景&#xff0c;下面挂textureact放背景图片&#xff0c;右键实例化子场景把…

自然语言处理(NLP)—— 置信度(Confidence)

1. 置信度&#xff08;Confidence&#xff09;的概念 置信度&#xff08;Confidence&#xff09;在机器学习和统计中通常指一个模型对其做出的预测是正确的确信程度。在分类任务中&#xff0c;置信度通常由模型赋予特定类别的概率值来表示。例如&#xff0c;在文本分类或实体识…

外界访问docker服务失败

各位i大佬请问一下&#xff1a;我容器起了&#xff0c;但是外网访问不了目标机器的9090端口。 我检查了&#xff1a;1.本机的防火墙已关闭&#xff0c; 2.目标机器的9090端口显示正在被docker监听。 3.外网可以访问目标机器。 4.docker日志&#xff0c;未显示服务报错。 5…

07.与jenkins集成实现cicd

7.与jenkins集成实现ci/cd ip地址服务内存192.168.111.11kube-apiserver 80801G192.168.111.13k8s-node22G192.168.111.14jenkins(tomcat jdk) 8080 kubelet docker1G192.168.111.15gitlab 8080,80 docker2G 通过jenkins一键操作实现发布服务&#xff0c;jenkins对接k8s …

【前缀和】42. 接雨水

本文涉及知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 LeetCode42. 接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&am…

【PPT】根据字体大小自动缩放文本框大小

【PPT】根据字体大小自动缩放文本框大小 一般我们新建文本框输入文字后&#xff0c;文本框的大小是不会自动缩放的&#xff0c;是根据你一开始拖动的尺寸固定的 你可以设置文本框的长度随着文字的变化而自动调整。这样&#xff0c;无论你输入多少文字&#xff0c;文本框都会自…

FFmpeg开发笔记(三十三)分析ZLMediaKit对H.264流的插帧操作

《FFmpeg开发实战&#xff1a;从零基础到短视频上线》一书的“3.4.3 把原始的H264文件封装为MP4格式”介绍了如何把H.264裸流封装为MP4文件。那么在网络上传输的H.264裸流是怎样被接收端获取视频格式的呢&#xff1f;前文指出H.264流必定以“SPS帧→PPS帧→IDR帧”开头&#x…

深入JVM:全面解析GC调优

文章目录 深入JVM&#xff1a;全面解析GC调优一、序言二、GC调优指标三、GC在线监控1、Jstat工具2、VisualVM工具 四、GC日志分析1、收集GC日志2、GCViewer工具3、GCeasy工具 五、GC问题调优1、调整JVM内存大小&#xff08;1&#xff09;调整堆内存大小及比例&#xff08;2&…

ChatGPT-4o 有何特别之处?

文章目录 多模态输入&#xff0c;多模态输出之前的模型和现在模型对比 大家已经知道&#xff0c;OpenAI 在 GPT-4 发布一年多后终于推出了一个新模型。它仍然是 GPT-4 的一个变体&#xff0c;但具有前所未见的多模态功能。 有趣的是&#xff0c;它包括实时视频处理等强大功能&…

疫情物资捐赠和分配系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;机构管理&#xff0c;用户管理&#xff0c;发放管理&#xff0c;物资管理 前台账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;物资论坛&#xff0c;公告信息…

7.1 Go 错误的概念

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

Python:由b站临时短链接获取到永久链接(去除分享中的杂项)

&#x1f4da;博客主页&#xff1a;knighthood2001 ✨公众号&#xff1a;认知up吧 &#xff08;目前正在带领大家一起提升认知&#xff0c;感兴趣可以来围观一下&#xff09; &#x1f383;知识星球&#xff1a;【认知up吧|成长|副业】介绍 ❤️如遇文章付费&#xff0c;可先看…