Unity 设计模式 之 结构型模式 -【适配器模式】【桥接模式】 【组合模式】

news2024/9/20 17:11:59

Unity 设计模式 之 结构型模式 -【适配器模式】【桥接模式】 【组合模式】

目录

Unity 设计模式 之 结构型模式 -【适配器模式】【桥接模式】 【组合模式】

一、简单介绍

二、适配器模式 (Adapter Pattern)

1、什么时候使用适配器模式

2、使用适配器模式的好处

3、适配器模式的注意事项

三、在 Unity 中使用 适配器模式

1、定义目标接口 IModelLoader

2、模拟不同的 3D 模型加载器

2.1 OBJ 模型加载器

2.2 FBX 模型加载器

3、创建适配器

3.1 OBJ 模型适配器

3.2 FBX 模型适配器

4、在 Unity 场景中使用适配器模式

5、运行结果分析

四、桥接模式(Bridge Pattern)

1、什么时候使用桥接模式

2、使用桥接模式的好处

五、在 Unity 中使用 桥接模式

1、定义渲染接口 IRenderer

2、实现具体的渲染类

2.1 标准材质渲染器 StandardMaterialRenderer

2.2 自定义材质渲染器 CustomMaterialRenderer

3、定义抽象类 Shape

4、创建具体的形状类

4.1 立方体类 Cube

4.2 球体类 Sphere

5、在 Unity 场景中使用桥接模式

6、运行分析

六、组合模式(Composite Pattern)

1、什么时候使用组合模式

2、使用组合模式的好处

3、使用组合模式时的注意事项

七、在 Unity  中使用 组合模式

1、定义组件接口 IShape

2、实现叶子节点类

2.1 立方体 Cube

2.2 球体 Sphere

2.3 圆柱体 Cylinder

3、实现组合节点 ShapeGroup

4、在 Unity 中使用组合模式

5、运行分析


一、简单介绍

设计模式 是指在软件开发中为解决常见问题而总结出的一套 可复用的解决方案。这些模式是经过长期实践证明有效的 编程经验总结,并可以在不同的项目中复用。设计模式并不是代码片段,而是对常见问题的 抽象解决方案,它提供了代码结构和模块间交互的一种设计思路,帮助开发者解决特定的设计问题。

设计模式的特点:

  1. 通用性:设计模式针对的是软件开发中常见的设计问题,适用于各种软件工程项目。
  2. 可复用性:设计模式可以在不同项目和环境下被重复使用,提高代码的可维护性和扩展性。
  3. 可扩展性:设计模式有助于让代码结构更加灵活,易于扩展和修改。
  4. 模块化:通过设计模式,可以减少代码的耦合性,增强模块间的独立性。
  5. 提高沟通效率:设计模式为开发者提供了一种通用的设计语言,使得团队成员能够快速理解并讨论设计方案。

二、适配器模式 (Adapter Pattern)

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

在开发中,适配器模式通常用于解决现有类和新接口不兼容的问题,而无需修改现有代码。它的核心思想是创建一个适配器类,使得不同接口之间的转换变得透明。

适配器模式有两种主要实现方式:

  1. 对象适配器:通过组合的方式,适配器类持有一个被适配的对象,并将调用委托给该对象。
  2. 类适配器:通过继承的方式,适配器类继承自需要适配的类,同时实现目标接口。

1、什么时候使用适配器模式

  1. 系统需要使用现有的类,但这个类的接口与系统的接口不兼容时。适配器模式可以在不修改现有类的情况下,使其接口适应新的需求。

  2. 你想复用旧代码,并且不想修改旧代码或违反开闭原则时。适配器模式允许你使用旧代码,而不需要更改现有代码库。

  3. 需要将类整合到一个不兼容的框架中,而又不希望改动类的定义时。通过适配器模式,你可以创建一个中间层,让新框架能够使用旧类。

  4. 集成第三方库:当引入第三方库时,它们的接口可能与现有代码的需求不一致。通过适配器模式,可以实现接口之间的转换,顺利进行集成。

2、使用适配器模式的好处

  1. 提高代码的复用性:适配器模式允许复用现有的类和库,无需修改其源代码。通过适配器,你可以将现有类无缝集成到新的系统中,而无需重写它们。

  2. 解决接口不兼容问题:当你需要使用一个现有类,但它的接口不符合你当前项目的需求时,可以通过适配器模式解决这一问题。适配器可以“翻译”接口,使得不兼容的类能够在一起工作。

  3. 支持旧系统的集成:在软件开发中,项目经常需要集成遗留系统或者第三方库。适配器模式能够很好地帮助你将这些遗留系统整合到新的系统中,扩展其功能而不需要修改旧代码。

  4. 分离客户端代码与具体实现:适配器模式将客户端代码与实际实现分离,这使得客户端代码可以适应未来的变化,比如新的接口或实现方式的引入。

3、适配器模式的注意事项

  1. 适配器本身需要额外的代码:引入适配器可能会增加系统的复杂性,尤其是当涉及多个适配器时。要权衡适配器的引入是否真正有必要。

  2. 可能引入性能开销:适配器模式通过引入中间层来解决接口不兼容问题,这可能在某些场景下增加调用的性能开销,特别是在大量频繁的接口调用时。

  3. 适配的灵活性:适配器的实现应该尽可能保持灵活,避免过于依赖具体的实现类。确保适配器可以应对接口或实现方式的变化。

总之,适配器模式 用于解决不兼容接口之间的转换问题,提供了将现有类复用到新环境中的灵活机制。它的主要好处是提高代码的复用性和扩展性,尤其适合在需要集成旧代码或第三方库时使用。通过适配器模式,开发者可以在不修改原始类的情况下,兼容不同接口,使系统更加灵活和可扩展。

三、在 Unity 中使用 适配器模式

在 Unity 中,我们可以使用适配器模式来处理不同类型的 3D 对象渲染,例如不同的 3D 模型格式(比如 OBJFBXGLTF 等)或不同的材质处理方式。通过适配器模式,可以将这些不同的 3D 模型格式转换成统一的接口来使用。

我们将模拟一个场景,其中需要加载不同格式的 3D 模型。通过适配器模式,我们可以创建一个统一的接口,让系统无论加载哪种格式的模型,都会以相同的方式进行操作。

步骤概述:

  1. 定义一个目标接口 IModelLoader,它用于统一加载模型的接口。
  2. 实现不同的 3D 模型加载器,比如 ObjModelLoaderFbxModelLoader,它们各自处理不同格式的模型。
  3. 创建适配器,将这些不同的加载器适配到 IModelLoader 接口。
  4. 使用适配器,在场景中加载不同格式的模型。

参考类图如下:

1、定义目标接口 IModelLoader

该接口定义了一个加载模型的方法 LoadModel(),通过这个接口,我们可以统一管理不同格式的模型加载。

public interface IModelLoader
{
    void LoadModel();
}

2、模拟不同的 3D 模型加载器

在这个示例中,我们会模拟两个不同的 3D 模型加载器,一个用于加载 OBJ 模型,另一个用于加载 FBX 模型。

2.1 OBJ 模型加载器
using UnityEngine;

public class ObjModelLoader
{
    public void LoadObjModel()
    {
        Debug.Log("Loading OBJ model...");
        // 模拟加载 OBJ 模型
        GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
        cube.GetComponent<Renderer>().material.color = Color.blue;
    }
}
2.2 FBX 模型加载器
using UnityEngine;

public class FbxModelLoader
{
    public void LoadFbxModel()
    {
        Debug.Log("Loading FBX model...");
        // 模拟加载 FBX 模型
        GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        sphere.GetComponent<Renderer>().material.color = Color.red;
    }
}

3、创建适配器

我们将创建适配器类,将 ObjModelLoaderFbxModelLoader 适配为统一的 IModelLoader 接口。

3.1 OBJ 模型适配器
public class ObjModelAdapter : IModelLoader
{
    private ObjModelLoader objModelLoader;

    public ObjModelAdapter(ObjModelLoader loader)
    {
        objModelLoader = loader;
    }

    public void LoadModel()
    {
        objModelLoader.LoadObjModel();
    }
}
3.2 FBX 模型适配器
public class FbxModelAdapter : IModelLoader
{
    private FbxModelLoader fbxModelLoader;

    public FbxModelAdapter(FbxModelLoader loader)
    {
        fbxModelLoader = loader;
    }

    public void LoadModel()
    {
        fbxModelLoader.LoadFbxModel();
    }
}

4、在 Unity 场景中使用适配器模式

using UnityEngine;

public class ModelLoaderExample : MonoBehaviour
{
    void Start()
    {
        // 使用 OBJ 模型适配器加载 OBJ 模型
        ObjModelLoader objLoader = new ObjModelLoader();
        IModelLoader objModelAdapter = new ObjModelAdapter(objLoader);
        objModelAdapter.LoadModel(); // 加载并显示 OBJ 模型

        // 使用 FBX 模型适配器加载 FBX 模型
        FbxModelLoader fbxLoader = new FbxModelLoader();
        IModelLoader fbxModelAdapter = new FbxModelAdapter(fbxLoader);
        fbxModelAdapter.LoadModel(); // 加载并显示 FBX 模型
    }
}

5、运行结果分析

  1. OBJ 模型:当 ObjModelAdapter.LoadModel() 被调用时,适配器会使用 ObjModelLoader 来加载一个立方体(模拟的 OBJ 模型),并将其颜色设置为蓝色。

  2. FBX 模型:当 FbxModelAdapter.LoadModel() 被调用时,适配器会使用 FbxModelLoader 来加载一个球体(模拟的 FBX 模型),并将其颜色设置为红色。

通过适配器模式,我们将不同的 3D 模型加载逻辑统一到了 IModelLoader 接口,使得客户端可以以相同的方式处理不同格式的模型,而无需关心底层的具体实现。

通过适配器模式,我们能够将现有的类和接口兼容起来,简化系统中不同类之间的交互。在 Unity 中,适配器模式可以用于处理不同的资源格式(如模型、音频、材质等)的加载和使用。

它极大地提高了代码的复用性和可扩展性,特别是在处理与第三方库或遗留代码时。通过适配器,客户端代码可以以统一的方式使用不同实现,降低了代码的耦合度。

适配器模式特别适合在 Unity 中处理多种资源加载、外部库集成和扩展功能时使用。例如,将外部导入的模型格式或资产类型转换为系统能够理解和处理的标准格式。

四、桥接模式(Bridge Pattern)

桥接模式(Bridge Pattern) 是一种结构型设计模式,旨在将抽象部分与其实现部分分离,使它们可以独立变化。换句话说,桥接模式通过引入一个桥接接口,将类的抽象层次和实现层次分开,从而使得它们能够分别独立地扩展。

桥接模式通过组合(而不是继承)来实现这种分离,这样可以避免类爆炸式的增长(即由于多个抽象和实现的组合导致的大量子类)。

桥接模式的组成部分

  1. Abstraction(抽象类):定义了高层的抽象行为,并且包含对 Implementor(实现类接口)的引用。
  2. RefinedAbstraction(细化抽象类):扩展 Abstraction,通过组合方式调用 Implementor 的方法来实现具体行为。
  3. Implementor(实现类接口):定义实现类的接口,该接口并不与 Abstraction 相关联。
  4. ConcreteImplementor(具体实现类):具体实现 Implementor 接口中的方法。

1、什么时候使用桥接模式

  1. 类需要在多个维度上扩展,且这些维度之间是独立变化的。例如,系统需要支持不同的操作系统平台,同时还需要支持多种功能扩展,这时使用桥接模式可以避免多重继承带来的复杂性。

  2. 不希望使用继承或者继承层次过深:如果你使用继承,可能会产生很多子类,而桥接模式可以通过组合方式减少类的数量,并使代码更具弹性。

  3. 需要动态切换实现时:桥接模式允许你在运行时切换不同的实现类,而不需要修改抽象层次的代码,非常适合需要灵活切换实现的场景。

  4. 希望增强代码的可维护性和可测试性:桥接模式通过解耦抽象和实现,使得两者可以独立开发、测试和维护,从而提高代码的可维护性。

2、使用桥接模式的好处

  1. 分离抽象与实现:桥接模式允许你将抽象部分与具体实现部分分离开来,使得它们可以独立变化,降低了耦合度。抽象和实现可以分别扩展,互不影响。

  2. 扩展性强:由于抽象部分和实现部分可以独立地扩展,因此可以更容易地进行系统扩展,而不需要修改现有代码。比如,你可以为同一抽象引入不同的实现,而不需要修改抽象层次的代码。

  3. 减少类爆炸:通过组合代替继承,避免了因为多维度扩展(如平台、功能等)而导致的类爆炸问题。只需添加新的实现类或抽象类,就可以扩展系统。

  4. 动态切换实现:桥接模式允许你在运行时动态地切换实现,提供了极大的灵活性。例如,你可以根据不同的环境选择不同的实现类来完成任务。

五、在 Unity 中使用 桥接模式

在 Unity 中,桥接模式可以用于将 渲染方式 3D 对象的形状 分离,从而实现更灵活的渲染系统。例如,我们可以有不同的渲染器(比如使用 标准材质 自定义材质 进行渲染),同时也可以有不同的形状(如 立方体球体 等)。桥接模式允许我们将这些渲染器和形状解耦,使它们能够独立扩展。

使用桥接模式在 Unity 中渲染 3D 对象

我们将设计一个系统,能够以不同的方式渲染不同形状的 3D 对象。使用桥接模式,将渲染逻辑和形状解耦。渲染方式可以是使用标准材质渲染,也可以是自定义材质渲染。形状包括立方体和球体。

参考类图如下:

1、定义渲染接口 IRenderer

这个接口定义了一个 Render 方法,接受一个形状名称作为参数,用于渲染对应的形状。

public interface IRenderer
{
    void Render(string shape);
}

2、实现具体的渲染类

2.1 标准材质渲染器 StandardMaterialRenderer
using UnityEngine;

public class StandardMaterialRenderer : IRenderer
{
    public void Render(string shape)
    {
        Debug.Log($"Rendering {shape} with Standard Material");
        // 创建 Unity 原生物体并应用标准材质
        GameObject obj = shape == "Cube" ? GameObject.CreatePrimitive(PrimitiveType.Cube) : GameObject.CreatePrimitive(PrimitiveType.Sphere);
        obj.GetComponent<Renderer>().material = new Material(Shader.Find("Standard"));
    }
}
2.2 自定义材质渲染器 CustomMaterialRenderer
using UnityEngine;

public class CustomMaterialRenderer : IRenderer
{
    public void Render(string shape)
    {
        Debug.Log($"Rendering {shape} with Custom Material");
        // 创建 Unity 原生物体并应用自定义材质(如带颜色的材质)
        GameObject obj = shape == "Cube" ? GameObject.CreatePrimitive(PrimitiveType.Cube) : GameObject.CreatePrimitive(PrimitiveType.Sphere);
        Material customMaterial = new Material(Shader.Find("Standard"));
        customMaterial.color = Color.green; // 自定义颜色
        obj.GetComponent<Renderer>().material = customMaterial;
    }
}

3、定义抽象类 Shape

Shape 类是抽象类,持有一个 IRenderer 的引用,并定义了 Draw 方法,用于渲染形状。

public abstract class Shape
{
    protected IRenderer renderer;

    public Shape(IRenderer renderer)
    {
        this.renderer = renderer;
    }

    public abstract void Draw();
}

4、创建具体的形状类

4.1 立方体类 Cube
public class Cube : Shape
{
    public Cube(IRenderer renderer) : base(renderer) {}

    public override void Draw()
    {
        renderer.Render("Cube");
    }
}
4.2 球体类 Sphere
public class Sphere : Shape
{
    public Sphere(IRenderer renderer) : base(renderer) {}

    public override void Draw()
    {
        renderer.Render("Sphere");
    }
}

5、在 Unity 场景中使用桥接模式

using UnityEngine;

public class BridgePatternExample : MonoBehaviour
{
    void Start()
    {
        // 使用标准材质渲染器渲染立方体
        IRenderer standardRenderer = new StandardMaterialRenderer();
        Shape cube = new Cube(standardRenderer);
        cube.Draw();  // 输出:Rendering Cube with Standard Material

        // 使用自定义材质渲染器渲染球体
        IRenderer customRenderer = new CustomMaterialRenderer();
        Shape sphere = new Sphere(customRenderer);
        sphere.Draw();  // 输出:Rendering Sphere with Custom Material
    }
}

6、运行分析

  • cube.Draw() 被调用时,立方体将使用标准材质渲染。
  • sphere.Draw() 被调用时,球体将使用自定义材质(绿色)渲染。

在这个示例中,桥接模式将渲染方式(IRenderer)和形状(Shape)进行了分离。通过这种方式,我们可以独立扩展渲染方式和形状。比如你可以为不同的形状添加更多渲染方式(如自发光材质渲染器等),也可以扩展更多的形状,而不需要修改现有代码。

渲染逻辑和形状实现独立变化,增强了系统的扩展性和灵活性。

不同渲染逻辑可以复用,适应不同的形状,而不同形状也可以复用相同的渲染器。

桥接模式适合应用在需要多个维度变化的场景中,例如 Unity 中的渲染系统、音效处理系统、或者动画控制系统。在这些系统中,不同的维度可以独立扩展,而不影响彼此。

六、组合模式(Composite Pattern)

组合模式(Composite Pattern) 是一种结构型设计模式,它将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得客户端对单个对象和组合对象的使用具有一致性。

在组合模式中,叶子对象和容器对象被统一为一个对象接口,客户端可以同样地对待它们。这种模式常用于表示具有层次结构的数据结构,例如文件系统、公司组织结构、GUI 树等。

组合模式的组成部分

  1. Component(抽象组件):定义了叶子和容器的共同接口,通常包括对子组件的管理方法(如添加、删除子组件)。
  2. Leaf(叶子节点):表示没有子节点的基本组件,实现 Component 接口。
  3. Composite(组合节点):包含子组件,负责对子组件的管理,实现 Component 接口。

1、什么时候使用组合模式

  1. 需要表示对象的部分-整体层次结构时,例如文件系统、图形界面控件树、组织架构等。组合模式适合用于管理树形结构,使得各个节点具有一致的操作接口。

  2. 客户端希望一致地对待组合对象和单个对象时。组合模式可以让客户端无需关心处理的是单个对象还是一组对象,极大简化了客户端的代码。

  3. 需要动态地管理对象结构时,使用组合模式可以轻松地添加、删除和遍历组合对象及其子对象,而不需要复杂的操作。

2、使用组合模式的好处

  1. 一致性:客户端可以一致地处理单个对象和组合对象。组合模式将复杂对象和简单对象的处理方式统一起来,使代码更简洁,不需要分别处理叶子对象和组合对象。

  2. 层次结构清晰:组合模式能够清晰地表示对象的层次结构,例如文件系统中的文件和文件夹、公司中的员工和部门等。组合对象可以包含其他组合对象或叶子对象,轻松构建复杂的树形结构。

  3. 灵活的对象管理:通过组合模式,可以轻松地向组合对象中添加或移除子组件,动态地管理对象的结构。对于多层次的结构,修改只需要在局部进行,避免全局修改。

  4. 更好地扩展性:组合模式允许新增叶子节点或组合节点,不会影响现有的类结构。只需要遵循相同的接口即可轻松扩展对象的种类。

3、使用组合模式时的注意事项

  1. 平衡组合对象的复杂度:组合模式虽然简化了客户端代码,但如果对象树过于复杂,会导致系统中的对象关系难以维护。因此在设计时要考虑对象结构的复杂性,避免过度嵌套。

  2. 避免滥用组合模式:组合模式适用于具有层次结构的对象,如果应用到不合适的场景,可能会导致设计复杂化。例如在处理单一对象时,使用组合模式可能会显得多余。

  3. 叶子节点和组合节点的区别:在实现组合模式时,叶子节点和组合节点的行为应该区分开。叶子节点通常不包含子节点,而组合节点可以包含多个子节点。在设计过程中,要清楚地定义两者的功能和用途。

  4. 性能问题:由于组合模式涉及树形结构的递归遍历,因此在处理大量子节点或深层次树形结构时,可能会产生性能问题。特别是在对整个树进行操作时,要注意递归调用的深度和频率。

七、在 Unity  中使用 组合模式

在 Unity 中,组合模式可以应用于管理 3D 对象的层次结构,例如组合复杂的游戏对象,如一个包含多个部分的机器人或车辆。这些对象的每个部分(如身体、轮子、头部等)可以作为叶子节点,而整个对象则作为组合节点。

在这个示例中,我们将使用组合模式实现一个场景,其中包含不同的 3D 形状(立方体、球体、圆柱体等),并将它们组合成一个更复杂的对象。我们可以一致地操作单个形状和组合对象。

参考类图如下:

1、定义组件接口 IShape

这个接口定义了一个 Render 方法,用于渲染 3D 对象。

public interface IShape
{
    void Render();
}

2、实现叶子节点类

这些类实现了 IShape 接口,用于渲染具体的 3D 形状。

2.1 立方体 Cube
using UnityEngine;

public class Cube : IShape
{
    public void Render()
    {
        Debug.Log("Rendering Cube");
        GameObject.CreatePrimitive(PrimitiveType.Cube);
    }
}
2.2 球体 Sphere
using UnityEngine;

public class Sphere : IShape
{
    public void Render()
    {
        Debug.Log("Rendering Sphere");
        GameObject.CreatePrimitive(PrimitiveType.Sphere);
    }
}
2.3 圆柱体 Cylinder
using UnityEngine;

public class Cylinder : IShape
{
    public void Render()
    {
        Debug.Log("Rendering Cylinder");
        GameObject.CreatePrimitive(PrimitiveType.Cylinder);
    }
}

3、实现组合节点 ShapeGroup

ShapeGroup 是组合节点,它可以包含多个 IShape 对象,并对它们进行统一的渲染。

using System.Collections.Generic;
using UnityEngine;

public class ShapeGroup : IShape
{
    private List<IShape> shapes = new List<IShape>();

    public void AddShape(IShape shape)
    {
        shapes.Add(shape);
    }

    public void RemoveShape(IShape shape)
    {
        shapes.Remove(shape);
    }

    public void Render()
    {
        Debug.Log("Rendering Shape Group");
        foreach (var shape in shapes)
        {
            shape.Render();
        }
    }
}

4、在 Unity 中使用组合模式

using UnityEngine;

public class CompositePattern3DExample : MonoBehaviour
{
    void Start()
    {
        // 创建单个形状
        IShape cube = new Cube();
        IShape sphere = new Sphere();
        IShape cylinder = new Cylinder();

        // 创建组合对象
        ShapeGroup complexObject = new ShapeGroup();
        complexObject.AddShape(cube);
        complexObject.AddShape(sphere);

        // 创建更复杂的组合对象
        ShapeGroup complexGroup = new ShapeGroup();
        complexGroup.AddShape(complexObject);
        complexGroup.AddShape(cylinder);

        // 渲染所有对象
        Debug.Log("Rendering all shapes:");
        complexGroup.Render();
    }
}

5、运行分析

当运行代码时,Unity 会在控制台输出如下信息,并且在场景中创建相应的 3D 对象:

Rendering all shapes:
Rendering Shape Group
Rendering Cube
Rendering Sphere
Rendering Cylinder

在场景中,你会看到一个立方体、球体和圆柱体被渲染出来。通过组合模式,我们可以轻松地将单个对象和组合对象进行统一处理,无需为每个对象写单独的渲染代码。

在这个示例中,组合模式允许我们将多个 3D 形状组合在一起,构建一个更复杂的 3D 对象层次结构,并能够一致地操作它们;客户端可以一致地处理单个对象和组合对象,无需关心它们是单一形状还是组合体;可以很方便地向组合对象中添加更多的形状,扩展性非常好。

组合模式适合用在需要表示层次结构的场景中,例如场景中的 3D 物体组合、游戏中的层次化对象管理等;要注意避免过度嵌套结构,尤其是在处理非常复杂的 3D 对象时,树形结构的深度可能会影响性能。

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

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

相关文章

Active Directory 实验室设置第一部分- AD林安装

在之前的文章中&#xff0c;已经讨论了活动目录的基本知识。在这篇文章中&#xff0c;我们将讨论如何设置和配置环境&#xff0c;以便我们可以使用它来执行各种攻击方案和检测。我们将讨论如何通过GUI和CLI方式完成。 # 1、Active Directory 设置 让我们从活动目录实验室设置…

【JAVA开源】基于Vue和SpringBoot的校园美食分享平台

本文项目编号 T 033 &#xff0c;文末自助获取源码 \color{red}{T033&#xff0c;文末自助获取源码} T033&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

docker-compose 部署 flink [支持pyflink]

下载 flink 镜像 [rootlocalhost ~]# docker pull flink Using default tag: latest latest: Pulling from library/flink 762bedf4b1b7: Pull complete 95f9bd9906fa: Pull complete a880dee0d8e9: Pull complete 8c5deab9cbd6: Pull complete 56c142282fae: Pull comple…

python安装-升级

这里写自定义目录标题 欢迎使用Markdown编辑器 欢迎使用Markdown编辑器 运行python 或pycharm时报错 [notice] A new release of pip is available: 23.1.2 -> 24.2 [notice] To update, run: python.exe -m pip install --upgrade pipCMD 进入 DOS C:\Users\wang>pyt…

深度学习:(五)初识神经网络

&#xff08;一&#xff09;神经网络的层数 除去输入层&#xff0c;但包括输出层&#xff0c;每一层都有自己的参数。 输入层称为第零层。 &#xff08;二&#xff09;最简单的神经网络&#xff08;逻辑回归&#xff09; 下图中的小圆圈&#xff0c;代表了一种运算。且一个小…

手撕小顶堆

1. 抛砖引玉 给定两个以升序排列的整数数组 nums1 和 nums2 , 以及一个整数 k 。 定义一对值 (u,v)&#xff0c;其中第一个元素来自 nums1&#xff0c;第二个元素来自 nums2 。 请找到和最小的 k 个数对 (u1,v1), (u2,v2) … (uk,vk) 。 分析 大根堆&#xff08;大顶堆&#x…

vue无法通过页面路径访问提示404,通过nginx配置处理

部署vue项目时&#xff0c;可以通过IP的方式访问主页&#xff0c;当进入特定页面在刷新时&#xff0c;因为浏览器通过URL地址进行请求&#xff0c;就提示404错误。 每次都需要重新从主页进入&#xff0c;这里是因为nginx配置的问题&#xff0c;在nginx里增加一行重定向的设置 …

如何使用淘宝API获取买家秀数据?一份详细指南

什么是淘宝买家秀API&#xff1f; 淘宝买家秀API是淘宝开放平台提供的一种接口&#xff0c;它允许开发者通过编程方式获取淘宝商品的买家秀信息&#xff0c;包括买家上传的图片、视频、评论等内容。 为什么需要使用淘宝买家秀API&#xff1f; 提升商品质量&#xff1a;通过分…

什么是CSRF攻击,该如何防护CSRF攻击

CSRF攻击&#xff08;跨站请求伪造&#xff0c;Cross-Site Request Forgery&#xff09;是一种网络攻击手段&#xff0c;攻击者利用已通过身份验证的用户&#xff0c;诱导他们在不知情的情况下执行未授权操作。这种攻击通常发生在用户登录到可信网站并且有活动的会话时&#xf…

【Elasticsearch】-spring boot 依赖包冲突问题

<dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.17.24</version></dependency> 在pom的配置中&#xff0c;只引入了elasticsearch-7.17.24 &#xff0c;但实际上会同时…

vue2中字符串动态拼接字段给到接口

【设计初衷是用户可根据给定的字段进行准确描述】 实现功能&#xff1a; 1. 文本域内容串动态配置字段&#xff0c;以$ {英文}拼接格式给到接口。 &#xff08;传参如&#xff1a;$ {heat_status_code}正常&#xff0c;$ {wdy_temp}也正常&#xff01;&#xff09; 2. 编辑时根…

Nginx从入门到入土(四):基于Nginx负载均衡策略

软负载和硬负载的概念前文提起过&#xff0c;那接下来我们便讲讲什么是负载均衡。 前言 Nginx负载均衡解决的是高并发的问题。 定义&#xff1a; 负载均衡&#xff08;Load Balancing&#xff09;是一种技术策略&#xff0c;它旨在将工作负载&#xff08;如网络流量、计算任…

react之jsx基础(2)高频使用场景

文章目录 1. **组件定义**2. **条件渲染**3. **列表渲染**4. **事件处理**5. **嵌套组件**6. **表单处理**7. **样式应用**8. **处理子组件** 在 React 中&#xff0c;JSX 的使用是非常广泛和高频的。以下是一些常见的高频使用场景及其示例&#xff0c;帮助你更好地理解 JSX 的…

Python基于flask框架的智能停车场车位系统 数据可视化分析系统fyfc81

目录 技术栈和环境说明解决的思路具体实现截图系统设计python语言django框架介绍flask框架介绍性能/安全/负载方面可行性分析论证python-flask核心代码部分展示python-django核心代码部分展示技术路线操作可行性详细视频演示源码获取 技术栈和环境说明 结合用户的使用需求&…

我在高职教STM32——准备HAL库工程模板(2)

新学期已开始,又要给学生上 STM32 嵌入式课程了。这课上了多年了,一直用的都是标准库来开发,已经驾轻就熟了。人就是这样,有了自己熟悉的舒适圈,就很难做出改变,老师上课也是如此,排斥新课和不熟悉的内容。显然,STM32 的开发,HAL 库已是主流,自己其实也在使用,只不过…

基于SpringBoot+Vue的商场停车场管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…

MeterSphere技术分享:UI自动化测试的必要性与解决方案

UI自动化测试体系的建设价值遵循测试金字塔模型&#xff0c;该模型建议测试人员在不同层次上编写和执行测试。UI测试需要编写和设计测试脚本、执行完整的应用程序&#xff0c;并模拟用户与应用程序交互&#xff0c;因此UI测试的测试速度相对较慢。但是UI测试的业务覆盖很高&…

【STL】stack,deque,queue 基础,应用与操作

stack 1.stack相关介绍 stack&#xff08;栈&#xff09; 栈是一种后进先出&#xff08;LIFO, Last In First Out&#xff09;的数据结构&#xff0c;意味着最后插入的数据最先被移除。C 中的栈是通过容器适配器实现的&#xff0c;底层默认使用 deque&#xff08;双端队列&am…

数字电子技术-数值比较器

目录 数值比较器 1、1位二进制数值比较器 多位数值比较器 4位数值比较器74LS85(TTL型) 74LS85数值比较器的使用说明 数值比较器 Digital Comparator,又称数字比较器&#xff0c;用以对两个数字的大小或是否相等进行比较的逻辑电路。 1、1位二进制数值比较器 A和B只能取值…