【Java常见的几种设计模式】

Java常见的几种设计模式

  • 1. 单例模式(Singleton Pattern)
  • 2. 工厂模式(Factory pattern)
  • 3. 抽象工厂模式(Abstract Factory Pattern)
  • 4. 建造者模式(Builder Pattern)
  • 5. 原型模式(Prototype pattern)
  • 6. 适配器模式(Adapter Pattern)
  • 7. 装饰器模式(Decorator Pattern)
  • 8. 观察者模式(Observer Pattern)

1. 单例模式(Singleton Pattern)

单例模式(Singleton Pattern)是一种创建型设计模式,用于确保一个类只有一个实例,并提供全局访问点。

在Java中,单例模式的实现通常包括以下几个关键要素:

  1. 私有的构造方法(Private Constructor):为了防止外部代码通过构造方法创建多个实例,单例类的构造方法需要被声明为私有的。

  2. 静态私有实例变量(Private Static Instance Variable):单例类内部维护一个静态私有的实例变量,用于保存单例对象的唯一实例。

  3. 静态公有获取方法(Public Static Getter Method):提供一个公有的静态方法,用于获取单例对象的实例。该方法通常被命名为getInstance()

  4. 延迟实例化(Lazy Initialization):单例对象的实例化通常是延迟进行的,即在第一次调用getInstance()方法时才创建实例。

  5. 线程安全性(Thread Safety):如果在多线程环境下使用单例模式,需要考虑线程安全性。可以通过加锁(synchronized)或使用双重检查锁定(double-checked locking)等方式来确保线程安全。

下面是一个简单的示例,展示了如何在Java中实现单例模式:

public class Singleton {private static Singleton instance;private Singleton() {// 私有构造方法}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}

在上述示例中,Singleton类的构造方法被声明为私有的,确保其他类无法直接实例化该类。通过静态方法getInstance()获取Singleton类的实例,如果实例为null,则进行实例化。由于使用了synchronized关键字,该实现方式是线程安全的,但可能会影响性能。

另一种常用的线程安全的延迟初始化方式是双重检查锁定(double-checked locking):

public class Singleton {private volatile static Singleton instance;private Singleton() {// 私有构造方法}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}

在上述示例中,使用了volatile关键字来确保在多线程环境下对instance变量的可见性。双重检查锁定可以减少锁的使用次数,提高性能。

需要注意的是,单例模式的实现方式有多种,选择适合具体情况的方式非常重要。此外,单例模式在某些情况下可能会导致全局状态的存在,因此需要谨慎使用,确保不会引入不必要的复杂性和耦合性。

2. 工厂模式(Factory pattern)

工厂模式(Factory Pattern)是一种创建型设计模式,用于定义一个用于创建对象的接口,但将具体的对象创建过程延迟到子类中。

在Java中,工厂模式主要包括以下几个角色:

  1. 抽象产品(Abstract Product):定义了产品的接口,具体产品需要实现该接口。

  2. 具体产品(Concrete Product):实现了抽象产品接口的具体类,是工厂模式中要创建的对象。

  3. 抽象工厂(Abstract Factory):定义了创建产品的接口,包含一个或多个创建产品的抽象方法。

  4. 具体工厂(Concrete Factory):实现了抽象工厂接口,负责创建具体产品的对象。

工厂模式的核心思想是将对象的创建过程封装在工厂类中,客户端只需通过工厂类来创建对象,而无需关心具体的创建细节。这样可以降低客户端与具体产品类之间的耦合度,使得系统更加灵活和可扩展。

下面是一个简单的示例,展示了如何在Java中实现工厂模式:

// 抽象产品
public interface Product {void operation();
}// 具体产品 A
public class ConcreteProductA implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductA operation");}
}// 具体产品 B
public class ConcreteProductB implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductB operation");}
}// 抽象工厂
public interface Factory {Product createProduct();
}// 具体工厂 A
public class ConcreteFactoryA implements Factory {@Overridepublic Product createProduct() {return new ConcreteProductA();}
}// 具体工厂 B
public class ConcreteFactoryB implements Factory {@Overridepublic Product createProduct() {return new ConcreteProductB();}
}

在上述示例中,Product是抽象产品接口,定义了产品的操作方法。ConcreteProductAConcreteProductB是具体产品类,分别实现了Product接口。

Factory是抽象工厂接口,定义了创建产品的方法。ConcreteFactoryAConcreteFactoryB是具体工厂类,分别实现了Factory接口,并负责创建具体产品的对象。

客户端可以通过具体工厂来创建具体产品的对象,如下所示:

public class Client {public static void main(String[] args) {Factory factoryA = new ConcreteFactoryA();Product productA = factoryA.createProduct();productA.operation();Factory factoryB = new ConcreteFactoryB();Product productB = factoryB.createProduct();productB.operation();}
}

在上述示例中,客户端通过具体工厂ConcreteFactoryAConcreteFactoryB来创建具体产品ConcreteProductAConcreteProductB的对象,并调用其操作方法。

工厂模式可以根据具体的业务需求进行灵活的扩展和变化。通过定义抽象工厂和具体工厂,可以轻松添加新的产品和工厂,而无需修改客户端代码。这样可以实现代码的解耦和可维护性。

3. 抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式(Abstract Factory Pattern)。抽象工厂模式是一种创建型设计模式,用于提供一个接口,用于创建一系列相关或依赖对象的家族,而无需指定具体的类。

在Java中,抽象工厂模式主要包括以下几个角色:

  1. 抽象工厂(Abstract Factory):定义了创建一系列产品的方法,通常是一个接口或抽象类。

  2. 具体工厂(Concrete Factory):实现了抽象工厂接口,负责创建一系列具体产品的对象。

  3. 抽象产品(Abstract Product):定义了产品的接口,具体产品需要实现该接口。

  4. 具体产品(Concrete Product):实现了抽象产品接口的具体类,是抽象工厂模式中要创建的对象。

抽象工厂模式的核心思想是将一系列相关的产品组织在一起,通过抽象工厂来创建这些产品的对象。客户端通过抽象工厂接口来创建产品,而无需关心具体的产品类。

下面是一个简单的示例,展示了如何在Java中实现抽象工厂模式:

// 抽象产品 A
public interface AbstractProductA {void operationA();
}// 具体产品 A1
public class ConcreteProductA1 implements AbstractProductA {@Overridepublic void operationA() {System.out.println("ConcreteProductA1 operationA");}
}// 具体产品 A2
public class ConcreteProductA2 implements AbstractProductA {@Overridepublic void operationA() {System.out.println("ConcreteProductA2 operationA");}
}// 抽象产品 B
public interface AbstractProductB {void operationB();
}// 具体产品 B1
public class ConcreteProductB1 implements AbstractProductB {@Overridepublic void operationB() {System.out.println("ConcreteProductB1 operationB");}
}// 具体产品 B2
public class ConcreteProductB2 implements AbstractProductB {@Overridepublic void operationB() {System.out.println("ConcreteProductB2 operationB");}
}// 抽象工厂
public interface AbstractFactory {AbstractProductA createProductA();AbstractProductB createProductB();
}// 具体工厂 1
public class ConcreteFactory1 implements AbstractFactory {@Overridepublic AbstractProductA createProductA() {return new ConcreteProductA1();}@Overridepublic AbstractProductB createProductB() {return new ConcreteProductB1();}
}// 具体工厂 2
public class ConcreteFactory2 implements AbstractFactory {@Overridepublic AbstractProductA createProductA() {return new ConcreteProductA2();}@Overridepublic AbstractProductB createProductB() {return new ConcreteProductB2();}
}

在上述示例中,AbstractProductAAbstractProductB是抽象产品接口,定义了产品的操作方法。ConcreteProductA1ConcreteProductA2ConcreteProductB1ConcreteProductB2是具体产品类,分别实现了抽象产品接口。

AbstractFactory是抽象工厂接口,定义了创建产品的方法。ConcreteFactory1ConcreteFactory2是具体工厂类,分别实现了AbstractFactory接口,并负责创建具体产品的对象。

客户端可以通过具体工厂来创建一系列相关产品的对象,如下所示:

public class Client {public static void main(String[] args) {AbstractFactory factory1 = new ConcreteFactory1();AbstractProductA productA1 = factory1.createProductA();AbstractProductB productB1 = factory1.createProductB();productA1.operationA();productB1.operationB();AbstractFactory factory2 = new ConcreteFactory2();AbstractProductA productA2 = factory2.createProductA();AbstractProductB productB2 = factory2.createProductB();productA2.operationA();productB2.operationB();}
}

在上述示例中,客户端通过具体工厂ConcreteFactory1ConcreteFactory2来创建一系列相关产品的对象,并调用其操作方法。

抽象工厂模式可以帮助我们实现高层模块与具体产品类的解耦,使得系统更加灵活和可扩展。通过定义抽象工厂和具体工厂,可以轻松切换不同的产品家族,并且不需要修改客户端代码。这样可以实现代码的解耦和可维护性。

4. 建造者模式(Builder Pattern)

建造者模式(Builder Pattern)是一种创建型设计模式,用于将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。

在Java中,建造者模式主要包括以下几个角色:

  1. 产品类(Product):定义了要构建的复杂对象。

  2. 抽象建造者(Builder):定义了构建产品的抽象方法,通常包括设置不同部分的方法。

  3. 具体建造者(Concrete Builder):实现了抽象建造者接口,负责具体产品各个部分的构建。

  4. 指挥者(Director):负责调用具体建造者来构建产品对象,它不知道具体的构建细节。

下面是一个简单的示例,展示了如何在Java中实现建造者模式:

// 产品类
public class Product {private String partA;private String partB;private String partC;public void setPartA(String partA) {this.partA = partA;}public void setPartB(String partB) {this.partB = partB;}public void setPartC(String partC) {this.partC = partC;}public void show() {System.out.println("PartA: " + partA);System.out.println("PartB: " + partB);System.out.println("PartC: " + partC);}
}// 抽象建造者
public interface Builder {void buildPartA();void buildPartB();void buildPartC();Product getResult();
}// 具体建造者
public class ConcreteBuilder implements Builder {private Product product;public ConcreteBuilder() {this.product = new Product();}@Overridepublic void buildPartA() {product.setPartA("PartA");}@Overridepublic void buildPartB() {product.setPartB("PartB");}@Overridepublic void buildPartC() {product.setPartC("PartC");}@Overridepublic Product getResult() {return product;}
}// 指挥者
public class Director {public Product construct(Builder builder) {builder.buildPartA();builder.buildPartB();builder.buildPartC();return builder.getResult();}
}

在上述示例中,Product是要构建的复杂对象,它具有多个部分(partA、partB、partC)。

Builder是抽象建造者接口,定义了构建产品的抽象方法。ConcreteBuilder是具体建造者类,实现了抽象建造者接口,负责实际构建产品的各个部分,并返回最终构建的产品对象。

Director是指挥者类,负责调用具体建造者来构建产品对象。客户端通过指挥者来构建产品,而无需直接与具体建造者交互。

使用建造者模式的客户端代码示例如下:

public class Client {public static void main(String[] args) {Builder builder = new ConcreteBuilder();Director director = new Director();Product product = director.construct(builder);product.show();}
}

在上述示例中,客户端创建了具体建造者ConcreteBuilder和指挥者Director,然后通过指挥者调用具体建造者的方法来构建产品对象。最后,客户端可以通过产品对象的方法来展示产品的各个部分。

建造者模式适用于需要构建复杂对象,并且构建过程中涉及多个部分的情况。通过将构建过程封装在具体建造者中,可以灵活地组合和配置不同的部分,从而创建不同的表示。同时,建造者模式也可以避免构造方法的参数过多和构造方法重载的问题,使代码更加清晰和易于维护。

5. 原型模式(Prototype pattern)

原型模式(Prototype Pattern)是一种创建型设计模式,用于通过复制现有对象来创建新对象,而无需依赖于显式的实例化过程。它通过克隆(复制)现有对象的属性来创建新对象,从而避免了直接创建对象的开销和复杂性。

在Java中,原型模式的核心概念是原型接口(Prototype)和具体原型(Concrete Prototype)。

  1. 原型接口(Prototype):定义了克隆方法 clone(),它是原型模式的核心。该接口可以是一个抽象类或者接口。在Java中,可以通过实现 Cloneable 接口来指示对象是可克隆的。

  2. 具体原型(Concrete Prototype):实现了原型接口,并实现了克隆方法。具体原型是需要被复制的对象。

下面是一个简单的示例,展示了如何在Java中实现原型模式:

// 原型接口
public interface Prototype extends Cloneable {Prototype clone();
}// 具体原型
public class ConcretePrototype implements Prototype {private String name;public ConcretePrototype(String name) {this.name = name;}public void setName(String name) {this.name = name;}public String getName() {return name;}@Overridepublic Prototype clone() {try {return (Prototype) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}
}

在上述示例中,Prototype 是原型接口,定义了 clone() 方法。ConcretePrototype 是具体原型类,实现了 Prototype 接口,并重写了 clone() 方法。在 clone() 方法中,通过调用 super.clone() 来创建一个新的对象,并返回该对象的引用。

使用原型模式的客户端代码示例如下:

public class Client {public static void main(String[] args) {ConcretePrototype prototype = new ConcretePrototype("Prototype 1");ConcretePrototype clone = (ConcretePrototype) prototype.clone();System.out.println("Original: " + prototype.getName());System.out.println("Clone: " + clone.getName());clone.setName("Prototype 2");System.out.println("Original: " + prototype.getName());System.out.println("Clone: " + clone.getName());}
}

在上述示例中,客户端创建了一个具体原型对象 prototype,然后通过调用 clone() 方法创建了一个克隆对象 clone。通过输出可以看到,原型对象和克隆对象具有相同的属性值。

原型模式的优点包括:

  • 减少对象的创建开销:通过克隆现有对象来创建新对象,避免了显式的实例化过程,提高了对象创建的效率。

  • 简化对象的创建过程:通过复制现有对象的属性,可以快速创建新对象,而无需关注对象创建的细节。

  • 支持动态配置对象:可以通过修改原型对象的属性,然后克隆该对象来创建新对象,实现了对象的动态配置。

  • 可以用于保护对象的状态:克隆对象是原型对象的一个副本,对克隆对象的修改不会影响原型对象。

需要注意的是,在使用原型模式时,要注意克隆对象的深拷贝和浅拷贝问题。如果对象的属性包含其他可变对象的引用,那么进行浅拷贝可能导致克隆对象和原型对象之间共享引用,从而影响对象的状态。在这种情况下,需要进行深拷贝来创建对象的完全独立副本。

6. 适配器模式(Adapter Pattern)

适配器模式(Adapter Pattern)是一种结构型设计模式,用于将一个类的接口转换成客户端所期望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的类可以协同工作。

在Java中,适配器模式主要包括以下几个角色:

  1. 目标接口(Target):定义了客户端所期望的接口,适配器类将会实现该接口。

  2. 适配器类(Adapter):实现了目标接口,并持有一个被适配的对象的引用。适配器类将客户端的请求转发给被适配对象。

  3. 被适配的类(Adaptee):需要被适配的类,它定义了不兼容目标接口的方法。

下面是一个简单的示例,展示了如何在Java中实现适配器模式:

// 目标接口
public interface Target {void request();
}// 适配器类
public class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void request() {// 转发请求给被适配对象adaptee.specificRequest();}
}// 被适配的类
public class Adaptee {public void specificRequest() {System.out.println("Adaptee's specific request");}
}

在上述示例中,Target 是目标接口,定义了客户端所期望的接口方法 request()

Adapter 是适配器类,实现了目标接口 Target,并在其内部持有一个被适配的对象 Adaptee 的引用。在 request() 方法中,适配器类将客户端的请求转发给被适配对象的 specificRequest() 方法。

Adaptee 是被适配的类,它定义了不兼容目标接口的方法 specificRequest()

使用适配器模式的客户端代码示例如下:

public class Client {public static void main(String[] args) {Adaptee adaptee = new Adaptee();Target adapter = new Adapter(adaptee);adapter.request();}
}

在上述示例中,客户端创建了被适配对象 adaptee 和适配器对象 adapter,然后通过适配器对象调用目标接口的方法 request()。适配器类将客户端的请求转发给被适配对象,从而实现了适配器模式的功能。

适配器模式的优点包括:

  • 提供了类与类之间的透明转换:客户端通过适配器对象与目标接口进行交互,无需直接与被适配对象交互,从而实现了类与类之间的透明转换。

  • 复用了现有的类:适配器模式可以复用已有的类,通过适配器将其接口转换成客户端所期望的接口,避免了修改现有类的代码。

  • 解耦了客户端和被适配对象:适配器模式将客户端与被适配对象解耦,客户端只需要与适配器对象进行交互,无需了解被适配对象的具体实现。

需要注意的是,在使用适配器模式时,需要根据具体情况选择类适配器模式还是对象适配器模式。类适配器模式使用继承来实现适配器,而对象适配器模式使用组合来实现适配器。类适配器模式要求适配器类同时继承目标接口和被适配类,因此只能适配一个被适配类。而对象适配器模式通过持有被适配对象的引用来实现适配器,可以适配多个被适配类。另外,适配器模式也可以使用接口适配器模式来解决接口不兼容的问题,接口适配器模式通过提供默认实现来适配接口。

7. 装饰器模式(Decorator Pattern)

装饰器模式(Decorator Pattern)是一种结构型设计模式,用于动态地给一个对象添加额外的功能,同时又不改变其接口。装饰器模式通过将对象包装在一个装饰器类中,然后逐层地添加新的行为或功能,实现了对对象的透明包装。

在Java中,装饰器模式主要包括以下几个角色:

  1. 抽象组件(Component):定义了被装饰对象的接口,可以是一个抽象类或者接口。

  2. 具体组件(Concrete Component):实现了抽象组件的接口,是被装饰的原始对象。

  3. 抽象装饰器(Decorator):继承自抽象组件,持有一个抽象组件的引用,并定义了与抽象组件相同的接口。

  4. 具体装饰器(Concrete Decorator):继承自抽象装饰器,实现了具体的装饰逻辑,并在调用被装饰对象的方法之前或之后添加额外的功能。

下面是一个简单的示例,展示了如何在Java中实现装饰器模式:

// 抽象组件
public interface Component {void operation();
}// 具体组件
public class ConcreteComponent implements Component {@Overridepublic void operation() {System.out.println("ConcreteComponent operation");}
}// 抽象装饰器
public abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}@Overridepublic void operation() {component.operation();}
}// 具体装饰器
public class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}@Overridepublic void operation() {super.operation();additionalOperation();}private void additionalOperation() {System.out.println("ConcreteDecoratorA additional operation");}
}

在上述示例中,Component 是抽象组件,定义了被装饰对象的接口方法 operation()

ConcreteComponent 是具体组件,实现了抽象组件接口,并定义了原始对象的行为。

Decorator 是抽象装饰器,继承自抽象组件,并持有一个抽象组件的引用。在 operation() 方法中,抽象装饰器调用被装饰对象的方法。

ConcreteDecoratorA 是具体装饰器,继承自抽象装饰器,实现了具体的装饰逻辑。在 operation() 方法中,具体装饰器先调用父类的 operation() 方法,然后添加额外的功能。

使用装饰器模式的客户端代码示例如下:

public class Client {public static void main(String[] args) {Component component = new ConcreteComponent();Component decorator = new ConcreteDecoratorA(component);decorator.operation();}
}

在上述示例中,客户端创建了具体组件对象 component 和具体装饰器对象 decorator,然后通过装饰器对象调用接口方法 operation()。装饰器模式会透明地将调用转发给被装饰对象,并在调用前后添加了额外的功能。

装饰器模式的优点包括:

  • 动态地添加功能:可以在运行时动态地添加额外的功能,而无需修改原始对象的代码。

  • 可以透明地包装对象:装饰器模式通过透明地包装对象,使得客户端无需关心具体的装饰器和原始对象之间的差异。

  • 遵循开闭原则:可以通过添加新的装饰器来扩展功能,而无需修改已有的代码。

需要注意的是,在使用装饰器模式时,要注意装饰器的顺序。由于装饰器模式是逐层包装的,装饰器的顺序会影响最终的行为。另外,装饰器模式也可能导致类的数量增加,增加了代码的复杂性。因此,在使用装饰器模式时需要权衡好灵活性和复杂性之间的关系。

8. 观察者模式(Observer Pattern)

观察者模式(Observer Pattern)是一种行为型设计模式,用于定义对象之间的一对多依赖关系,使得当一个对象的状态发生变化时,其依赖的其他对象都能够自动收到通知并进行相应的更新。

在Java中,观察者模式主要包括以下几个角色:

  1. 主题(Subject):也称为被观察者或可观察对象,它维护了一组观察者对象,并提供了添加、删除和通知观察者的方法。

  2. 观察者(Observer):定义了一个更新接口,被主题调用以便在主题的状态发生变化时更新自身。

  3. 具体主题(Concrete Subject):实现了主题接口,维护了观察者对象的集合,并在状态发生变化时通知观察者。

  4. 具体观察者(Concrete Observer):实现了观察者接口,在接收到主题的通知时进行相应的更新操作。

下面是一个简单的示例,展示了如何在Java中实现观察者模式:

import java.util.ArrayList;
import java.util.List;// 主题接口
public interface Subject {void registerObserver(Observer observer);void removeObserver(Observer observer);void notifyObservers();
}// 观察者接口
public interface Observer {void update();
}// 具体主题
public class ConcreteSubject implements Subject {private List<Observer> observers = new ArrayList<>();@Overridepublic void registerObserver(Observer observer) {observers.add(observer);}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers() {for (Observer observer : observers) {observer.update();}}// 具体主题的业务逻辑public void doSomething() {// 状态发生变化// ...// 通知观察者notifyObservers();}
}// 具体观察者
public class ConcreteObserver implements Observer {@Overridepublic void update() {// 接收到通知后的更新操作// ...System.out.println("ConcreteObserver received the update.");}
}

在上述示例中,Subject 是主题接口,定义了注册观察者、移除观察者和通知观察者的方法。

Observer 是观察者接口,定义了更新接口 update(),在接收到主题的通知时进行相应的更新操作。

ConcreteSubject 是具体主题,实现了主题接口,并维护了观察者对象的集合。在状态发生变化时,具体主题会调用 notifyObservers() 方法通知观察者。

ConcreteObserver 是具体观察者,实现了观察者接口,在接收到主题的通知时进行相应的更新操作。

使用观察者模式的客户端代码示例如下:

public class Client {public static void main(String[] args) {ConcreteSubject subject = new ConcreteSubject();ConcreteObserver observer = new ConcreteObserver();subject.registerObserver(observer);subject.doSomething();}
}

在上述示例中,客户端创建了具体主题对象 subject 和具体观察者对象 observer,然后通过主题对象调用业务方法 doSomething()。在业务方法中,具体主题的状态发生变化,并调用 notifyObservers() 方法通知观察者。具体观察者接收到通知后进行相应的更新操作。

观察者模式的优点包括:

  • 松耦合:主题和观察者之间是松耦合的,它们之间通过抽象接口进行通信,使得主题和观察者可以独立地进行扩展和修改。

  • 支持广播通信:主题可以同时通知多个观察者,实现了一对多的依赖关系。

  • 符合开闭原则:可以在不修改主题和观察者的情况下,动态地添加新的观察者。

需要注意的是,在使用观察者模式时,要避免观察者之间的循环依赖,以及观察者的更新操作不应该过于复杂,以免影响主题的性能。此外,Java中也提供了内置的观察者模式实现,可以使用 java.util.Observerjava.util.Observable 类来实现观察者模式。

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

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

相关文章

【ICer的脚本练习】tcl语法熟悉和工具tcl的实例

系列的目录说明请见:ICer的脚本练习专栏介绍与全流程目录_尼德兰的喵的博客-CSDN博客 前言 TCL(Tool Command Language)是一种简单但功能强大的脚本语言,它经常用于自动化任务、测试和快速原型开发。你看这个名字就能知道,这个语言最主要的作用就是用来操作工具,尤其我们…

[软考中级]软件设计师-uml

事物 uml中有4中事物&#xff0c;结构事物&#xff0c;行为事物&#xff0c;分组事物和注释事物 结构事物是uml模型中的名词&#xff0c;通常是模型的静态部分&#xff0c;描述概念或物理元素 行为事物是uml的动态部分&#xff0c;是模型中的动词&#xff0c;描述了跨越时间…

appium---如何判断原生页面和H5页面

目前app中存在越来越多的H5页面了&#xff0c;对于一些做app自动化的测试来说&#xff0c;要求也越来越高&#xff0c;自动化不仅仅要支持原生页面&#xff0c;也要可以H5中进行操作自动化&#xff0c; webview是什么 webview是属于android中的一个控件&#xff0c;也相当于一…

Go语言变量学习

您可以阅读Golang 教程第 2 部分&#xff1a;如何运行Hello World以及IDE介绍 什么是变量&#xff1f; 变量是为存储特定类型值的内存位置指定的名称。Go 中有多种声明变量的语法。让我们一一看看。 声明单个变量 var name type是声明单个变量的语法。 package mainimport…

vue3模板-vscode设置(语法糖)

选择菜单里的 文件 > 首选项 > 用户代码片段 vscode模板 {"Print to conaole":{"prefix": "v-ts", //在新建立的页面中输入C就会有智能提示&#xff0c;Tab就自动生成好了"body": ["<template>"," <…

快手新版本sig3参数算法还原

Frida Native层主动调用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81…

C++之委托构造函数实例(二百四十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

【每日一句】只出现一次的数

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;位运算 其他语言Cpython3 写在最后 Tag 【位运算-异或和】【数组】【2023-10-14】 题目来源 136. 只出现一次的数字 题目解读 给你一个数组&#xff0c;找出数组中只出现一次的元素。题目保证仅有一个元素出现一次&a…

[华为杯研究生创新赛 2023] 初赛 REV WP

前言 一年没打比赛了, 差一题进决赛, REV当时lin的第三个challenge没看出来是凯撒, 想得复杂了, 结果错失一次线下机会 >_< T4ee 动态调试, nop掉反调试代码 发现处理过程为 置换sub_412F20处理(这里看其他师傅的wp知道应该是rc4, 我是直接en逆的buf字符串中每一位和…

竞赛 深度学习+opencv+python实现昆虫识别 -图像识别 昆虫识别

文章目录 0 前言1 课题背景2 具体实现3 数据收集和处理3 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数&#xff1a;2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 4 MobileNetV2网络5 损失函数softmax 交叉熵5.1 softmax函数5.2 交叉熵损失函数 6 优化器SGD7 学…

Qt通过正则表达式筛选出字符串中的手机号

需求 用户需要聊天记录中含有11位的手机号码进行提醒的功能&#xff0c;所以需要在收到聊天消息后匹配查看是否存在手机号。如果找到然后提醒。 分析 主要的需求可以拆分为两点&#xff1a; 筛选出字符串里面的数字字符。通过正则匹配数字字符是否是11位手机号码。 一开始没…

Java设计模式之享元模式

享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构型设计模式&#xff0c;它通过共享对象来减少内存使用和提高性能。在享元模式中&#xff0c;将对象分为可共享的内部状态和不可共享的外部状态。内部状态是对象共享的部分&#xff0c;而外部状态是对象的变化部分&…

【网安必读】CTF/AWD实战速胜指南《AWD特训营》

文章目录 前言&#x1f4ac;正文这本书好在哪❔这本书讲了什么❔文末送书 前言&#x1f4ac; 【文末送书】今天推荐一本网安领域优质书籍《AWD特训营》&#xff0c;本文将从其内容与优势出发&#xff0c;详细阐发其对于网安从业人员的重要性与益处。 正文 &#x1f52d;本书…

软考高级系统架构设计师系列之:深入理解设计模式

软考高级系统架构设计师系列之:深入理解设计模式 一、设计模式相关技术文章二、设计原则三、设计模式概念四、设计模式的分类五、创建性模式六、创建性模式-工厂方法模式七、创建性模式-抽象工厂模式八、创建性模式-构建器模式九、面向对象设计-结构性模式十、结构性模式-适配…

数据结构 | Huffman TreeCode

构造参考&#xff1a; 赫夫曼树_关于huffman树,权值相同-CSDN博客 编码参考&#xff1a; 【数据结构与算法】-哈夫曼树(Huffman Tree)与哈夫曼编码_数据结构哈夫曼树编码-CSDN博客

在springboot中如何开启Bean数据校验

①&#xff1a;添加JSR303规范坐标与Hibernate校验框架对应坐标 <dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId> </dependency><dependency><groupId>org.hibernate.validator<…

系统架构设计:20 论软件需求管理

目录 一 需求工程 1 需求开发 1.1 需求获取 1.1.1 软件需求的分类 1.1.2 需求获取方法

开启多线程渲染后出现大量的Crash信息

1&#xff09;开启多线程渲染后出现大量的Crash信息 2&#xff09;Unity是否有提供硬件接口将纹理从Gamma值转为Linear值 3&#xff09;屏幕特效如何适配不同分辨率 这是第356篇UWA技术知识分享的推送&#xff0c;精选了UWA社区的热门话题&#xff0c;涵盖了UWA问答、社区帖子等…

《论文阅读:Dataset Condensation with Distribution Matching》

点进去这篇文章的开源地址&#xff0c;才发现这篇文章和DC DSA居然是一个作者&#xff0c;数据浓缩写了三篇论文&#xff0c;第一篇梯度匹配&#xff0c;第二篇数据增强后梯度匹配&#xff0c;第三篇匹配数据分布。DC是匹配浓缩数据和原始数据训练一次后的梯度差&#xff0c;DS…

idea怎么设置作者信息(详细)

目录 一&#xff1a;在Java类的开头自动注释作者名字和日期等信息 二&#xff1a;给Java的方法注释作者名字和日期等信息 1. 不可修改的模板&#xff1a;Postfix Completion 2. 可修改的模板&#xff1a;Live Templates tips&#xff1a;首先给大家推荐两款好用的免费软件&…