【十四】设计模式~~~行为型模式~~~中介者模式(Java)

news2025/1/22 16:44:59

【学习难度:★★★☆☆,使用频率:★★★★★】

3.1. 模式动机

       建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展,这就是观察者模式的模式动机。

案例1

       “红灯停,绿灯行”,在日常生活中,交通信号灯装点着我们的城市,指挥着日益拥挤的城市交通。当红灯亮起,来往的汽车将停止;而绿灯亮起,汽车可以继续前行。在这个过程中,交通信号灯是汽车(更准确地说应该是汽车驾驶员)的观察目标,而汽车是观察者。随着交通信号灯的变化,汽车的行为也将随之而变化,一盏交通信号灯可以指挥多辆汽车。如图22-1所示:
在这里插入图片描述

       在软件系统中,有些对象之间也存在类似交通信号灯和汽车之间的关系,一个对象的状态或行为的变化将导致其他对象的状态或行为也发生改变,它们之间将产生联动,正所谓“触一而牵百发”。为了更好地描述对象之间存在的这种一对多(包括一对一)的联动,观察者模式应运而生,它定义了对象之间一种一对多的依赖关系,让一个对象的改变能够影响其他对象。本章我们将学习用于实现对象间联动的观察者模式。

案例2

       Sunny软件公司欲开发一款多人联机对战游戏(类似魔兽世界、星际争霸等游戏),在该游戏中,多个玩家可以加入同一战队组成联盟,当战队中某一成员受到敌人攻击时将给所有其他盟友发送通知,盟友收到通知后将作出响应。
       Sunny软件公司开发人员需要提供一个设计方案来实现战队成员之间的联动。

       Sunny软件公司开发人员通过对系统功能需求进行分析,发现在该系统中战队成员之间的联动过程可以简单描述如下:
联盟成员受到攻击–>发送通知给盟友–>盟友作出响应。

       如果按照上述思路来设计系统,由于联盟成员在受到攻击时需要通知他的每一个盟友,因此每个联盟成员都需要持有其他所有盟友的信息,这将导致系统开销较大,因此Sunny公司开发人员决定引入一个新的角色——“战队控制中心”——来负责维护和管理每个战队所有成员的信息。当一个联盟成员受到攻击时,将向相应的战队控制中心发送求助信息,战队控制中心再逐一通知每个盟友,盟友再作出响应,如图22-2所示:
在这里插入图片描述

       在图22-2中,受攻击的联盟成员将与战队控制中心产生联动,战队控制中心还将与其他盟友产生联动。
       如何实现对象之间的联动?如何让一个对象的状态或行为改变时,依赖于它的对象能够得到通知并进行相应的处理?

3.2. 模式定义

       观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

观察者模式是一种对象行为型模式。

       观察者模式是使用频率最高的设计模式之一,它用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应。在观察者模式中,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间可以没有任何相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展。

3.3. 模式结构

观察者模式包含如下角色:

  • Subject: 目标,目标又称为主题,它是指被观察的对象。在目标中定义了一个观察者集合,一个观察目标可以接受任意数量的观察者来观察,它提供一系列方法来增加和删除观察者对象,同时它定义了通知方法notify()。目标类可以是接口,也可以是抽象类或具体类。
  • ConcreteSubject: 具体目标,具体目标是目标类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知;同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有的话)。如果无须扩展目标类,则具体目标类可以省略。
  • Observer: 观察者,观察者将对观察目标的改变做出反应,观察者一般定义为接口,该接口声明了更新数据的方法update(),因此又称为抽象观察者
  • ConcreteObserver: 具体观察者,在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致;它实现了在抽象观察者Observer中定义的update()方法。通常在实现时,可以调用具体目标类的attach()方法将自己添加到目标类的集合中或通过detach()方法将自己从目标类的集合中删除。

       观察者模式结构中通常包括观察目标和观察者两个继承层次结构,其结构如图22-3所示:

在这里插入图片描述

       观察者模式描述了如何建立对象与对象之间的依赖关系,以及如何构造满足这种需求的系统。观察者模式包含观察目标和观察者两类对象,一个目标可以有任意数目的与之相依赖的观察者,一旦观察目标的状态发生改变,所有的观察者都将得到通知。作为对这个通知的响应,每个观察者都将监视观察目标的状态以使其状态与目标状态同步,这种交互也称为发布-订阅(Publish-Subscribe)。观察目标是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅它并接收通知。

       下面通过示意代码来对该模式进行进一步分析。首先我们定义一个抽象目标Subject,典型代码如下所示:

import java.util.*;
abstract class Subject {
    //定义一个观察者集合用于存储所有观察者对象
protected ArrayList observers<Observer> = new ArrayList();
 
//注册方法,用于向观察者集合中增加一个观察者
	public void attach(Observer observer) {
    observers.add(observer);
}
 
    //注销方法,用于在观察者集合中删除一个观察者
	public void detach(Observer observer) {
    observers.remove(observer);
}
 
    //声明抽象通知方法
	public abstract void notify();
}

       具体目标类ConcreteSubject是实现了抽象目标类Subject的一个具体子类,其典型代码如下所示:

class ConcreteSubject extends Subject {
    //实现通知方法
	public void notify() {
        //遍历观察者集合,调用每一个观察者的响应方法
		for(Object obs:observers) {
			((Observer)obs).update();
		}
	}	
}

       抽象观察者角色一般定义为一个接口,通常只声明一个update()方法,为不同观察者的更新(响应)行为定义相同的接口,这个方法在其子类中实现,不同的观察者具有不同的响应方法。抽象观察者Observer典型代码如下所示:

interface Observer {
    //声明响应方法
	public void update();
}

       在具体观察者ConcreteObserver中实现了update()方法,其典型代码如下所示:

class ConcreteObserver implements Observer {
    //实现响应方法
	public void update() {
		//具体响应代码
	}
}

       在有些更加复杂的情况下,具体观察者类ConcreteObserver的update()方法在执行时需要使用到具体目标类ConcreteSubject中的状态(属性),因此在ConcreteObserver与ConcreteSubject之间有时候还存在关联或依赖关系,在ConcreteObserver中定义一个ConcreteSubject实例,通过该实例获取存储在ConcreteSubject中的状态。如果ConcreteObserver的update()方法不需要使用到ConcreteSubject中的状态属性,则可以对观察者模式的标准结构进行简化,在具体观察者ConcreteObserver和具体目标ConcreteSubject之间无须维持对象引用。如果在具体层具有关联关系,系统的扩展性将受到一定的影响,增加新的具体目标类有时候需要修改原有观察者的代码,在一定程度上违反了“开闭原则”,但是如果原有观察者类无须关联新增的具体目标,则系统扩展性不受影响。

3.4. 时序图

在这里插入图片描述

3.5. 代码分析

       为了实现对象之间的联动,Sunny软件公司开发人员决定使用观察者模式来进行多人联机对战游戏的设计,其基本结构如图22-4所示:
在这里插入图片描述

3.5.1 生产

       在图22-4中,AllyControlCenter充当目标类,ConcreteAllyControlCenter充当具体目标类,Observer充当抽象观察者,Player充当具体观察者。完整代码如下所示:

package com.zyz.demo;

import java.util.ArrayList;

/**
 * @author zyz
 * @version 1.0
 * @data 2023/5/26 18:43
 * @Description:
 */
interface Observer {
    public String getName();

    public void setName(String name);

    public void help(); //声明支援盟友方法

    public void beAttacked(AllyControlCenter acc); //声明遭受攻击方法
}


//战队成员类:具体观察者类

class Player implements Observer {
    private String name;

    public Player(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 支援盟友方法的实现
     */

    @Override
    public void help() {
        System.out.println("坚持住," + this.name + "来救你!");
    }

    /**
     * 遭受攻击方法的实现,当遭受攻击时将调用战队控制中心类的通知方法notifyObserver()来通知盟友
     *
     * @param acc
     */

    @Override
    public void beAttacked(AllyControlCenter acc) {
        System.out.println(this.name + "被攻击!");
        acc.notifyObserver(name);
    }

}


//战队控制中心类:目标类

abstract class AllyControlCenter {
    protected String allyName; //战队名称
    protected ArrayList<Observer> players = new ArrayList<Observer>(); //定义一个集合用于存储战队成员

    public void setAllyName(String allyName) {
        this.allyName = allyName;
    }

    public String getAllyName() {
        return this.allyName;
    }

    /**
     * 注册方法
     *
     * @param obs
     */
    public void join(Observer obs) {
        System.out.println(obs.getName() + "加入" + this.allyName + "战队!");
        players.add(obs);
    }

    /**
     * 注销方法
     *
     * @param obs
     */
    public void quit(Observer obs) {
        System.out.println(obs.getName() + "退出" + this.allyName + "战队!");
        players.remove(obs);
    }

    /**
     * 声明抽象通知方法
     *
     * @param name
     */
    public abstract void notifyObserver(String name);
}

class ConcreteAllyControlCenter extends AllyControlCenter {

    public ConcreteAllyControlCenter(String allyName) {
        System.out.println(allyName + "战队组建成功!");
        System.out.println("----------------------------");
        this.allyName = allyName;
    }

    /**
     * //实现通知方法
     *
     * @param name
     */
    @Override
    public void notifyObserver(String name) {
        System.out.println(this.allyName + "战队紧急通知,盟友" + name + "遭受敌人攻击!");
        //遍历观察者集合,调用每一个盟友(自己除外)的支援方法
        for (Object obs : players) {
            if (!((Observer) obs).getName().equalsIgnoreCase(name)) {
                ((Observer) obs).help();
            }
        }


    }
}

3.5.2 客户端

package com.zyz.demo;

/**
 * @author zyz
 * @version 1.0
 * @data 2023/5/26 18:52
 * @Description: 客户端
 */
class Client {
    public static void main(String args[]) {
        //定义观察目标对象
        AllyControlCenter acc;
        acc = new ConcreteAllyControlCenter("金庸群侠");

        //定义四个观察者对象
        Observer player1,player2,player3,player4;

        player1 = new Player("杨过");
        acc.join(player1);

        player2 = new Player("令狐冲");
        acc.join(player2);

        player3 = new Player("张无忌");
        acc.join(player3);

        player4 = new Player("段誉");
        acc.join(player4);

        //某成员遭受攻击
        player1.beAttacked(acc);
    }
}

3.5.3 测试结果

在这里插入图片描述

       在本实例中,实现了两次对象之间的联动,当一个游戏玩家Player对象的beAttacked()方法被调用时,将调用AllyControlCenter的notifyObserver()方法来进行处理,而在notifyObserver()方法中又将调用其他Player对象的help()方法。Player的beAttacked()方法、AllyControlCenter的notifyObserver()方法以及Player的help()方法构成了一个联动触发链,执行顺序如下所示:

Player.beAttacked() --> AllyControlCenter.notifyObserver() -->Player.help()。

3.6. 模式分析

  • 观察者模式描述了如何建立对象与对象之间的依赖关系,如何构造满足这种需求的系统。
  • 这一模式中的关键对象是观察目标和观察者,一个目标可以有任意数目的与之相依赖的观察者,一旦目标的状态发生改变,所有的观察者都将得到通知。
  • 作为对这个通知的响应,每个观察者都将即时更新自己的状态,以与目标状态同步,这种交互也称为发布-订阅(publishsubscribe)。目标是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅它并接收通知。

3.7. 实例

3.8. 优点

观察者模式的优点

  • 观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。
  • 观察者模式在观察目标和观察者之间建立一个抽象的耦合。
  • 观察者模式支持广播通信。
  • 观察者模式符合“开闭原则”的要求。

3.9. 缺点

观察者模式的缺点

  • 如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
  • 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
  • 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

3.10. 适用环境

在以下情况下可以使用观察者模式:

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

3.11. 模式应用

       观察者模式在软件开发中应用非常广泛,如某电子商务网站可以在执行发送操作后给用户多个发送商品打折信息,某团队战斗游戏中某队友牺牲将给所有成员提示等等,凡是涉及到一对一或者一对多的对象交互场景都可以使用观察者模式。

3.12. 模式扩展

MVC模式

  • MVC模式是一种架构模式,它包含三个角色:模型(Model),视图(View)和控制器(Controller)。观察者模式可以用来实现MVC模式,观察者模式中的观察目标就是MVC模式中的模型(Model),而观察者就是MVC中的视图(View),控制器(Controller)充当两者之间的中介者(Mediator)。当模型层的数据发生改变时,视图层将自动改变其显示内容。

3.13. 总结

       观察者模式定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅模式、模型-视图模式、源-监听器模式或从属者模式。观察者模式是一种对象行为型模式。

  • 观察者模式包含四个角色:目标又称为主题,它是指被观察的对象;具体目标是目标类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知;观察者将对观察目标的改变做出反应;在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致。
  • 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个目标对象,当这个目标对象的状态发生变化时,会通知所有观察者对象,使它们能够自动更新。
  • 观察者模式的主要优点在于可以实现表示层和数据逻辑层的分离,并在观察目标和观察者之间建立一个抽象的耦合,支持广播通信;其主要缺点在于如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间,而且如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
  • 观察者模式适用情况包括:一个抽象模型有两个方面,其中一个方面依赖于另一个方面;一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变;一个对象必须通知其他对象,而并不知道这些对象是谁;需要在系统中创建一个触发链。
  • 在JDK的java.util包中,提供了Observable类以及Observer接口,它们构成了Java语言对观察者模式的支持。

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

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

相关文章

提高测试效率5大捷径

1、优先级 测试任务和开发任务一样&#xff0c;都需要进行优先级排序。在测试工作中&#xff0c;优先进行级别高的测试任务&#xff0c;这样能够在无法保障测试周期的前提下&#xff0c;也不会对整体开发进度造成较大的影响。 提高测试效率5大捷径 2、重视测试策略 测试策略的基…

零代码,使用 Dify 两分钟接入企业微信

前置准备 企业微信的管理员权限 一个 Dify 的帐号 一个 Laf 云的帐号 &#xff08;可选&#xff09;一个 OpenAI 的 API Key。如果没有&#xff0c;可以使用 Dify 免费提供的 200 次调用机会用于测试。 &#xff08;可选&#xff09;在电脑上新建一个 env.txt 的文件&#…

C++进阶 —— 列表初始化(C++11新特性)

目录 一&#xff0c;列表初始化 二&#xff0c;类列表初始化 三&#xff0c;类模板列表初始化 库模板初始化列表实现 模拟模板初始化列表实现 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)&#xff0c;使得C03这个名字已经取代了C98称为C11之前的最新C标准名称&…

神经网络与机器学习

《神经网络与深度学习》 第一章 绪论1.1 人工智能知识结构预备知识顶会论文常用的深度学习框架研究领域 1.2 如何开发AIS芒果机器学习 1.3 表示学习局部表示和分布式表示 1.4 深度学习&#xff08;Deep Learning) 第一章 绪论 1.1 人工智能 人工智能的一个子领域 神经网络&a…

百度商业AI技术创新大赛火热进行中,携手专家大咖一起创新为更好!

百度商业AI技术创新大赛火热进行中 来自百度、中国人工智能学会 及NVIDIA的专家大咖纷纷送上寄语 希望与充满创新思维的年轻人一起 探讨AI技术的创新应用 挖掘AIGC在商业领域发展的更多可能 开启中国人工智能发展新篇章&#xff01; -戴琼海- 国务院参事 CAAI理事长 …

分布式锁的应用场景与分布式锁实现(三):基于Zookeeper实现分布式锁

分布式锁的应用场景与分布式锁实现&#xff08;二&#xff09;&#xff1a;基于Redis实现分布式锁 基于Zookeeper实现分布式锁 ​ 实现分布式锁目前有三种流行方案&#xff0c;分别为基于数据库、Redis、Zookeeper的方案。这里主要介绍基于zk怎么实现分布式锁。在实现分布式锁…

每日一题——重复的子字符串

每日一题 重复的子字符串 题目链接 注&#xff1a;本题的题解基本建立在KMP算法之上&#xff0c;对KMP算法不太了解的小伙伴可以参考这篇文章KMP算法及其改进图文详解 方法一&#xff1a;移动匹配 我们先来看几个可以由一个字串重复多次构成的主字符串&#xff1a;“aaa”&am…

chatgpt赋能Python-python人脸识别步骤

简介 Python是一种优秀的编程语言&#xff0c;它广泛应用于人工智能、数据科学、Web应用程序开发等领域。其中&#xff0c;人脸识别是Python应用程序中的重要一环。 本文将介绍Python人脸识别的具体步骤&#xff0c;希望对初学者有所帮助。 Python人脸识别步骤 安装必要的库…

销售管理全面指南:职能、流程、目标和工具

销售管理是优化公司销售队伍的过程&#xff0c;以有效利用现有资源来完成交易。对于任何依靠销售来推动收入的企业来说&#xff0c;这是绝对必要的。 销售管理可以细分为三个主要领域&#xff1a;销售运营、销售策略和销售分析。 根据美国营销协会&#xff08;AMA&#xff…

使用腾讯云短信服务实现Spring Boot短信发送

发送短信 01 注册微信公众号02 注册腾讯云账号03 创建签名和模板第一步 创建签名第二部 创建模板 04 发送短信 01 注册微信公众号 在百度中寻找微信公众平台&#xff0c;并在进入官网后注册。在账号注册过程中&#xff0c;需选择订阅号(个人)。注册成功后&#xff0c;请保存账…

我的浙大MEM提前批面试全流程重点信息梳理

浙江大学MEM已上岸&#xff0c;目前在读&#xff0c;给大家分享下我的备考经验&#xff0c;希望可以帮助到大家。 在确定自己的目标院校后收集相关信息是非常重要的&#xff0c;比如今年计划招多少学生&#xff0c;往年上岸都需要多少分&#xff0c;学费等情况&#xff0c;招考…

Kyligence x 集简云|无代码集成数百款应用,轻松打造数据产品

一站式指标平台 Kyligence Zen 现已支持对接集简云平台&#xff0c;企业无需繁琐的开发工作&#xff0c;即可无代码集成数百款应用&#xff0c;打破数据孤岛、统一数据口径&#xff0c;帮助企业实现数据的协作和分享&#xff0c;轻松进行数据分析、构建数据产品&#xff0c;助力…

腾讯董志强出席全国信安标委“标准周”:数字化转型需要高安全等级架构

2023年5月29日至6月1日&#xff0c;全国信息安全标准化技术委员会&#xff08;以下简称“信安标委”&#xff09;2023年第一次“标准周”活动在云南昆明举行。此次活动聚集了全国顶级的网络安全标准专家、学者和业界领袖&#xff0c;共同探讨网络安全标准领域的前沿议题和最佳实…

c语言函数返回值的几种方式,入参方式回传数据

背景 在正常使用过程中&#xff0c;突然发现有用二级指针传递地址&#xff0c;我想没必要用二级指针&#xff0c;实际目的是函数入参的参数&#xff0c;也是函数出参的参数 #mermaid-svg-ylOpK9fmaLgdD9YO {font-family:"trebuchet ms",verdana,arial,sans-serif;fo…

火山引擎A/B测试:MAB智能调优实验,企业活动效果提升新利器

618临近&#xff0c;各大电商APP的预热活动已然拉开序幕。对企业而言&#xff0c;一场活动从策划到上线&#xff0c;中间经过效果验证&#xff0c;其业务成本很高。一个好的活动创意从策划、开发、到最终发布&#xff0c;至少会经历几周实践&#xff0c;如果中间还经历A/B实验的…

三肽-33/Preventhelia(Diaminopropionoyl Tripeptide-33)

紫外线是一种电磁波&#xff0c;波长小于可见光&#xff0c;大部分地球表面的紫外线来自太阳&#xff0c;紫外线是伤害性光线的一种&#xff0c;经由皮肤吸收&#xff0c;会破坏DNA&#xff0c;使细胞会死亡或凋零从而产生皱纹、晒伤、等一系列不良反应。 作用机理---- Preven…

深入理解设计原则之依赖反转原则(DIP)

系列文章目录 C高性能优化编程系列 深入理解设计原则系列 深入理解设计模式系列 高级C并发线程编程 DIP&#xff1a;依赖反转原则 系列文章目录1、依赖反转原则的定义和解读2、稳定的抽象层3、依赖倒置原则和控制反转、依赖注入的联系小结 1、依赖反转原则的定义和解读 SOIL…

Linux零拷贝

零拷贝&#xff08;Zero-copy&#xff09;是一种优化技术&#xff0c;用于减少数据在内核空间和用户空间之间的拷贝次数&#xff0c;提高数据传输的效率和性能。它通过最小化数据的复制操作&#xff0c;将数据直接从源位置传输到目标位置&#xff0c;而不需要额外的数据拷贝。 …

微信小程序 构建npm报错: 没有找到可以构建的 NPM 包,请确认需要参与构建的 npm 都在 `miniprogramRoot` 目录内,

构建npm时报错 几个解决方案&#xff1a; 1、没有初始化项目 可以看这篇博客&#xff1a;微信小程序构建npm&#xff08;js和ts 2、ts版本下记得修改删除project.config.json中setting字段下的一些内容 需要加或修改 "packNpmManually": true, "packNpmRe…

短视频矩阵系统软件源码---技术部署创建

矩阵系统源码主要有三种框架&#xff1a;Spring、Struts和Hibernate。Spring框架是一个全栈式的Java应用程序开发框架&#xff0c;提供了IOC容器、AOP、事务管理等功能。Struts框架是一个MVC架构的Web应用程序框架&#xff0c;用于将数据模型、Web应用程序的用户界面和控制器逻…