【聊一聊】三种工厂模式的创建

三种工厂模式的创建

在这里插入图片描述

今天终于星期五了,最近由于碰上一个需求,中间涉及Oracle改国产数据库的改造,好家伙,差点没把我忙坏了

不过今天终于有空啦!~哈哈哈

这篇本应该是上周就结束的,但是拖到今天,我们就今天进行结束

(还有一件快乐的事情,就是我遇见自己喜欢的人啦!嘻嘻)

好啦!~话不多说,我们进入今天的正题

本文总纲

我始终 认为一份思维导图是很重要的,建议大家也跟着建立一遍,绝对有着更上一层楼的感觉.(Just do it~ OK !)

在这里插入图片描述


我们主要进行用案例来掌握者几种模式,以练代学!!!效率绝对杠杠的


案例解析:(看对比,推荐敲一遍!~)

下面我们用一个案例来说明: 【在Spring环境下实现】

我们分别定义加减乘除类为了达到模拟计算机的效果

没有引入抽象模式时:

首先看执行类

  • 比如下面我们执行加法运算时,我们就要创建一个OperationSub的类

换句话说:

  • 我们要使用不同的运算时,就要创建不同的类,并且明确知道该类的名称(就是我们平时的显示new一个对象)
package com.byv.design_patterns;

public class Test {
    /**
     * 定义一个执行类
     * @param args
     */
    public static void main(String[] args) {
        AddOper addOper = new AddOper();
        addOper.setVal1(2);
        addOper.setVal2(3);
        System.out.println(addOper.getRes());
    }
}

抽象基类:

package com.byv.design_patterns;

import lombok.Data;

import java.math.BigDecimal;

/**
 * 抽象类: 计算机基类
 * 抽取公共逻辑
 */
@Data
public abstract class Operation {
    //计算的元素
    private int val1=0;
    private int val2=0;

    /**
     * 获取计算的结果,只能由子类来实现
     * @return
     */
    protected abstract int getRes();
}

加法类

package com.byv.design_patterns;

/**
 * 加法类
 */
public class AddOper extends Operation{
    //继承父类,实现自己的计算逻辑
    @Override
    protected int getRes() {
        return getVal1()+getVal2();
    }
}


除法类

-----------------
package com.byv.design_patterns;

/**
 * 除法类
 */
public class DivisionOper extends Operation{
    //继承父类,实现自己的计算逻辑
    @Override
    protected int getRes() {
        //判断是否除数合法
        return getVal2()!=0?getVal1()/getVal2():Integer.MIN_VALUE;
    }
}

乘法类

---------------
package com.byv.design_patterns;

/**
 * 乘法类
 */
public class MulticleOper extends Operation{
    //继承父类,实现自己的计算逻辑
    @Override
    protected int getRes() {
        return getVal1()*getVal2();
    }
}

减法类

------------
package com.byv.design_patterns;

/**
 * 减法类
 */
public class SubOper extends Operation{
    //继承父类,实现自己的计算逻辑
    @Override
    protected int getRes() {
        return getVal1()-getVal2();
    }
}

1.简单工厂模式

Static Factory Method:就是最简单的,上来不管三七二十一,就是把所有的对象(就是工厂) 给建造出来

上篇的工厂模式已经说过:简单工厂模式由一个工厂对象决定创建出哪一种产品实例

我们也看到上面没有采用设计模式的麻烦,那么我们怎么用简单工厂模式实现呢?(你可能会说,说啊!~别急啊,哈哈我们往下看)

再说实现之前,我们现看看简工框架组成()

三者关系图:

在这里插入图片描述

Factory:

  • 这是本模式的核心,含有一定的商业逻辑和判断逻辑
  • Java中往往由一个具体类实现(OperationFactory)

Product:

  • 他一般是具体产品继承父类或者实现的接口
  • Java中由接口或者抽象类实现(Operation)

ConcretProduct:

  • 工厂类所创建的对象就是此角色的实例
  • Java由一个具体类实现
  • 来用类图来清晰的表示下的他们之间的关系(OperationAdd\OperationSub)

案例:简单工厂模式实现

package com.byv.design_patterns;

import lombok.extern.java.Log;

/**
 * 简单工厂模式
 */
public class OperationFactory {
    //将所有的工厂对象创建出来,看下面的就知道
    public static Operation createOperation(String operation){
        Operation oper=null;
        switch (operation){
            case "+":
                oper=new AddOper();
                break;
            case "-":
                oper=new SubOper();
                break;
            case "*":
                oper=new MulticleOper();
                break;
            case "/":
                oper=new DivisionOper();
            default:
                System.out.println(" 输入非法,不支持此计算方式");
        }
        return oper;
    }
}

怎么调用?

上面的工厂类创建出来后,使用工厂创建对象(注意看,~我们用工厂,仔细推敲)

我们看到同样是创建一个加法运算的创建

package com.byv.design_patterns;

import com.byv.design_patterns.static_factory.OperationFactory;

public class Test {
    /**
     * 定义一个执行类
     * @param args
     */
    public static void main(String[] args) {
        //不用设计模式的
        AddOper addOper = new AddOper();
        addOper.setVal1(2);
        addOper.setVal2(3);
        System.out.println(addOper.getRes());


        //使用简单工厂模式
        //这一步真的很关键
        Operation operationAdd= OperationFactory.createOperation("+");
        operationAdd.setVal1(2);
        operationAdd.setVal2(3);
        System.out.printf(operationAdd.getRes()+"");
        
        
    }
}

工厂方法模式

这个怎么理解呢,就是更智能了,用户可以根据哪个创建哪个
在设计模式上完全符合"开闭原则"

工厂模式实现方式

关系图

Product: 抽象产品Operation

ConcreteProduct: 具体产品 ---->operationAdd

Factory: 抽象工厂 IFactory

ConcreteFactory: 具体工厂(AddFactory)

在这里插入图片描述

案例代码实现

package com.byv.design_patterns.satand_factory;

import com.byv.design_patterns.Operation;

/**
 * 减法类
 */
public class SubOper extends Operation implements IFactory{
    //继承父类,实现自己的计算逻辑
    @Override
    protected int getRes() {
        return getVal1()-getVal2();
    }

    @Override
    public Operation Creation() {
        return new SubOper();
    }
}


package com.byv.design_patterns.satand_factory;

import com.byv.design_patterns.Operation;

/**
 * 乘法类
 */
public class MulticleOper extends Operation implements IFactory{
    //继承父类,实现自己的计算逻辑
    @Override
    protected int getRes() {
        return getVal1()*getVal2();
    }

    @Override
    public Operation Creation() {
        return new MulticleOper();
    }
}



package com.byv.design_patterns.satand_factory;

import com.byv.design_patterns.Operation;

/**
 * 除法类
 */
public class DivisionOper extends Operation implements IFactory{
    //继承父类,实现自己的计算逻辑
    @Override
    protected int getRes() {
        //判断是否除数合法
        return getVal2()!=0?getVal1()/getVal2():Integer.MIN_VALUE;
    }

    @Override
    public Operation Creation() {
        return new DivisionOper();
    }
}


package com.byv.design_patterns.satand_factory;

import com.byv.design_patterns.Operation;

/**
 * 加法类
 */
public class AddOper extends Operation implements IFactory{
    //继承父类,实现自己的计算逻辑
    @Override
    protected int getRes() {
        return getVal1()+getVal2();
    }

    @Override
    public Operation Creation() {
        return new AddOper();
    }
}

怎么调用?

package com.byv.design_patterns;

import com.byv.design_patterns.satand_factory.IFactory;
import com.byv.design_patterns.static_factory.OperationFactory;

public class Test {
    /**
     * 定义一个执行类
     * @param args
     */
    public static void main(String[] args) {
        //不用设计模式的
        AddOper addOper = new AddOper();
        addOper.setVal1(2);
        addOper.setVal2(3);
        System.out.println(addOper.getRes());


        //使用简单工厂模式
        //这一步真的很关键
        Operation operationAdd= OperationFactory.createOperation("+");
        operationAdd.setVal1(2);
        operationAdd.setVal2(3);
        System.out.printf(operationAdd.getRes()+"");


        //使用工厂模式
        IFactory factory=new com.byv.design_patterns.satand_factory.AddOper();
        Operation operationStandAdd=factory.Creation();
        operationAdd.setVal1(2);
        operationAdd.setVal2(3);
        System.out.printf(operationAdd.getRes()+"");
    }
}

思考!(后面补充)

为什么要使用工厂创建对象?

为什么每种对象要单独有一个工厂?

抽象工厂模式

抽象工厂模式包含如下角色:

  1. AbstractFactory(抽象工厂):用于声明生成抽象产品的方法
  2. ConcreteFactory(具体工厂):实现了抽象工厂声明的生成抽象产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中;
  3. AbstractProduct(抽象产品):为每种产品声明接口,在抽象产品中定义了产品的抽象业务方法;
  4. Product(具体产品):定义具体工厂生产的具体产品对象,实现抽象产品接口中定义的业务方法。

采用一个汽车代工厂造汽车的例子。假设我们是一家汽车代工厂商,我们负责给奔驰和特斯拉两家公司制造车子。我们简单的把奔驰车理解为需要加油的车,特斯拉为需要充电的车。其中奔驰车中包含跑车和商务车两种,特斯拉同样也包含跑车和商务车。

下面是抽象产品,奔驰车和特斯拉车:

public interface BenzCar {
    //加汽油
    public void gasUp();

}

public interface TeslaCar {
    //充电
    public void charge();
}

下面是具体产品,奔驰跑车、奔驰商务车、特斯拉跑车、特斯拉商务车:

public class BenzSportCar implements BenzCar {
    public void gasUp() {
        System.out.println("给我的奔驰跑车加最好的汽油");
    }
}

public class BenzBusinessCar implements BenzCar{
    public void gasUp() {
        System.out.println("给我的奔驰商务车加一般的汽油");
    }
}

public class TeslaSportCar implements TeslaCar {
    public void charge() {
        System.out.println("给我特斯拉跑车冲满电");
    }
}

public class TeslaBusinessCar implements TeslaCar {
    public void charge() {
        System.out.println("不用给我特斯拉商务车冲满电");
    }
}

下面是抽象工厂:

public interface CarFactory {

    public BenzCar getBenzCar();
    public TeslaCar getTeslaCar();
}

下面是具体工厂

public class SportCarFactory implements CarFactory {
    public BenzCar getBenzCar() {
        return new BenzSportCar();
    }

    public TeslaCar getTeslaCar() {
        return new TeslaSportCar();
    }
}

public class BusinessCarFactory implements CarFactory {
    public BenzCar getBenzCar() {
        return new BenzBusinessCar();
    }

    public TeslaCar getTeslaCar() {
        return new TeslaBusinessCar();
    }
}

思考!

“开闭原则”的倾斜性是什么?

好了完结撒花(今晚写到这!~哈哈哈哈!)
在这里插入图片描述

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

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

相关文章

【数字图像处理matlab系列】数组索引

【数字图像处理matlab系列】数组索引 【先赞后看养成习惯】【求点赞+关注+收藏】 MATLAB 支持大量功能强大的索引方案,这些索引方案不仅简化了数组操作,而且提高了程序的运行效率。 1. 向量索引 维数为1xN的数组称为行向量。行向量中元素的存取是使用一维索引进行的。因此…

如何解决Layui后台接口返回数据,但是table.render不渲染表格数据的问题

我这边进行了pareData数据格式转换,response重新定义了layui的参数格式规范 接口正常返回了数据 但是就是不渲染,我这个郁闷啊!! 忽然,我把后台重新定义的layui规定的格式参数,有个参数名叫data&#xff0…

037—pandas 按指定列堆叠数据

前言 在数据分析中,我们经常需要对数据进行堆叠操作,但 Pandas 提供的 df.stack() 只能按默认索引进行操作,同时堆叠后的列名无法指定,本列我们就来解决这些问题。 读入数据 代码如下(示例):…

关于php foreach函数和变量覆盖

foreach函数是PHP中用于遍历数组或对象的函数(且仅用于数组的遍历)。它允许循环遍历数组中的每个元素,并对每个元素执行相同的操作。foreach语句的基本语法如下: foreach ($array as $value) {//执行的操作 }在这个语法中&#x…

政安晨:【深度学习部署】—— TensorFlow Extended(TFX)介绍

政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎机器学习 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正! 前言 TensorFlow Extended(TFX&a…

Orbit 使用指南 10|在机器人上安装传感器 | Isaac Sim | Omniverse

如是我闻: 资产类(asset classes)允许我们创建和模拟机器人,而传感器 (sensors) 则帮助我们获取关于环境的信息,获取不同的本体感知和外界感知信息。例如,摄像头传感器可用于获取环境的视觉信息&#xff0c…

5.windows Ubuntu 子系统,测序数据质量检测。

我们在得到一组或几组测序数据后,比如从测序公司拿到的测序数据为fastq.gz格式,首先我们需要对它们进行MD5检验,确保数据没有问题后才可进入以后的程序。(MD5可以进行测序数据完整性验证:MD5可以用于验证数据在传输或存…

IPMI开源库pyghmi基本使用

简介:Pyghmi是一个纯Python(主要是IPMI)服务器管理库。IPMI(Intelligent Platform Management Interface,智能平台管理接口)是一种开放的标准,旨在帮助系统管理员在本地和远程管理服务器系统。而…

第十届蓝桥杯大赛个人赛省赛(软件类)真题- CC++ 研究生组-最短路

6 肉眼观察&#xff0c; 看起来短的几条路对比下来是6~ #include <iostream> using namespace std; int main() {printf("6");return 0; }

AcWing 2060. 奶牛选美(每日一题)

目录 题目&#xff1a; 解题思路&#xff1a; 总结&#xff1a; 原题链接&#xff1a;2060. 奶牛选美 - AcWing题库 题目&#xff1a; 听说最近两斑点的奶牛最受欢迎&#xff0c;约翰立即购进了一批两斑点牛。 不幸的是&#xff0c;时尚潮流往往变化很快&#xff0c;当前…

[C语言]结构体、位段、枚举常量、联合体

目录 结构体 结构体的使用方法 结构体所占用的大小 位段 位段的使用方法 位段所占用的大小 枚举常量 枚举常量的使用方法 枚举常量的优势 联合体 联合体的使用方法 结构体 结构体的使用方法 结构体是一些值的集合&#xff0c;我们可以定义一个结构体&#xff0c;里…

实例:NX二次开发使用链表进行拉伸功能(链表相关功能练习)

一、概述 在进行批量操作时经常会利用链表进行存放相应特征的TAG值&#xff0c;以便后续操作&#xff0c;最常见的就是拉伸功能。这里我们以拉伸功能为例子进行说明。 二、常用链表相关函数 UF_MODL_create_list 创建一个链表&#xff0c;并返回链表的头指针。…

STM32---DHT11温湿度传感器与BH1750FVI光照传感器(HAL库、含源码)

写在前面&#xff1a;本节我们学习使用两个常见的传感器模块&#xff0c;分别为DHT11温湿度传感器以及BH1750FVI光照传感器,这两种传感器在对于环境监测中具有十分重要的作用&#xff0c;因为其使用简单方便&#xff0c;所以经常被用于STM32的项目之中。今天将使用分享给大家&a…

Digital WooCommerce Stores: 创建数字WordPress商店的详细教程- US Domain Center主机

第一步&#xff1a;了解数字 WooCommerce 商店 数字 WooCommerce 商店是一种电子商务模式&#xff0c;其中您可以销售虚拟产品&#xff0c;如在线课程、电子书、PDF、图像和视频。您可以使用 WooCommerce 插件在您的 WordPress 网站上设置数字产品&#xff0c;并通过在线交易提…

pandas的综合练习

事先说明&#xff1a; 由于每次都要导入库和处理中文乱码问题&#xff0c;我都是在最前面先写好&#xff0c;后面的代码就不在写了。要是copy到自己本地的话&#xff0c;就要把下面的代码也copy下。 # 准备工作import pandas as pd import numpy as np from matplotlib impor…

查立得php+mysql源码通用数据库配置教程

适用范围&#xff1a; 查分吧PHP多条件都输对版已有表万用查询系统 phpMySql已有数据表通用搜索可增删改查 查立得快搜系统(phpMysql) v20220208 查立得万能查&#xff08;phpmysql&#xff09; v20220512 及 各付费版 等几十款源码 数据库配置路径 数…

ReNamer Pro+Alist+RaiDrive妙用:实现批量修改网盘文件名称

ReNamer ProAlistRaiDrive妙用&#xff1a;批量修改管理网盘文件 说明工具下载Alist和RaiDrive安装和使用Renamer Pro激活和使用 说明 批量修改网盘文件名称的软件也大量存在&#xff0c;但是要么收费要么不好用&#xff0c;alist中也存在使用lamda表达式修改文件名称&#xf…

GT20L16S1Y标准汉字字库芯片完全解析(2)

接前一篇文章&#xff1a;GT20L16S1Y标准汉字字库芯片完全解析&#xff08;1&#xff09; 本文内容参考&#xff1a; 字库芯片GT20L16S1Y使用记录-CSDN博客 GT20L16S1Y字库IC驱动_gt20l16s1y字库芯片测试程序-CSDN博客 《GT20L16S1Y 标准点阵汉字库芯片产品规格书 V4.0I_K 2…

Day45:WEB攻防-PHP应用SQL二次注入堆叠执行DNS带外功能点黑白盒条件

目录 PHP-MYSQL-二次注入-DEMO&74CMS DEMO-用户注册登录修改密码 CMS-74CMS个人中心简历功能 PHP-MYSQL-堆叠注入-DEMO&CTF强网 Demo 2019强网杯-随便注&#xff08;CTF题型&#xff09; PHP-MYSQL-带外注入-DEMO&DNSLOG(让服务器主动把数据交出去) 知识点&…

C#,图论与图算法,输出无向图“欧拉路径”的弗勒里(Fleury Algorithm)算法和源程序

1 欧拉路径 欧拉路径是图中每一条边只访问一次的路径。欧拉回路是在同一顶点上开始和结束的欧拉路径。 这里展示一种输出欧拉路径或回路的算法。 以下是Fleury用于打印欧拉轨迹或循环的算法(源)。 1、确保图形有0个或2个奇数顶点。2、如果有0个奇数顶点,则从任意位置开始。…