设计模式之工厂模式(万字长文)

文章目录

  • 概述
  • 工厂模式的优点包括
  • 工厂模式有几种主要的变体
    • 看一个具体需求
    • 使用传统的方式来完成
      • 传统的方式的优缺点
    • 简单工厂模式基本介绍
    • 使用简单工厂模式
      • 简单工厂模式的优缺点
        • 优点:
        • 缺点:
    • 工厂方法模式
      • 看一个新的需求
      • 思路 1
      • 思路 2
      • 工厂方法模式介绍
      • 工厂方法模式应用案例
    • 抽象工厂模式
      • 基本介绍
      • 抽象工厂模式应用实例
  • 工厂模式小结

概述

工厂模式是一种创建型设计模式,它提供了一种创建对象的接口,但将对象的实例化过程推迟到子类或具体的实现类中。工厂模式的主要目的是将对象的创建与使用分离,从而降低代码的耦合性,增强代码的可维护性和可扩展性。

工厂模式的优点包括

  1. 对象的封装:将对象的创建细节封装在具体的工厂类中,使客户端不需要了解具体的创建过程,只需通过工厂来获取所需的对象。
  2. 代码重用:由于对象的创建过程在工厂类中集中管理,可以避免在多个地方重复创建相同类型的对象。
  3. 易于扩展:当需要添加新的产品或变体时,只需创建新的具体工厂类和产品类,而不需要修改现有代码。
  4. 降低耦合:客户端只与抽象工厂类进行交互,不直接依赖于具体产品类,从而降低了代码的耦合性。

工厂模式有几种主要的变体

  1. 简单工厂模式:不是正式的设计模式,更像是一种编程习惯,将对象的创建封装在一个静态方法中。
  2. 工厂方法模式:定义了一个用于创建对象的抽象方法,由具体的子类工厂来实现创建逻辑。
  3. 抽象工厂模式:提供一个创建一组相关或相互依赖对象的接口,每个具体工厂类负责创建一组具体产品。

看一个具体需求

看一个披萨的项目:要便于披萨种类的扩展,要便于维护

  1. 披萨的种类很多(比如 GreekPizz、CheesePizz 等)
  2. 披萨的制作有 prepare,bake, cut, box
  3. 完成披萨店订购功能。

使用传统的方式来完成

  1. 思路分析(类图)

在这里插入图片描述

新建一个tradition.pizzastore包

编写 OrderPizza.java 去订购需要的各种 Pizza

  1. 代码展示:
package com.lh.factory.tradition.pizzastore.order;import java.io.BufferedReader;import java.io.IOException;
import java.io.InputStreamReader;import com.lh.factory.simplefactory.pizzastore.pizza.CheesePizza;
import com.lh.factory.simplefactory.pizzastore.pizza.GreekPizza;
import com.lh.factory.simplefactory.pizzastore.pizza.PepperPizza;
import com.lh.factory.simplefactory.pizzastore.pizza.Pizza;public class OrderPizza {// 构造器public OrderPizza() {//比萨的Pizza pizza = null;String orderType; // 订购披萨的类型do {orderType = getType();if (orderType.equals("greek")) {pizza = new GreekPizza();pizza.setName("胡椒披萨");} else if (orderType.equals("cheese")) {pizza = new CheesePizza();pizza.setName("奶酪披萨");// 新写的代码} else if (orderType.equals("pepper")) {pizza = new PepperPizza();pizza.setName("希腊披萨");} else {System.out.println("不存在!");break;}// 输出 Pizza 制作过程pizza.prepare();pizza.bake();pizza.cut();pizza.box();} while (true);}// 写一个方法,可以获取客户希望订购的披萨种类private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 种类:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}

Pizza类,作为抽象类,功能参考类图

package com.lh.factory.tradition.pizzastore.pizza;//将Pizza 类做成抽象类
public abstract class Pizza {//名字protected String name;public void setName(String name) {this.name = name;}//原材料(不同的披萨,不一样的原材料),做成抽象方法,自定义实现public abstract void prepare();//烘烤public void bake() {System.out.println(name + "baking");}//切割public void cut() {System.out.println(name + "cuting");}//打包public void box() {System.out.println(name + "boxing");}
}

三个子类继承Pizza类

package com.lh.factory.tradition.pizzastore.pizza;public class CheesePizza extends Pizza{@Overridepublic void prepare() {System.out.println("给胡椒披萨,制作原材料");}
}package com.lh.factory.tradition.pizzastore.pizza;public class GreekPizza extends Pizza{@Overridepublic void prepare() {System.out.println("奶酪准备原材料");}
}package com.lh.factory.tradition.pizzastore.pizza;public class PepperPizza extends Pizza {@Overridepublic void prepare() {System.out.println(" 给希腊披萨 准备原材料 ");}
}

客户端:

package com.lh.factory.tradition.pizzastore.order;//相当于一个客户端,发出订购
public class PizzaStore {public static void main(String[] args) {//传统方法new OrderPizza();}
}

传统的方式的优缺点

  1. 优点是比较好理解,简单易操作。
  2. 缺点是违反了设计模式的 ocp 原则,即对扩展开放,对修改关闭。即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码.
  3. 比如我们这时要新增加一个 Pizza 的种类(Pepper 披萨),我们需要做如下修改.如果我们增加一个 Pizza 类,只要是订购 Pizza 的代码都需要修改.

在orderType中新增的代码如下图:参考上方的orderType代码,代码块中有如下功能:

在这里插入图片描述

  1. 改进的思路分析
    分析:修改代码可以接受,但是如果我们在其它的地方也有创建 Pizza 的代码,就意味着,也需要修改,而创建 Pizza的代码,往往有多处。
    思路:把创建 Pizza 对象封装到一个类中,这样我们有新的 Pizza 种类时,只需要修改该类就可,其它有创建到 Pizza对象的代码就不需要修改了.-> 简单工厂模式

简单工厂模式基本介绍

  1. 简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式

  2. 简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)

  3. 在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式

使用简单工厂模式

  1. 简单工厂模式的设计方案: 定义一个可以实例化 Pizaa 对象的类,封装创建对象的代码。

uml类图如下:

在这里插入图片描述

  1. 看代码示例

简单工厂模式的pizza包下的类,均不做改动,参考如上代码即可 (需要细心观看哦)

这里只展示修改后的OrderPizza和客户端了,以及新的简单工厂模式

package com.lh.factory.simplefactory.pizzastore.order;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;import com.lh.factory.simplefactory.pizzastore.pizza.CheesePizza;
import com.lh.factory.simplefactory.pizzastore.pizza.GreekPizza;
import com.lh.factory.simplefactory.pizzastore.pizza.PepperPizza;
import com.lh.factory.simplefactory.pizzastore.pizza.Pizza;public class OrderPizza {SimlpleFactory simlpleFactory;Pizza pizza = null;//构造器public OrderPizza(SimlpleFactory simlpleFactory) {//接受简单工厂setFactory(simlpleFactory);}public void setFactory(SimlpleFactory simlpleFactory) {String orderType = ""; // 用户输入的this.simlpleFactory = simlpleFactory; // 设置简单工厂对象do {orderType = getType();pizza = this.simlpleFactory.createPizza(orderType);//输出pizzaif (pizza != null) { //订购成功pizza.prepare();pizza.bake();pizza.cut();pizza.box();}else {System.out.println("订购披萨失败!");break;}} while (true);}// 写一个方法,可以获取客户希望订购的披萨种类private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 种类:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}

好处:只需要修改工厂类的代码即可,不需要在业务场景下进行修改

下面的工厂类写了两个相同的方法,没别的意思,就是告诉大家,简单工厂模式,也叫静态工厂模式

package com.lh.factory.simplefactory.pizzastore.order;import com.lh.factory.simplefactory.pizzastore.pizza.CheesePizza;
import com.lh.factory.simplefactory.pizzastore.pizza.GreekPizza;
import com.lh.factory.simplefactory.pizzastore.pizza.PepperPizza;
import com.lh.factory.simplefactory.pizzastore.pizza.Pizza;//简单工厂类
public class SimlpleFactory {//返回对应的Pizza public Pizza createPizza(String orderType) {Pizza pizza = null;if (orderType.equals("greek")) {pizza = new GreekPizza();pizza.setName("希腊披萨");} else if (orderType.equals("cheese")) {pizza = new CheesePizza();pizza.setName("奶酪披萨");// 新写的代码} else if (orderType.equals("pepper")) {pizza = new PepperPizza();pizza.setName("胡椒披萨");}return pizza;}//简单工厂模式也叫静态工厂模式public static Pizza createPizza2(String orderType) {Pizza pizza = null;System.out.println("使用简单工厂模式2");if (orderType.equals("greek")) {pizza = new GreekPizza();pizza.setName("希腊披萨");} else if (orderType.equals("cheese")) {pizza = new CheesePizza();pizza.setName("奶酪披萨");// 新写的代码} else if (orderType.equals("pepper")) {pizza = new PepperPizza();pizza.setName("胡椒披萨");}return pizza;}
}

静态工厂模式的OrderPizza类(静态工厂模式看起来更加方便,减少了一部分代码)

package com.lh.factory.simplefactory.pizzastore.order;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;import com.lh.factory.simplefactory.pizzastore.pizza.Pizza;public class OrderPizza2 {Pizza pizza = null;String orderType = "";// 构造器public OrderPizza2() {// 接受简单工厂do {orderType = getType();pizza = SimlpleFactory.createPizza2(orderType);// 输出pizzaif (pizza != null) { // 订购成功pizza.prepare();pizza.bake();pizza.cut();pizza.box();} else {System.out.println("订购披萨失败!");break;}} while (true);}// 写一个方法,可以获取客户希望订购的披萨种类private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 种类:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}}

简单工厂模式的优缺点

优点:

封装对象的创建逻辑:通过将对象的创建逻辑封装在静态工厂方法中,客户端代码无需了解对象的具体创建过程,降低了对象创建的复杂度。

代码组织:简单工厂模式可以集中管理对象的创建逻辑,使代码更加清晰、简洁,并且易于维护。

灵活性:如果需要更改或替换产品,只需修改工厂方法的实现,不会影响客户端代码,从而实现了产品变化对客户端的透明性。

缺点:

不符合开闭原则:当需要添加新的产品类型时,可能需要修改工厂方法的代码,这违背了开闭原则(对扩展开放,对修改关闭)。

工厂类职责过重:工厂类通常负责创建多种不同类型的对象,导致工厂类职责变得较重,随着产品种类的增加,工厂类会变得越来越复杂。

不支持多个工厂类:在简单工厂模式中,只有一个工厂类负责所有对象的创建,这可能会导致工厂类变得庞大,难以管理。

不够灵活:由于所有对象的创建逻辑集中在一个工厂类中,如果不同的产品有复杂的创建过程,可能无法很好地适应。

工厂方法模式

看一个新的需求

披萨项目新的需求:客户在点披萨时,可以点不同口味的披萨,比如 北京的奶酪 pizza、北京的胡椒 pizza 或者是伦敦的奶酪 pizza、伦敦的胡椒 pizza。

思路 1

使用简单工厂模式,创建不同的简单工厂类,比如 BJPizzaSimpleFactory、LDPizzaSimpleFactory 等等。从当前这个案例来说,也是可以的,但是考虑到项目的规模,以及软件的可维护性、可扩展性并不是特别好 (考验大家抽象能力)

思路 2

使用工厂方法模式

工厂方法模式介绍

  1. 工厂方法模式设计方案:将披萨项目的实例化功能抽象成抽象方法,在不同的口味点餐子类中具体实现。
  2. 工厂方法模式:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。

工厂方法模式应用案例

  1. 披萨项目新的需求:客户在点披萨时,可以点不同口味的披萨,比如 北京的奶酪 pizza、北京的胡椒 pizza 或者是伦敦的奶酪 pizza、伦敦的胡椒 pizza

  2. 思路分析图解

在这里插入图片描述

Pizza类与它的子类

package com.lh.factory.factorymethod.pizzastore.pizza;//将Pizza 类做成抽象类
public abstract class Pizza {//名字protected String name;//原材料(不同的披萨,不一样的原材料),做成抽象方法,自定义实现public abstract void prepare();//烘烤public void bake() {System.out.println(name + "baking");}//切割public void cut() {System.out.println(name + "cuting");}//打包public void box() {System.out.println(name + "boxing");}public void setName(String name) {this.name = name;}
}public class LDPepperPizza extends Pizza{@Overridepublic void prepare() {setName("伦敦胡椒披萨...");System.out.println("伦敦胡椒pizza,准备原材料");}
}public class LDCheesePizza extends Pizza{@Overridepublic void prepare() {setName("伦敦奶酪披萨...");System.out.println("伦敦奶酪pizza,准备原材料");}}public class BJPepperPizza extends Pizza{@Overridepublic void prepare() {setName("北京胡椒披萨...");System.out.println("北京pizza,准备原材料");}
}public class BJCheesePizza extends Pizza{@Overridepublic void prepare() {setName("北京奶酪披萨...");System.out.println("北京pizza,准备原材料");}
}

工厂抽象类,定义一个工厂的抽象方法,让其子类自己实现,这样可以不需要动工厂自身的代码,如果想添加新的品种,可以新创建一个,继承工厂抽象类重写其方法就可以

package com.lh.factory.factorymethod.pizzastore.order;import java.io.BufferedReader;import java.io.IOException;
import java.io.InputStreamReader;import com.lh.factory.factorymethod.pizzastore.pizza.Pizza;public abstract class OrderPizza {// 构造器public OrderPizza() {Pizza pizza = null;String orderType; // 订购披萨的类型do {orderType = getType();//抽象方法,由工厂子类完成pizza = createPizza(orderType);// 输出 Pizza 制作过程pizza.prepare();pizza.bake();pizza.cut();pizza.box();} while (true);}// 定义一个抽象方法,createPizza,让各个工厂子类自己实现abstract Pizza createPizza(String orderType);// 写一个方法,可以获取客户希望订购的披萨种类private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 种类:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}

两个分工厂分别继承OrderPizza 类,分别实现各自的功能

package com.lh.factory.factorymethod.pizzastore.order;import com.lh.factory.factorymethod.pizzastore.pizza.LDCheesePizza;
import com.lh.factory.factorymethod.pizzastore.pizza.LDPepperPizza;
import com.lh.factory.factorymethod.pizzastore.pizza.Pizza;public class LDOrderPizza extends OrderPizza{@OverridePizza createPizza(String orderType) {Pizza pizza = null;if (orderType.equals("cheese")) {pizza = new LDCheesePizza();}else if (orderType.equals("pepper")) {pizza = new LDPepperPizza();}	return pizza;}
}package com.lh.factory.factorymethod.pizzastore.order;import com.lh.factory.factorymethod.pizzastore.pizza.BJCheesePizza;
import com.lh.factory.factorymethod.pizzastore.pizza.BJPepperPizza;
import com.lh.factory.factorymethod.pizzastore.pizza.Pizza;public class BJOrderPizza extends OrderPizza{@OverridePizza createPizza(String orderType) {Pizza pizza = null;if (orderType.equals("cheese")) {pizza = new BJCheesePizza();}else if (orderType.equals("pepper")) {pizza = new BJPepperPizza();}return pizza;}
}

客户端:

package com.lh.factory.factorymethod.pizzastore.order;public class PizzaStore {public static void main(String[] args) {//创建北京口味的各种Pizzanew BJOrderPizza();//创建伦敦口味的各种Pizzanew LDOrderPizza();}
}

抽象工厂模式

基本介绍

  1. 抽象工厂模式:定义了一个 interface 用于创建相关或有依赖关系的对象簇,而无需指明具体的类
  2. 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。
  3. 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
  4. 将工厂抽象成两层,AbsFactory(抽象工厂) 和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应
    的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
  5. 类图

在这里插入图片描述

抽象工厂模式应用实例

Pizza类与它的子类,与抽象工厂方法模式中的Pizza类和它的子类代码一样,这里不做复制粘贴,耐心可观看

工厂接口:

package com.lh.factory.absfactory.pizzastore.order;import com.lh.factory.absfactory.pizzastore.pizza.Pizza;//一个抽象工厂模式的抽象层(接口)
public interface AbsFactory {//让下面的工厂子类具体实现Pizza createFactory(String orderType);}

OrderType工厂类,将业务需求写好之后,不动此代码。直接调用即可

package com.lh.factory.absfactory.pizzastore.order;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;import com.lh.factory.absfactory.pizzastore.pizza.Pizza;public class OrderPizza {// 是聚合AbsFactory factory;//构造器public OrderPizza(AbsFactory factory) {setFactory(factory);}//指向子类实例化private void setFactory(AbsFactory factory) {Pizza pizza = null;String orderType; // 用户输入披萨this.factory = factory;do {orderType = getType();//可能是北京,或者是伦敦pizza = factory.createFactory(orderType);if (pizza != null) { //订购 okpizza.prepare();pizza.bake();pizza.cut();pizza.box();}else {System.out.println("订购失败!");break;}} while (true);}// 写一个方法,可以获取客户希望订购的披萨种类private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 种类:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}

两个工厂各自实现AbsFactory,各自实现自己的功能

package com.lh.factory.absfactory.pizzastore.order;import com.lh.factory.absfactory.pizzastore.pizza.BJCheesePizza;
import com.lh.factory.absfactory.pizzastore.pizza.BJPepperPizza;
import com.lh.factory.absfactory.pizzastore.pizza.Pizza;//北京工厂子类
public class BJFactory implements AbsFactory{	@Overridepublic Pizza createFactory(String orderType) {// TODO Auto-generated method stubSystem.out.println("使用的是抽象工厂模式");Pizza pizza = null;if (orderType.equals("cheese")) {pizza = new BJCheesePizza();}else if (orderType.equals("pepper")) {pizza = new BJPepperPizza();}return pizza;}
}package com.lh.factory.absfactory.pizzastore.order;import com.lh.factory.absfactory.pizzastore.pizza.LDCheesePizza;
import com.lh.factory.absfactory.pizzastore.pizza.LDPepperPizza;
import com.lh.factory.absfactory.pizzastore.pizza.Pizza;//伦敦工厂子类
public class LDFactory implements AbsFactory{@Overridepublic Pizza createFactory(String orderType) {// TODO Auto-generated method stubSystem.out.println("使用的是抽象工厂模式");Pizza pizza = null;if (orderType.equals("cheese")) {pizza = new LDCheesePizza();}else if (orderType.equals("pepper")) {pizza = new LDPepperPizza();}return pizza;}
}

工厂模式小结

  1. 工厂模式的意义
    将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。
  2. 三种工厂模式 (简单工厂模式、工厂方法模式、抽象工厂模式)
  3. 设计模式的依赖抽象原则
    • 创建对象实例时,不要直接 new 类, 而是把这个 new 类的动作放在一个工厂的方法中,并返回。有的书上说,
      变量不要直接持有具体类的引用。
    • 不要让类继承具体类,而是继承抽象类或者是实现 interface(接口)
    • 不要覆盖基类中已经实现的方法。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

macOS上编译obs-studio

前言 最近基于obs的1个二开程序,需要移植到macOS平台上,由于遇到些问题,本文记录下如何在macOS上配置&编译&运行obs程序完整过程。 下载 首先下载cmake-gui工具,下载CMAKE,选择对应macOS平台的cmake版本&…

【ArcGIS微课1000例】0074:ArcGIS热点分析(Getis-Ord Gi*)---犯罪率热点图

严重声明:本文来自专栏《ArcGIS微课1000例:从点滴到精通》,为CSDN博客专家刘一哥GIS原创,原文及专栏地址为:(https://blog.csdn.net/lucky51222/category_11121281.html),谢绝转载或爬取!!! 文章目录 一、热点分析工具介绍二、ArcGIS热点分析案例1. 普通热点分析2. 加…

【ArcGIS微课1000例】0072:如何生成空间权重矩阵

严重声明:本文来自专栏《ArcGIS微课1000例:从点滴到精通》,为CSDN博客专家刘一哥GIS原创,原文及专栏地址为:(https://blog.csdn.net/lucky51222/category_11121281.html),谢绝转载或爬取!!! 文章目录 一、空间权重矩阵工具介绍二、ArcGIS生成空间权重矩阵三、注意事项…

从零开始配置Jenkins与GitLab集成:一步步实现持续集成

在软件开发中,持续集成是确保高效协作和可靠交付的核心实践。以下是在CentOS上安装配置Jenkins与GitLab集成的详细步骤: 1.安装JDK 解压JDK安装包并设置环境变量: JDK下载网址 Java Downloads | Oracle 台灣 tar zxvf jdk-11.0.5_linux-x64_b…

设计模式三原则

1.1单一职责原则 C 面向对象三大特性之一的封装指的就是将单一事物抽象出来组合成一个类,所以我们在设计类的时候每个类中处理的是单一事物而不是某些事物的集合。 设计模式中所谓的单一职责原则,就是对一个类而言,应该仅有一个引起它变化的原…

怎么借助ChatGPT处理数据结构的问题

目录 使用ChatGPT进行数据格式化转换 代码示例 ChatGPT格式化数据提示语 代码示例 批量格式化数据提示语 代码示例 ChatGPT生成的格式化批处理代码 使用ChatGPT合并不同数据源的数据 合并数据提示语 自动合并数据提示语 ChatGPT生成的自动合并代码 结论 数据合并是…

RT-Thread内核学习

内核框架 内核是操作系统最基础也是最重要的部分,内核处于硬件层之上,内核部分包括内核库、实时内核实现。 内核库是为了保证内核能够独立运行的一套小型的类似C库的函数实现子集。这部分根据编译器不同自带C库的情况也会不同。 当使用GNU GCC编译器时&…

波奇学C++:stl的list模拟实现

list是双向带头链表。所以迭代器end()相当于哨兵卫的头。 list不支持和[]重载&#xff0c;原因在于list空间不是连续的&#xff0c;和[]的代价比较大。 访问第n个节点&#xff0c;只能用for循环&#xff0c;来实现 list<int> l; l.push_back(0); l.push_back(1); l.pu…

hive-列转行

转成 select customer_code,product_type from temp.temp_xx LATERAL VIEW explode(SPLIT(product_types,,)) table_tmp AS product_type where customer_code K100515182

C#开发WinForm之DataGridView开发

前言 DataGridView是开发Winform的一个列表展示&#xff0c;类似于表格。学会下面的基本特征用法&#xff0c;再辅以经验&#xff0c;基本功能开发没问题。 1.设置 DataGridView表格行首为序号索引, //设置 DataGridView表格行首为序号索引private void dataGridView1_RowPost…

python实现卡尔曼滤波代码详解

Kalman滤波算法的原理可以参考&#xff1a; 卡尔曼滤波理解 python中filterpy库中实现了各种滤波算法&#xff0c; 其中就包括了kalman滤波算法。 具体实现代码&#xff1a; https://github.com/rlabbe/filterpy/blob/master/filterpy/kalman/kalman_filter.py 本文针对该代码…

数据结构——布隆计算器

文章目录 1.什么是布隆过滤器&#xff1f;2.布隆过滤器的原理介绍3.布隆过滤器使用场景4.通过 Java 编程手动实现布隆过滤器5.利用Google开源的 Guava中自带的布隆过滤器6.Redis 中的布隆过滤器6.1介绍6.2使用Docker安装6.3常用命令一览6.4实际使用 1.什么是布隆过滤器&#xf…

骨传导耳机对大脑有影响吗?骨传导耳机有什么副作用

先上结论&#xff0c;骨传导耳机对大脑没有影响。骨传导耳机使用的是骨传导技术&#xff0c;声音是通过头骨骨头和颌骨给内耳传递的&#xff0c;而不是通过传统的空气传播。 简单来说&#xff0c;骨传导技术使用人类骨骼结构和声学原理来传递声音&#xff0c;这种现象我们也很常…

最新Burp Suite入门技术

Burp Suite的安装 Burp Suite是一款集成化的渗透测试工具&#xff0c;包含了很多功能&#xff0c;可以帮助我们高效地完成对Web应用程序的渗透测试和安全检测。 Burp Suite由Java语言编写&#xff0c;Java自身的跨平台性使我们能更方便地学习和使用这款软件。不像其他自动化测…

vue3 基础知识 (组件之间的通信 and vuex) 02

侬好哇 &#xff01;&#x1f60d; 文章目录 一、组件的通信 &#xff08;父传子&#xff09;二、非 Prop 的Attribute (属性&#xff09;三、组件的通信 &#xff08;子传父&#xff09;四、非父子组件的相互通信&#xff08;Provide/Inject&#xff09;五、非父子组件的相互通…

顺序表之初

欢迎来到我的&#xff1a;世界 希望作者的文章对你有所帮助&#xff0c;有不足的地方还请指正&#xff0c;大家一起学习交流 ! 目录 线性表简介顺序表定义动态顺序表的初始化尾插头插Cheak 判断是否增容尾删&#xff1a;头删&#xff1a;打印在pos位置前插入x删除pos位置的值查…

Python学习笔记_实战篇(二)_django多条件筛选搜索

多条件搜索在很多网站上都有用到&#xff0c;比如京东&#xff0c;淘宝&#xff0c;51cto&#xff0c;等等好多购物教育网站上都有&#xff0c;当然网上也有很多开源的比楼主写的好的多了去了&#xff0c;仅供参考&#xff0c;哈哈 先来一张效果图吧&#xff0c;不然幻想不出来…

浅谈小程序开源业务架构建设之路

一、业务介绍 1.1 小程序开源整体介绍 百度从做智能小程序的第一天开始就打造真正开源开放的生态&#xff0c;我们的愿景是&#xff1a;定义移动时代最佳体验&#xff0c;建设智能小程序行业标准&#xff0c;打破孤岛&#xff0c;共建开源、开放、繁荣的小程序行业生态。百度智…

电子电路学习笔记之SA1117BH-1.2TR——LDO低压差线性稳压器

关于LDO调节器&#xff08;Low Dropout Regulator&#xff09;是一种电压稳压器件&#xff0c;常用于电子设备中&#xff0c;用于将高电压转换为稳定的低电压。它能够在输入电压和输出电压之间产生较小的差异电压&#xff0c;因此被称为"低压差稳压器"。 LDO调节器通…

设计模式之职责链模式(ChainOfResponsibility)的C++实现

1、职责链模式的提出 在软件开发过程中&#xff0c;发送者经常发送一个数据请求给特定的接收者对象&#xff0c;让其对请求数据进行处理&#xff08;一个数据请求只能有一个对象对其处理&#xff09;。如果发送的每个数据请求指定特定的接收者&#xff0c; 将带来发送者与接收…