设计模式 简单工厂 工厂方法模式 抽象工厂模式

工厂模式介绍

工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。它是创建型模式。

简单工厂

简单工厂模式是指由一个工厂对象决定创建出哪一种产品类的实例, 但它不属于GOF 23种设计模式

简单工厂适用于工厂类负责创建的对象较少的场景, 且客户端只需要传入工厂类的参数, 对于如何创建对象的逻辑不需要关心

适用场景: 工厂类负责创建的对象较少 对于如何创建对象的逻辑不需要关心

优点: 只需要传入一个正确的参数 就可以获取所需要的对象 无需知道创建细节

缺点: 违背开闭原则 不易于扩展过于复杂的产品结构 新增产品需要修改工厂类的代码

以下我们用支付场景演示简单工厂用法

1.定义支付接口

/**
 * 支付接口
 *
 * @author Lion Li
 */
public interface IPay {
    void payment();
}

2.编写工厂实例

/**
 * 付款方式工厂
 *
 * @author Lion Li
 */
public class PayFactory {

    /**
     * 创建付款实例
     * Class<? extends IPay> 单一原则 限制必须是 IPay 的子类
     */
    public IPay create(Class<? extends IPay> clazz) {
        if (null != clazz) {
            try {
                return clazz.newInstance();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }

}

3.编写具体的支付类 例如: 微信 支付宝

/**
 * 微信支付
 *
 * @author Lion Li
 */
public class WxPay implements IPay {

    public void payment() {
        System.out.println("微信支付");
    }
}
/**
 * 支付宝支付
 *
 * @author Lion Li
 */
public class ZfbPay implements IPay {

    public void payment() {
        System.out.println("支付宝支付");
    }
}

4.编写测试类并运行测试

/**
 * @author Lion Li
 */
public class Test {

    public static void main(String[] args) {
        IPay wx = new PayFactory().create(WxPay.class);
        IPay zfb = new PayFactory().create(ZfbPay.class);
        wx.payment();
        zfb.payment();
    }
}

工厂方法模式

工厂方法模式是指定义一个创建对象的接口, 但让实现这个接口的类来觉得实例化哪个类, 工厂方法让类的实例化推迟到子类中进行

适用场景: 创建对象需要大量重复的代码 不依赖于产品类实例如何被创建 实现等细节

优点: 用户只需要关心所需要产品对应的工厂 无需关心创建细节 加入新产品符合开闭原则 提供了系统的可扩展性

缺点: 类的个数容易过多 增加的代码的结构负责都 增加了系统的抽象性和理解难度

以下我们用汽车场景工厂方法模式用法

1.定义汽车接口规范

/**
 * 汽车接口规范
 *
 * @author Lion Li
 */
public interface ICar {
    void name();
}

2.编写汽车工厂接口规范

/**
 * 汽车工厂接口规范
 *
 * @author Lion Li
 */
public interface ICarFactory {
    ICar create();
}

3.编写具体的汽车种类 例如: 宝马 大众

/**
 * 宝马汽车
 *
 * @author Lion Li
 */
public class BaoMaCar implements ICar {

    public void name() {
        System.out.println("我是宝马");
    }
}
/**
 * 大众汽车
 *
 * @author Lion Li
 */
public class DaZhongCar implements ICar {

    public void name() {
        System.out.println("我是大众");
    }
}

4.编写具体的汽车工厂 例如: 宝马工厂 大众工厂

/**
 * 宝马汽车工厂
 *
 * @author Lion Li
 */
public class BaoMaCarFactory implements ICarFactory {

    public ICar create() {
        return new BaoMaCar();
    }
}
/**
 * 大众汽车工厂
 *
 * @author Lion Li
 */
public class DaZhongCarFactory implements ICarFactory {

    public ICar create() {
        return new DaZhongCar();
    }
}

5.编写测试类并运行测试

/**
 * @author Lion Li
 */
public class Test {

    public static void main(String[] args){
        ICarFactory baomaFactory = new BaoMaCarFactory();
        ICar baoma = baomaFactory.create();
        baoma.name();
        ICarFactory dazhongFactory = new DaZhongCarFactory();
        ICar dazhong = dazhongFactory.create();
        dazhong.name();
    }

}

抽象工厂

抽象工厂模式是指提供一个创建一系列相关或相互依赖对象的接口 无需指定他们具体的类

适用场景:

  1. 不依赖于产品类实例如何被创建等细节 强调一系列相关产品对象一起使用创建对象需要大量重复的代码
  2. 提供一个产品类的库 所有产品以同样的接口出现 从而不依赖于具体的实现

优点: 具体产品在应用层代码隔离 无需关心创建细节 将一个系列的产品统一到一起创建

缺点: 规定了所有可能被创建的产品集合 产品中扩展新产品困难 需要修改抽象工厂的接口 增加了系统的理解难度和抽象性

以下我们用多种出行方式来演示抽象工厂用法

1.定义产品接口规范

/**
 * 汽车接口规范
 *
 * @author Lion Li
 */
public interface ICar {
    void name();
}
/**
 * 飞机接口规范
 *
 * @author Lion Li
 */
public interface IAircraft {

    void name();
}

2.定义产品工厂接口规范

/**
 * 汽车工厂接口规范
 *
 * @author Lion Li
 */
public interface ICarFactory {
    ICar create();
}
/**
 * 飞机工厂接口规范
 *
 * @author Lion Li
 */
public interface IAircraftFactory {
    IAircraft create();
}

3.定义所有产品实现

/**
 * 宝马汽车
 *
 * @author Lion Li
 */
public class BaoMaCar implements ICar {
    public void name() {
        System.out.println("我是宝马");
    }
}
/**
 * 大众汽车
 *
 * @author Lion Li
 */
public class DaZhongCar implements ICar {
    public void name() {
        System.out.println("我是大众");
    }
}
/**
 * 波音飞机
 *
 * @author Lion Li
 */
public class BoYinAircraft implements IAircraft {
    public void name() {
        System.out.println("我是波音");
    }
}
/**
 * 空客飞机
 *
 * @author Lion Li
 */
public class KongKeAircraft implements IAircraft {
    public void name() {
        System.out.println("我是空客");
    }
}

4.定义所有产品工厂实现

/**
 * 宝马汽车工厂
 *
 * @author Lion Li
 */
public class BaoMaCarFactory implements ICarFactory {
    public ICar create() {
        return new BaoMaCar();
    }
}
/**
 * 大众汽车工厂
 *
 * @author Lion Li
 */
public class DaZhongCarFactory implements ICarFactory {
    public ICar create() {
        return new DaZhongCar();
    }
}
/**
 * 波音飞机工厂
 *
 * @author Lion Li
 */
public class BoYinAircraftFactory implements IAircraftFactory {
    public IAircraft create() {
        return new BoYinAircraft();
    }
}
/**
 * 空客飞机工厂
 *
 * @author Lion Li
 */
public class KongKeAircraftFactory implements IAircraftFactory {
    public IAircraft create() {
        return new KongKeAircraft();
    }
}

5.定义交通工具抽象工厂

/**
 * 交通工具抽象工厂
 *
 * @author Lion Li
 */
public abstract class TransportationFactory {

    public void init() {
        System.out.println("初始化数据");
    }

    protected abstract ICar createCar(Class<? extends ICarFactory> clazz);

    protected abstract IAircraft createAircraft(Class<? extends IAircraftFactory> clazz);
}

6.定义出行方式工厂

/**
 * 出行方式工厂
 *
 * @author Lion Li
 */
public class TravelFactory extends TransportationFactory {
    @Override
    protected ICar createCar(Class<? extends ICarFactory> clazz) {
        super.init();
        if (null != clazz) {
            try {
                return clazz.newInstance().create();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }

    @Override
    protected IAircraft createAircraft(Class<? extends IAircraftFactory> clazz) {
        super.init();
        if (null != clazz) {
            try {
                return clazz.newInstance().create();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }
}

7.编写测试类并运行测试

/**
 * @author Lion Li
 */
public class Test {

    public static void main(String[] args){
        TransportationFactory factory = new TravelFactory();
        ICar baoma = factory.createCar(BaoMaCarFactory.class);
        baoma.name();
        ICar dazhong = factory.createCar(DaZhongCarFactory.class);
        dazhong.name();
        IAircraft boyin = factory.createAircraft(BoYinAircraftFactory.class);
        boyin.name();
        IAircraft kongke = factory.createAircraft(KongKeAircraftFactory.class);
        kongke.name();
    }

}

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

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

相关文章

Command line is too long. Shorten command line for Application or also

一、问题描述 Error running ‘Application’: Command line is too long. Shorten command line for Application or also for Spring Boot default configuration? 二、原因分析 springboot项目启动命令过长&#xff01; 三、解决方案 第1步:点击项目启动配置项 第2步…

基于ssm的简单学校课程管理系统的设计与实现(源码+调试)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。今天给大家介绍一篇基于ssm的简单学校课程管…

vue2项目vue-qrcode-reader 扫一扫二维码插件

vue2项目 vue-qrcode-reader 扫一扫二维码插件 问题所在解决办法成功展示 问题所在 今天在引导师弟做扫二维码功能&#xff0c;发现通过npm install --save vue-qrcode-reade安装死活就是报错TypeError: Object...) is not a function 解决办法 百度了很多大牛的博客&#…

国内访问GitHub很卡,steam连接断开怎么办

目录 第一章、问题分析1.1&#xff09;问题1.2&#xff09;解决&#xff1a;下载个加速器就好了 友情提醒: 先看文章目录&#xff0c;大致了解文章知识点结构&#xff0c;点击文章目录可直接跳转到文章指定位置。 第一章、问题分析 1.1&#xff09;问题 国内访问GitHub很卡怎…

数据分析(一)(附带实例和源码)

一、主要目的&#xff1a; 主要利用Python包&#xff0c;如Numpy、Pandas和Scipy等常用分析工具并结合常用的统计量来进行数据的描述&#xff0c;把数据的特征和内在结构展现出来。熟悉在Python开发环境中支持数据分析的可用模块以及其中的方法&#xff0c;基于一定的样例数据…

Windows中安装Git软件和TortoiseGit软件

1、git软件下载地址 https://git-scm.com/download/win 2、TortoiseGit软件下载 >https://tortoisegit.org/download/ 3、软件安装 4、环境安装说明 上面介绍的是在Windows中使用git&#xff0c;如果你电脑已经装了Ubuntu系统&#xff0c;可以直接在Ubuntu中使用git命令提…

arthas获取spring bean

参考文章 arthas获取spring bean 写一个工具Util package com.example.lredisson.util;import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import o…

[RK-Linux] 移植Linux-5.10到RK3399(七)| 检查GPIO与LED节点,使能风扇接口

文章目录 一、原理图二、设备树配置三、节点控制一、原理图 ROC-RK3399-PC Pro 的 LED 接口如图: 工作灯 WORK_LED (蓝色灯)网络连接到 GPIO2_D3: DIY_LED (红色灯)网络连接到 GPIO0_B5: ROC-RK3399-PC Pro 要控制的 GPIO 接口主要是风扇,如图: FAN_CTL 网络连接到

【Java】SpringBoot中实现Redis Stream队列

SpringBoot实现Redis Stream队列 前言 简单实现一下在SpringBoot中操作Redis Stream队列的方式&#xff0c;监听队列中的消息进行消费。 jdk&#xff1a;1.8 springboot-version&#xff1a;2.6.3 redis&#xff1a;5.0.1&#xff08;5版本以上才有Stream队列&#xff09;…

【C++】STL 容器 - string 字符串操作 ⑤ ( string 字符串查找 | find 函数查找字符串 | rfind 函数查找字符串 )

文章目录 一、string 字符查找 - find 函数查找字符串1、string 类 find 函数原型说明2、代码示例 - 字符串查找3、代码示例 - 统计字符串子串 二、string 字符查找 - rfind 函数查找字符串1、string 类 rfind 函数原型说明2、代码示例 - rfind 字符串查找 一、string 字符查找…

前端常用去重的几种方式

文章目录 方式1: ES6新语法方式2: 遍历 利用filter方式3: 使用 new Map() for循环方式4: 利用 hasOwnProperty总结 在github 查看该文章 方式1: ES6新语法 过滤出网页中不重复的html标签 结合去重知识点考查 […new Set([…document.querySelectorAll(‘*’)].map(v>v.t…

HTML5+CSS3小实例:3D发光切换按钮效果

目录 一、运行效果 图片效果 二、项目概述 三、开发环境 四、实现步骤及代码 1.创建空文件夹 2.完成页面内容 3.完成css样式 五、项目总结 六、源码获取 一、运行效果 图片效果 二、项目概述 这个项目是一个演示3D发光切换按钮效果的网页。按钮由一个开关和一个指…

spring6 基于xml自动装配

目录结构 代码 UserContronller.java package bean.auto.controller;import bean.auto.service.UserService; import bean.auto.service.UserServiceImpl;public class UserContronller {private UserService userService;public void setUserService(UserService userServ…

智能配电房在线监测系统

智能配电房在线监测系统是一个综合性的系统&#xff0c;依托电力智慧运维工具-电易云&#xff0c;主要用于监控和调整配电房的环境、安防和电气设备状态。以下是该系统的一些主要功能和特点&#xff1a; 环境监控&#xff1a;实时监测配电房内的温度、湿度、SF6气体浓度、臭氧浓…

Cmake基础(4)

这篇文章在上一篇的基础之上应用多文件&#xff0c;即一个项目中添加多个文件 文章目录 GLOBsource_group排除文件 上一篇文章的cmake基本不变&#xff0c;这篇文章的重点在于add_executable(${EXECUTABLE_NAME} main.cpp) GLOB file(GLOB cpp_list ${CMAKE_CURRENT_SOURCE_…

【Python特征工程系列】8步教你用决策树模型分析特征重要性(源码)

一、问题 如果有一个包含数十个甚至数百个特征的数据集&#xff0c;每个特征都可能对你的机器学习模型的性能有所贡献。但是并不是所有的特征都是一样的。有些可能是冗余的或不相关的&#xff0c;这会增加建模的复杂性并可能导致过拟合。特征重要性分析可以识别并关注最具信息量…

浅谈MapReduce

MapReduce是一个抽象的分布式计算模型&#xff0c;主要对键值对进行运算处理。用户需要提供两个自定义函数&#xff1a; map&#xff1a;用于接受输入&#xff0c;并生成中间键值对。reduce&#xff1a;接受map输出的中间键值对集合&#xff0c;进行sorting后进行合并和数据规…

linux下的strerror和perror处理错误函数

strerror和perror是C语言中用于处理错误信息的函数。 strerror函数&#xff1a; strerror函数用于将错误码转换为对应的错误消息字符串。它接受一个整数参数&#xff0c;通常是由系统调用或库函数返回的错误码&#xff0c;然后返回一个描述该错误的字符串。 函数原型&#xff1…

双指针训练

1.原理 双指针是一种解题常用方法&#xff0c;常用于将数组按照某种要求进行分块/划分&#xff0c;这里的指针对于数组来说&#xff0c;可以替换成下标&#xff08;毕竟使用下标实际上就是用了指针&#xff09;。 1.1.划分区间 通常将这两个指针命名位dest/cur&#xff08;或…

AOP切入点表达式和使用连接点获取匹配到的方法信息

目录 第一种 execution(访问修饰符? 返回值 包名.类名.?方法名(方法参数) throws 异常?) 第二种 annotation(com.itheima.anno.Log 首先&#xff0c;自定义一个注解&#xff0c;可以自己随意命名&#xff1a; 第一种 execution(访问修饰符? 返回值 包名.类名.?方法名…