java中设计模式的使用(持续更新中)

概述

设计模式的目的:编写软件过程中,程序员面临着来自耦合性,内聚性以及可维护性,可扩展性,重用性,灵活性等多方面的挑战,设计模式是为了让程序(软件),具有更好的

  • 代码重用性(相同功能的代码,不用多次编写)
  • 可读性(编程规范性,便于其他程序员的阅读和理解)
  • 可扩展性(当需要增加新的功能时,非常的方便,也叫可维护性)
  • 可靠性(当我们增加新的功能后,对原来的功能没用影响)
  • 使程序呈现高内聚,低耦合的特性

设计模式的七大原则:

  1. 单一职责原则
  • 对类来说,及一个类应该只负责一项职责。如类A负责两个不同的职责:职责1,职责2。当职责1需求变更而改变A时,可能造成职责2执行错误,所以需要将类A的粒度分解为A1,A2。(例如一个UserDao,同时操作user表和order表,因此需要将UserDao拆分为UserDao和OrderDao)
  • 单一职责原则注意事项和细节
    • 降低类的复杂度,一个类只负责一项职责
    • 提高类的可读性,可维护性
    • 降低变更引起的风险
    • 通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才可以在代码级违反单一职责原则;只有类中方法数量足够少,可以在方法级别保持单一职责原则
  1. 接口隔离原则
  • 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上。
  1. 依赖倒转原则
  • 高层模块不应该依赖底层模块,二者都应该依赖其抽象
  • 抽象不应该依赖细节,细节应该依赖抽象
  • 依赖倒转的中心思想是面向接口编程
  • 依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的框架要稳定的多。在java中,抽象指的是接口或抽象类,细节就是具体的实现
  • 使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成
  1. 里氏替换原则
  • 继承包含这样一层含义:父类中凡是已经实现好的方法,实际上是在设定规范和契约,虽然它不强制要求所有的子类必须遵循这些契约,但是如果子类对这些已经实现的方法任意修改,就会对整个继承体系造成破坏。
  • 继承在给程序设计带来遍历的同时,也带来了弊端。比如使用继承会给程序带来侵入性。程序的可移植性降低,增加对象间的耦合性,如果一个类被其他的类所继承,则当这个类需要修改时,必须考虑到所有的子类,并且修改后,所有设计到子类的功能都有可能产生故障。
  1. 开闭原则ocp(开闭原则,工厂模式)
  • 开闭原则(Open Closed Principle)是编程中最基础、最重要的设计原则
  • 一个软件实体如类,模块和函数应该对扩展开放(针对提供方),对修改关闭(针对使用方)用抽象构建框架,用实现扩展细节
  • 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
  • 编程中遵循其他原则,以及使用设计模式的目的就是遵循开闭原则
  1. 迪米特法则
  • 一个对象应该对其他对象保持最少的了解
  • 类与类关系越密切,耦合度越大
  • 迪米特法则,又叫最少知道原则,即一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类不管多么的复杂,都尽量将逻辑封装在类的内部。对外除了提供的public方法,不对外泄漏任务信息
  • 迪米特法则还有哥更简单的定义:只与直接的朋友通信。(直接朋友:每个对象都会与其他对象有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖,关联,组合,聚合等。其中,我们称出现成员变量,方法参数,方法返回值中的类为直接的朋友,而出现在局部变量中的类不是直接的朋友。也就是说,陌生的类最好不要以局部变量的形式出现在类的内部)
  1. 合成复用原则
  • 原则是尽量使用合成/聚合的方式,而不是使用继承

设计模式分为三种类型

  • 创建型模式:单例模式、抽象工厂模式、原型模式、建造者模式、工厂模式
  • 结构型模式:适配器模式、桥接模式、装饰者模式、组合模式、外观模式、享元模式、代理模式
  • 行为型模式:模板方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、责任链模式

1.单例模式

所谓类得单例设计模式、就是采取一定得方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得对象实例的方法(一般静态方法)。

  • 单例模式保证了系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能
  • 当想实例化一个单例类时候,必须要记住使用相应的获取对象的方法,而不是使用new
  • 单例模式使用的场景:需要频繁的进行创建和销毁的对象,创建对象时耗时过多或消耗资源过多(即:重量级对象),但又经常用到的对象,工具类对象、频繁访问数据库或文件的对象(比如数据源、session工厂等)

单例模式有八种方式:

  • 饿汉式(静态常量)
  • 饿汉式(静态代码块)
  • 懒汉式(线程不安全)
  • 懒汉式(线程安全,同步方法)
  • 懒汉式(线程安全,同步代码块)
  • 双重检查
  • 静态内部类
  • 枚举

步骤:构造方法私有化,提供一个公共的方法供外部获取对象

饿汉式(静态常量)

优点:在类装载的时候就完成实例化,避免了线程同步问题

缺点:从未使用过这个实例,造成内存浪费

public class Singleton {private static final Singleton instance = new Singleton();//构造方法私有化private Singleton(){}//公共方法获取实例public static Singleton getInstance(){return instance;}
}
饿汉式(静态代码块)
public class Singleton {private static Singleton instance;static {instance = new Singleton();}private Singleton(){}public static Singleton getInstance(){return instance;}
}
懒汉式(线程不安全)

在多线程环境下,一个线程进入了if判断语句块,还未来得及往下执行,另外一个线程获得cpu的时间片往下执行,会创建多个实例。

public class Singleto {private static Singleto instance;private Singleto(){}public static Singleto getInstance(){if(instance == null){instance = new Singleto();}return instance;}
}
懒汉式(线程安全,同步方法)

解决线程不安全问题,但是效率低,当对象已经被创建后,所有线程都还是会去竞争锁,还是会去进入判断

public class Singleto {private static Singleto instance;private Singleto(){}public static synchronized  Singleto getInstance(){if(instance == null){instance = new Singleto();}return instance;}
}
懒汉式(线程安全,同步代码块)
public class Singleto {private static Singleto instance;private Singleto(){}public static  Singleto getInstance(){synchronized (Singleto.class) {if (instance == null) {instance = new Singleto();}return instance;}}
}
双重检查

又叫双重校验锁,解决线程安全问题,同时解决竞争锁性能问题,并且满足懒加载

public class Singleto {private static Singleto instance;private Singleto() {}public static Singleto getInstance() {if (instance == null) {synchronized (Singleto.class) {if (instance == null) {instance = new Singleto();}}}return instance;}
}
静态内部类

SingletonHolder在Singleto装载时不会被加载,在调用getInstance时才被加载,达到懒加载模式。并且jvm加载类时是线程安全的。

public class Singleto {private Singleto(){}private static class SingletonHolder{private static final Singleto INSTANCE = new Singleto();}public static Singleto getInstance(){return SingletonHolder.INSTANCE;} 
}
枚举
public enum Singleton {INSTANCE;public void doSomething() {}
}

2.工厂模式

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

简单工厂模式又叫静态工厂模式,原理就是将需要创建的对象抽取到一个工厂类中。使用的时候通过调用工厂获取对象,这样可以将对象的创建等细节抽取到一处,发生变更时只用更改工厂类即可,满足ocp原则。

披萨基类

public abstract class Pizza {String name;public abstract void prepare();public abstract void bake();public abstract void cut();public abstract void box();
}

创建两种披萨

/*** 芝士披萨** @author * @date 2024-11-06*/
public class CheesePizza extends Pizza {public CheesePizza() {super.name = "奶酪披萨";}public void prepare() {System.out.println("开始制作" + name);}public void bake() {System.out.println(name + "烘烤中");}public void cut() {System.out.println(name + "切割中");}public void box() {System.out.println(name + "打包中");}
}
/*** 牛肉披萨** @author * @date 2024-11-06*/
public class BeefPizza extends Pizza{public BeefPizza() {super.name = "牛肉披萨";}public void prepare() {System.out.println("开始制作" + name);}public void bake() {System.out.println(name + "烘烤中");}public void cut() {System.out.println(name + "切割中");}public void box() {System.out.println(name + "打包中");}
}

创建一个披萨订单

/*** 订一个披萨** @author * @date 2024-11-06*/
public class OrderPizza {String type;public OrderPizza(String type) {this.type = type;}public void submitOrder() {String orderType;orderType = getType();Pizza pizza = PizzaFactory.createPizza(orderType);pizza.prepare();pizza.bake();pizza.cut();pizza.box();}private String getType() {return this.type;}
}

创建披萨工厂

/*** 披萨工厂** @author * @date 2024-11-06*/
public class PizzaFactory {public static Pizza createPizza(String orderType) {Pizza pizza = null;if (orderType.equals("cheese")) {pizza = new CheesePizza();} else if (orderType.equals("beef")) {pizza = new BeefPizza();} else {System.out.println("没有该类型");}return pizza;}
}

披萨店订购披萨

/*** 披萨店** @author * @date 2024-11-06*/
public class PizzaStore {public static void main(String[] args) {OrderPizza orderPizza = new OrderPizza("beef");orderPizza.submitOrder();}
}

这样的好处就是扩展性强,以后有其他的披萨类型,只用创建一个新的披萨类,然后再工厂中添加新的披萨,其他使用工厂的创建即可,不用关心对象的创建。不使用工厂模式,新添加一个类型时,所有创建披萨的地方都要更改。

2.2工厂方法模式

工厂方法模式:定义一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。

披萨基类

public abstract class Pizza {String name;public abstract void prepare();public abstract void bake();public abstract void cut();public abstract void box();
}

不同区域和口味的披萨

public class BJBeefPizza extends Pizza {public BJBeefPizza() {super.name = "北京牛肉披萨";}public void prepare() {System.out.println("开始制作" + name);}public void bake() {System.out.println(name + "烘烤中");}public void cut() {System.out.println(name + "切割中");}public void box() {System.out.println(name + "打包中");}
}public class BJCheesePizza extends Pizza {public BJCheesePizza() {super.name = "北京奶酪披萨";}public void prepare() {System.out.println("开始制作" + name);}public void bake() {System.out.println(name + "烘烤中");}public void cut() {System.out.println(name + "切割中");}public void box() {System.out.println(name + "打包中");}
}public class CDBeefPizza extends Pizza {public CDBeefPizza() {super.name = "成都牛肉披萨";}public void prepare() {System.out.println("开始制作" + name);}public void bake() {System.out.println(name + "烘烤中");}public void cut() {System.out.println(name + "切割中");}public void box() {System.out.println(name + "打包中");}
}public class CDCheesePizza extends Pizza {public CDCheesePizza() {super.name = "成都奶酪披萨";}public void prepare() {System.out.println("开始制作" + name);}public void bake() {System.out.println(name + "烘烤中");}public void cut() {System.out.println(name + "切割中");}public void box() {System.out.println(name + "打包中");}
} 

抽象工厂方法类

public abstract class OrderPizza {protected String orderType;abstract Pizza createPizza(String orderType);public OrderPizza(String type) {orderType = type;}public void submitOrder() {Pizza pizza = createPizza(orderType);pizza.prepare();pizza.bake();pizza.cut();pizza.box();}
}

具体的工厂实现

public class BJOrderPizza extends OrderPizza {public BJOrderPizza(String type) {super(type);}Pizza createPizza(String orderType) {Pizza pizza = null;if (orderType.equals("cheese")) {pizza = new BJCheesePizza();} else if (orderType.equals("beef")) {pizza = new BJBeefPizza();}return pizza;}
}public class CDOrderPizza extends OrderPizza{public CDOrderPizza(String type) {super(type);}Pizza createPizza(String orderType) {Pizza pizza = null;if (orderType.equals("cheese")) {pizza = new CDCheesePizza();} else if (orderType.equals("beef")) {pizza = new CDBeefPizza();}return pizza;}
}

演示


public class PizzaStore {public static void main(String[] args) {new BJOrderPizza("cheese").submitOrder();new CDOrderPizza("beef").submitOrder();}
}
2.3抽象工厂模式
  • 抽象工厂模式:定义了一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类
  • 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合
  • 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)
  • 将工厂抽象成两层,AbsFactory(抽象工厂)和具体实现的工厂子类。程序员可以根据创建对象类型使用相应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。

抽象工厂

public interface AbsFactory {Pizza createPizza(String type);
}

具体的工厂

public class BJFactory implements AbsFactory{public Pizza createPizza(String type) {Pizza pizza = null;if (type.equals("cheese")) {pizza = new BJCheesePizza();} else if (type.equals("beef")) {pizza = new BJBeefPizza();}return pizza;}
}public class CDFactory implements AbsFactory{public Pizza createPizza(String type) {Pizza pizza = null;if (type.equals("cheese")) {pizza = new CDCheesePizza();} else if (type.equals("beef")) {pizza = new CDBeefPizza();}return pizza;}
}

工厂的使用

public class OrderPizza {AbsFactory factory;public OrderPizza(AbsFactory factory){this.factory = factory;}public void submitOrder(String orderType) {Pizza pizza = factory.createPizza(orderType);pizza.prepare();pizza.bake();pizza.cut();pizza.box();}
}

结果展示


public class PizzaStore {public static void main(String[] args) {OrderPizza orderPizza = new OrderPizza(new BJFactory());orderPizza.submitOrder("cheese");}
}

3.原型模式

  • 原型模式(prototype)是指:用原型实例指定创建对象的种类。并且通过拷贝这些原型,创建新的对象。
  • 原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象,无需指定如何创建的细节
  • 工作原理是通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建,即,对象.clone()
3.1代码实现

原型类实现Cloneable接口,覆写clone方法

public class Sheep implements Cloneable{private String name;private int age;private String color;public Sheep(String name, int age, String color) {this.name = name;this.age = age;this.color = color;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {}@Overridepublic String toString() {return "Sheep{" +"name='" + name + '\'' +", age=" + age +", color='" + color + '\'' +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
3.2深拷贝和浅拷贝问题

浅拷贝

  • 对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象
  • 对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。因为实际上两个对象的该成员变量都指向同一个实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值
  • 浅拷贝则是使用默认的clone()方法来实现

深拷贝

  • 复制对象的所有基本数据类型的成员变量值
  • 为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象。也就是说,对象进行深拷贝要对整个对象进行拷贝
  • 深拷贝实现方式1:重写clone方法来实现深拷贝
  • 深拷贝实现方式2:通过对象序列化实现深拷贝(推荐)
package com.demo.design_pattern.prototype;import java.io.Serializable;public class Beef implements Cloneable, Serializable {private String name;public Beef(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Beef{" +"name='" + name + '\'' +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
package com.demo.design_pattern.prototype;import java.io.*;public class Sheep implements Cloneable , Serializable {private String name;private int age;private String color;private Beef friend;public Sheep(String name, int age, String color) {this.name = name;this.age = age;this.color = color;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {}public String getColor() {return color;}public void setColor(String color) {this.color = color;}public Beef getFriend() {return friend;}public void setFriend(Beef friend) {this.friend = friend;}@Overridepublic String toString() {return "Sheep{" +"name='" + name + '\'' +", age=" + age +", color='" + color + '\'' +", friend=" + friend +'}';}/** 方式一:完成深拷贝* */@Overrideprotected Object clone() throws CloneNotSupportedException {Object clone = super.clone();Sheep sheep = (Sheep) clone;sheep.friend = (Beef) this.friend.clone();return clone;}/** 方式二:完成深拷贝* */public Object deepClone(){Sheep sheep = null;ByteArrayOutputStream bos = null;ObjectOutputStream oos = null;ByteArrayInputStream bis =null;ObjectInputStream ois =null;//创建流对象try {bos = new ByteArrayOutputStream();oos = new ObjectOutputStream(bos);// 序列号,写入当前对象的二进制流oos.writeObject(this);bis = new ByteArrayInputStream(bos.toByteArray());ois = new ObjectInputStream(bis);// 反序列化,从二进制流产生当前对象sheep = (Sheep) ois.readObject();} catch (Exception e){e.printStackTrace();}finally {try {assert bos != null;bos.close();assert oos != null;oos.close();assert bis != null;bis.close();assert ois != null;ois.close();} catch (IOException e) {e.printStackTrace();}}return sheep;}
}

代码演示


  Sheep sheep = new Sheep("肖恩", 12, "白色");sheep.setFriend(new Beef("小黑"));
//        Sheep sheep1 = (Sheep) sheep.clone();Sheep sheep1 = (Sheep) sheep.deepClone();System.out.println(sheep1.getFriend() == sheep.getFriend());System.out.println(sheep1);System.out.println(sheep);

原型模式的注意事项和细节:

  • 创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能提高效率
  • 不用重新初始化对象,而是动态地获得运行时的状态
  • 如果原始对象发生改变(增加或减少属性),其它克隆对象也会发生相应的变化,而无需修改代码
  • 缺点:需要为每一个类配备一个克隆方法,对全新的类来说不是很难,但对已有的类进行改造时,需要修改其源代码,违背了opc原则。

4.建造者模式

4.1概念
  • 建造者模式(Builder Pattern)又叫生成器模式,是一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象
  • 建造者模式使一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。
4.2核心角色
  • Product(产品角色):一个具体的产品对象
  • Builder(抽象建造者):创建一个Product对象的各个部件指定的接口/抽象类。
  • ConcreteBuilder(具体建造者):实现接口,构建和装配各个部件。
  • Director(指挥者):构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。它主要又两个作用,一是:隔离了客户与对象的生产过程,二是负责控制产品对象的生产过程。
4.3代码实现

4.3.1建造的产品
/*** 房子 --- 对应product** @author * @date 2024-11-11*/
public class House {private String basic;private String wall;private String roofed;public String getBasic() {return basic;}public void setBasic(String basic) {this.basic = basic;}public String getWall() {return wall;}public void setWall(String wall) {this.wall = wall;}public String getRoofed() {return roofed;}public void setRoofed(String roofed) {this.roofed = roofed;}}
4.3.2抽象建造者-定义建造的方法
/*** 房屋建造者 --- 对应抽象的建造者** @author * @date 2024-11-11*/
public abstract class HouseBuilder {protected House house = new House();/** 定义房子建造的步骤* */public abstract void buildBasic();public abstract void buildWall();public abstract void roofed();public House buildHouse() {return house;}
}
4.3.3具体的建造执行者--实现具体的建造方法
public class HigBuilding extends HouseBuilder{@Overridepublic void buildBasic() {System.out.println("高楼房子打地基50米");house.setBasic("高楼房子打地基50米");}@Overridepublic void buildWall() {System.out.println("高楼房子砌墙80cm");house.setWall("高楼房子砌墙80cm");}@Overridepublic void roofed() {System.out.println("高楼房子封顶");house.setRoofed("高楼房子封顶");}
}
4.3.4指挥者 --- 定义建造的流程(控制方法的执行流程)
/*** 房子建造指挥者** @author * @date 2024-11-11*/
public class HouseDirector {private HouseBuilder houseBuilder;public HouseDirector(HouseBuilder houseBuilder) {this.houseBuilder = houseBuilder;}/*** 建造房子,定义产品的创建过程** @return */public House constructHouse() {// 调用建造者中的方法,完成产品的创建houseBuilder.buildBasic();houseBuilder.buildWall();houseBuilder.roofed();return houseBuilder.buildHouse();}
}
4.3.5使用
public class Client {public static void main(String[] args) {HigBuilding higBuilding = new HigBuilding();HouseDirector houseDirector = new HouseDirector(higBuilding);House house = houseDirector.constructHouse();System.out.println(house);}
}
4.3.6建造者模式的注意事项和细节
  • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制
  • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大,因此在这种情况下,要考虑是否选择建造者模式

抽象工厂模式 vs 建造者模式

抽象工厂模式实现对产品家族的创建,一个产品家族是这样的一系列产品:具有不同分类维度的产品组合,采用抽象工厂模式不需要关心构建过程,只关心什么产品由什么工厂生产即可。而建造者模式则是要去按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新产品

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

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

相关文章

linux基础io重定向

文章目录 目录 文章目录 前言 一、函数的认识 1、认识close函数和dup2函数 1、close函数: ​编辑 2、write、read函数 1、write函数 2、read函数 二、重定向 1.引入函数dup2 ​编辑 2、输出重定向 3.输出重定向 三、myshell重定向 总结 前言 接上一篇,…

[STM32] 定时器应用之输出比较 (五)

文章目录 1.输出比较2.PWM 介绍3.配置PWM 1.输出比较 OC: 输出比较。 输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。每个高级定时器和通用定时器都拥有4个输出比较通道高级定…

【计算机毕设】无查重 基于python豆瓣电影评论舆情数据可视化系统(完整系统源码+数据库+开发笔记+详细部署教程)✅

目录 【计算机毕设】无查重 基于python豆瓣电影数据可视化系统(完整系统源码数据库开发笔记详细部署教程)✅ 一、项目背景 二、项目目标 三、项目功能 四、开发技术介绍 五、数据库设计 六、项目展示 七、开发笔记 八、启动步骤文档 九、权威教…

后台管理系统窗体程序:个人中心

目录 个人中心的功能介绍: 1、进入页面 2、页面内的各种功能设计 (1)修改按钮 (2)页面的进入退出操作 一、网页设计 二、html代码 三、css代码 四、js代码 本次项目为后台管理系统,在本系统内的第七…

PLC如何支持GEM300标准?SECS/GEM通讯协议

1. 提供技术服务,保证户使用没问题 2. 支持市场所有的常规PLC 3. 支持常规组态软件,如wincc、组态王、组态屏等 4. 支持各类传感器,私有协议、modbus、web等 5. 无需二次开发,只需配置映射到已有的PLC地址 GEM300协议是为了满…

用 Google Sheets 表格增强 Tableau 数据分析的 3 种玩法

轻松实现文本翻译、网页数据抓取,甚至创建高级日期表来增强 Tableau 可视化效果! 作为一款强大的数据可视化工具,Tableau 的可视化能力毋庸置疑。然而,对于跟表格打交道的用户来说,它没有“创建表格”的功能&#xff0…

计算机网络 (3)计算机网络的性能

一、计算机网络性能指标 速率: 速率是计算机网络中最重要的性能指标之一,它指的是数据的传送速率,也称为数据率(Data Rate)或比特率(Bit Rate)。速率的单位是比特/秒(bit/s&#xff…

CAP与BASE分布式理论

CAP理论 C:Consistency 一致性:指强一致性,分布式系统中的所有节点在同一时刻具有同样的值、都是最新的数据副本,一致性保证了不管向哪台服务器写入数据,其他的服务器能实时同步数据 强一致性:写入数据的时…

【Java基础知识系列】之Java类的初始化顺序

前言 类的初始化顺序 简单场景 代码示例 public class Person {private String name initName();private String initName() {System.out.println("【父类】初始化实例变量name");return "【父类】史蒂夫";}private int age;private static int staticVa…

探索大规模语言模型(LLM)在心理健康护理领域中的应用与潜力

概述 心理健康是公共卫生最重要的领域之一。根据美国国家精神卫生研究所(NIMH)的数据,到 2021 年,22.8% 的美国成年人将患上某种形式的精神疾病。在全球范围内,精神疾病占非致命性疾病负担的 30%,并被世界…

解决 idea windows 设置maven离线模式之后,maven继续请求远程仓库

在内网开发的时候经常遇到没有办法来链接远程仓库的情况,这个时候需要设置maven的离线模式。 idea windows 设置maven离线模式之后,maven继续请求远程仓库 当设置完离线模式之后,有的时候执行maven的命令会报错,提示请求远程失败…

卷积神经网络 (CNN)

代码功能 网络结构: 卷积层: 两个卷积层,每个卷积层后接 ReLU 激活函数。 最大池化层用于降低维度。 全连接层: 使用一个隐藏层(128 个神经元)和一个输出层(10 类分类任务)。 数据集…

等保二级需要哪些安全设备?

在信息化高速发展的今天,服务器的安全性成为了企业乃至国家信息安全的重要基石。等保二级,作为信息安全等级保护制度中的一个关键环节,对服务器的安全防护提出了明确要求。本文将详细阐述服务器等保二级所需的各种安全设备,旨在为…

C++【深入项目-检测键盘】

神马是检测键盘,就是让编辑器可以检测键盘按下了什么按键,我们先科普复习检测键盘 。 检测键盘需要用到一些函数,请见下: ! KEY_DOWN( 80 ) 这个代码是检测按下键盘上P按键。那80是什么?原来是对应按键的&#xff0…

问题An object named ‘ResNetArcFace‘ was already registered in ‘arch‘ registry!

在安装 GFPGAN 的时候,一切都顺利,但是执行的时候出现了错误,哦还有一个问题, 问题一 就是如果basicsr安装不成功可以执行如下命令 pip install -i https://mirrors.aliyun.com/pypi/simple tb-nightly pip install -i https:/…

Leecode刷题C语言之最少翻转次数使二进制矩阵回文①

执行结果:通过 执行用时和内存消耗如下: 题目:最少翻转次数使二进制矩阵回文① 给你一个 m x n 的二进制矩阵 grid 。如果矩阵中一行或者一列从前往后与从后往前读是一样的,那么我们称这一行或者这一列是 回文 的。你可以将 grid 中任意格子…

K8S containerd拉取harbor镜像

前言 接前面的环境 K8S 1.24以后开始启用docker作为CRI,这里用containerd拉取 正文 vim /etc/containerd/config.toml #修改内容如下 #sandbox_image "registry.aliyuncs.com/google_containers/pause:3.10" systemd_cgroup true [plugins."io.…

三、计算机视觉_01图像的基本操作

0 前言 图像的读取和处理是计算机视觉领域中的一个基本任务,在Python中,有几个流行的库可以用来读取和处理图像数据 0.1 Matplotlib介绍 Matplotlib是Python中一个非常流行的绘图库,它通常用于数据可视化,虽然它不是专门的图像…

Liunx-Ubuntu22.04.1系统下配置Anaconda+pycharm+pytorch-gpu环境配置

这里写自定义目录标题 Liunx-Ubuntu22.04.1系统下配置Anacondapycharmpytorch-gpu环境配置一、Anaconda3配置1.Anaconda安装2.Anaconda更新3.Anaconda删除 二、pycharm配置1.pycharm安装 三、pytorch配置 Liunx-Ubuntu22.04.1系统下配置Anacondapycharmpytorch-gpu环境配置 一…

[Mysql] Mysql的多表查询----多表关系(下)

4、操作 方式二&#xff1a;创建表之后设置外键约束 外键约束也可以在修改表时添加&#xff0c;但是添加外键约束的前提是&#xff1a;从表中外键列中的数据必须与主表中主键列中的数据一致或者是没有数据。 语法&#xff1a; alter table <从表名> add constr…