软件工程 | 第四章 系统设计

软件设计:根据需求分析的“做什么”来确定系统该“怎样做”。需要有经验的软件设计师完成、设计方法遵循一系列的原则和策略、经过专家和用户的评审

一、软件设计的目标的任务

1.软件设计的两个阶段

(1)概要设计

  • 包含数据设计、体系结构设计、接口设计、过程设计
  • 任务–>将需求分析转化为软件的系统结构和数据结构
    • 分解独立的软件部件
    • 建立模块之间的层次结构、调用关系、模块间的接口、人机交互界面

(2)详细设计–>对概要设计阶段建立的模型进行详细的定义和说明

  • 确定每个模块的具体算法
  • 模块内部数据结构和数据库的物理结构
  • 模块接口的具体实现
  • 每个模块设计测试用例
  • 文档->复审

2.软件设计的目标

通过一系列迭代过程生成一个要构造的实体的模型/表示

3.软件设计中的信息流

在需求分析基础上,将分析模型中的数据、功能、行为模型–>设计模型中的数据设计、体系结构设计、接口设计、构件设计

软件工程 | 第四章 系统设计

(1)体系结构设计:软件主要结构性元素及其之间的关系,从需求规约、分析模型和分析模型定义的系统交互中导出

(2)数据设计:将信息模型(E-R图定义的对象和关系、数据字典中的详细数据内容)–>数据结构/数据库结构

(3)接口设计:内部模块之间、软件和外部系统之间、软件和人之间的通信   基于数据流图和控制流图

(4)过程设计(构件设计):描述软件构件的内部实现细节

4.软件设计的指导性原则

(1)可跟踪性:设计阶段的单独一个元素可跟踪到需求的一个或多个方面

(2)一致性:一致的概念、符号、术语;一致的内部接口、软硬件接口

(3)可靠性:即使遇到异常数据、事件、操作也可以平滑巧妙地降级

(4)简单性

(5)适应性:构件具有良好的可扩展性

(6)清晰性

二、软件设计的基本原理

(一)模块化

1.模块

  • 由一个总体标识符来代表的,包含输入/输出、逻辑处理功能、内部信息以及运行计划的语句集合
  • 模块是构件的一种形式,eg:过程、函数宏、子函数
  • 特点:接口、功能、逻辑(功能的实现方法)、状态(运行环境和调用关系)

2.模块化

  • 将软件系统划分为可独立命名、单独访问的模块,每个模块具有特定的功能属性,模块集成到一起即可构成满足用户需求的软件系统
  • 可提高代码的可使用、可重用、可理解性;简化软件维护

3.Merey标准–>如何分解、模块大小如何设计

  • 模块可分解性
  • 可组装性
  • 可理解性:不参照其他模块可单独理解
  • 连续性:修改软件模块时只对少数模块进行修改,且修改后不影响整体功能
  • 保护性:模块出现错误异常时只影响自身

(二)抽象

1.抽象方法:从考虑的问题出发,撇开事物现象的、外部的、偶然的东西,抽出事物本质的、内在的、必然的东西,从空间形式和数量关系上揭示客观对象的本质和规律。

2.软件生命周期过程中每前进一步都是对软件抽象层次的进一步细化。抽象的最低层次是源程序代码。

3.两种常用的抽象手段:

  • 过程抽象–>任何一个完成明确功能的操作都可被当做单个实体
  • 数据抽象–>定义数据类型和对该类型的操作、限制对象值的范围

(三)逐步求精

1.是一种自顶向下的设计策略,逐步细化问题的实质和细节,最终完善地解决问题

2.在软件设计中,逐步求精就是把软件设计中的问题按照优先级和层次进行排队,并逐步对各个问题进行解决

3.抽象和逐步求精是互补的过程,层次结构的上一层是下一层的抽象,下一层是上一层的求精

(四)信息隐藏

1.信息隐藏:模块内的数据和过程对不需要这些信息的模块是不能进行访问的

2.使模块更具有独立性;使软件维护相对容易

(五)模块的独立性

1.模块独立性:每个模块只完成系统要求的独立子功能,在数据和信息交互与其他模块没有或者极少关联

2.具有独立性的模块容易开发–>功能分隔彻底使得接口简单  容易测试和维护–>错误传播的范围小

3.衡量独立程度的度量:耦合 内聚 –>目标:高内聚 低耦合

4.耦合–>软件系统内部不同模块之间的相互关联程度的度量,耦合的强弱取决于模块间接口的复杂程度、调用模块的方式、组件间通信接口方式

软件工程 | 第四章 系统设计

(1)非直接耦合

模块具有完全的功能上的独立性,模块之间不存在数据信息传递,仅依靠调用关系实现软件功能

(2)数据耦合

模块间的调用关系通过传递数据实现 eg:函数输出值的传递

软件工程 | 第四章 系统设计

(3)特征耦合

一个模块向另一个模块传递非全局的数据结构

软件工程 | 第四章 系统设计

(4)控制耦合

模块间不仅传递数据,还传递对运行过程有影响的控制信号

使一个模块的执行直接影响到接受控制信号模块的运行

软件工程 | 第四章 系统设计

(5)外部耦合

一组模块均访问同一个全局简单变量 eg:extern型的外部变量

软件工程 | 第四章 系统设计

(6)公共耦合

多个模块共同引用公共数据环境(全局数据结构、共享通信区、内存公共覆盖区、介质上共享文件)

软件工程 | 第四章 系统设计

(7)内容耦合

一个模块直接修改、操作另一模块的内部数据,或者直接转入另一个模块

软件工程 | 第四章 系统设计

5.内聚–>模块内部数据和过程等信息之间的紧密程度。各元素联系越紧密,内聚性越高。

软件工程 | 第四章 系统设计

(1)偶然内聚

模块内各处理元素之间没有任何关系,对其修改需谨慎

软件工程 | 第四章 系统设计

(2)逻辑内聚

逻辑相关的功能被放在同一模块中,eg:一个模块读取各种不同类型外设的输入

逻辑内聚模块各元素在功能上并无关系

软件工程 | 第四章 系统设计

(3)时间内聚

模块完成的功能必须在同一时间内执行,功能只因为时间因素关联在一起。Eg: 系统初始化

软件工程 | 第四章 系统设计

(4)过程内聚

模块内各个元素必须按照一定的顺序执行,主要与程序的执行过程有关,而与功能无关   Eg:主模块

弱点:超越了模块的功能界限–>可能包含某一级模块的功能,同时包含更低层模块的功能

(5)通信内聚

模块内所有处理元素都在同一数据结构上操作   Eg:事务处理系统

软件工程 | 第四章 系统设计

(6)顺序内聚

各处理元素都密切相关与同一功能,且必须按照顺序执行

弱点:模块完成多个功能或部分功能–>模块功能不单一

(7)功能内聚

模块内所有元素共同完成一个功能,缺一不可

好处:界面清晰、容易理解,复用性较好

启发式设计规则(不属于普遍遵循的原理)

1.改进软件结构提高模块独立性:通过模块分解/合并–>降低耦合 提高内聚

2.模块规模适中

3.深度、宽度、扇入、扇出合理

  • 深度:软件结构中控制的层数,粗略表示一个系统的大小和复杂程度
  • 宽度:软件结构中同一层次上模块总数的最大值,宽度越大系统越复杂
  • 扇入:直接调用当前模块的上级模块数目,扇入越大表明模块的使用效率越高 软件工程 | 第四章 系统设计
  • 扇出:一个模块直接控制的模块数目,扇出过大意味着模块过分复杂 软件工程 | 第四章 系统设计
  • 模块扇出过大时,可以增加中间层次的控制模块 软件工程 | 第四章 系统设计

4.模块的作用域应该在控制域内

作用域:受该模块内的判定影响的所有模块的集合

控制域:模块本身及其所有直接或间接从属与它的模块的集合

所有受判定影响的模块都从属于做出判定的模块

5.力争降低模块接口的复杂程度

6.设计单入口单出口的模块

7.模块功能可以预测–>输入数据相同时输出相同

三、软件体系结构设计

1.软件体系结构的概念

  • Dewayne Perry、Alex Wolf

具有一定形式的结构化元素,即构件的集合,包括处理构件(对数据加工)、数据构件(被加工的信息)、连接构件(组合连接不同部分)

  • Mary Show 、David Garlan

处理算法与数据结构之上关于整体系统结构设计和描述方面的一些问题,eg:全局组织和全局控制结构、关于通信 同步 与数据存取的协议

  • Kruchten

概念角度–>系统的主要构件及其之间的关系

模块角度–>功能分解与层次结构

运行角度–>描述系统的动态结构

代码角度–>代码和库函数在开发环境中的组织

  • Bass 、Cements、Kazman

一个程序/计算机系统的软件体系结构包括一个/一组 软件构件、软件构件外部可见特性(构件提供的服务、性能、特性、错误处理、共享资源的使用等)、及其相互关系

  • 整理

软件体系结构为软件系统提供了一个结构、行为、属性的高级抽象

由构成系统的元素的描述、元素的相互作用、指导元素集成的模式、模式的约束组成

指定了系统的组织结构和拓扑结构,显示了系统需求和构成系统的元素之间的对应关系

2.软件体系结构的重要性

  • 是软件风险承担者沟通的手段
  • 突出早期设计决策的选择,对后续的设计实现以及最终成功产生直接影响
  • 具有可复用性

3.软件体系结构风格

定义了用于描述系统的术语表和一组指导构件系统的规则

软件体系结构设计的核心问题–>能否到达软件体系结构级别的软件重用

  • 分层体系结构

(1)系统被组织成一个层次结构,每一层高度内聚并为上层服务。每一层只对相邻的层可见,上层通过下层提供的接口调用下层的功能–>松散耦合的结构模型

软件工程 | 第四章 系统设计

(2)优点

  • 支持基于抽象程度递增的系统设计:开发设计人员在设计某一层时只需关注该层使用的技术及其功能
  • 支持功能增强:功能改变最多影响相邻两层,便于系统功能的扩展
  • 支持重用:提供的服务接口不变时,同一层的不同实现可以交换使用

(3)缺点

  • 并不是每个系统都能容易划分为分层的模式
  • 难以找到合适、正确的层次抽象方法
  • 系统进行数据传输时需要经过多个层次–>性能和效率的下降
  • 程序调试相对困难
  • C2体系结构风格

(1)一系列相互协作的、由连接件连接起来的构件

构件相对独立,构件之间的通信通过以连接件为中介的异步消息交换机制实现,构件可将任意复杂的功能封装在一起。

(2)遵守的规则

  • 组织规则–>结构构建以构件、连接件为基础 软件工程 | 第四章 系统设计
  • 通信规则–>构件间通信必须通过消息实现
    • 构件的顶端域:可以对哪些通知做出响应、可以发出哪些请求
    • 构件的地段域:可以向下层发送哪些通知,可以响应下层哪些请求
    • 只感知层次高于自己的构件提供的服务
  • C/S体系结构风格

(1)客户机、服务器是两个独立的逻辑系统,服务器负责数据管理,客户机负责数据显示、用户交互和逻辑处理

(2)两层C/S体系结构的组成

  • 客户机程序:包括用户界面、业务处理程序;负责向服务器发送请求消息、接收和分析从服务器返回的数据
  • 服务器程序:包括数据库、数据查询、数据存储、数据更新程序;负责管理客户机程序的数据、调度管理、事务处理计算、共享资源管理
  • 二者的关系
    • 用户通过客户机的用户交界面提出操作请求,客户机的请求把用户的操作转换成通信协议要求的表达方式。通过服务器在客户机的代理,客户提出操作请求并获得服务器返回信息。
    • 服务器端的服务器接口提供客户机与服务器联系的标准
软件工程 | 第四章 系统设计

(3)优点

  • 客户机、服务器构件位置透明,利于分布式数据组织
  • 可分别运行在不同的操作系统之上,便于异构平台的不同开发技术的融合匹配
  • 构件之间充分隔离并彼此独立–>软硬件环境具有极大的灵活性,具有良好的可扩展性

(4)缺点

  • 开发成本高:软硬件配置要求比较高
  • 客户机程序设计复杂
  • 数据安全性不好:客户端可以直接访问数据库服务器
  • 单一服务器且以局域网为中心,难以扩展至大型企业广域网、Internet
  • 维护和升级成本高
  • 三层C/S体系结构风格

(1)组成

表示层负责处理用户的输入和向客户的输出,用于系统和用户之间的交互;功能层负责建立数据库连接,根据用户的请求生成访问数据库的SQL语句,并把结果返回给客户机;数据层负责实际的数据库存储和检索,响应功能层的数据处理请求,并将结果返回给功能层。

软件工程 | 第四章 系统设计
  • 表示层:系统和用户间的接口,实现系统与系统应用之间的对话
  • 功能层:负责处理具体的业务逻辑
  • 数据层:负责对数据库数据的读写操作
软件工程 | 第四章 系统设计

(2)优点

  • 合理划分三层结构的功能–>逻辑上保持相对独立,系统的逻辑结构更清晰
  • 更灵活、有效地选用相应的平台和硬件系统
  • 各层可进行自主语言的选择并且 可以并行开发
  • 充分利用功能层隔离表示层和数据层,增强数据安全性
  • B/S体系结构风格

(1)是三层C/S结构的一种实现方式,由浏览器、Web服务器、数据库服务器组成

软件工程 | 第四章 系统设计

(2)优点

  • 系统维护和升级方式简单:主要工作在服务器端,客户端不需要维护
  • 成本低,选择多:服务器可以选择多个操作系统,客户机可以选择多个浏览器

(3)不足

  • 缺乏对动态页面支持能力,没有集成有效的数据库处理能力
  • 系统扩展能力差,安全性难以保障
  • 数据查询等的响应速度低于C/S
  • 正交体系结构风格

(1)正交体系结构风格是一种由组织层和线索组成的层次化结构

每一个组织层都包含具有相同抽象级别的构件

线索:不同的功能模块,由完成不同层次功能的构件通过相互调用来组成,每一条线索完成整个系统中相对独立的一部分功能

完全正交:线索之间无关,同一层的构件之间不存在调用关系

(2)特征

  • 正交体系结构由完成不同功能的n个线索组成,n>1
  • 系统有m个不同抽象级别的层次,m>1
  • 线索之间保持相对的独立性(正交性)
  • 公共顶层–>驱动线索的运行;公共底层–>为线索提供公共的构件和使用数据 软件工程 | 第四章 系统设计

(3)优点

  • 结构清晰,容易理解–>线索功能相互独立,不进行相互调用
  • 易修改,可维护性强–>变更局部化,缩小了变更范围,减少了修改的工作量
  • 可移植性强
  • 数据共享体系结构风格(仓库风格)

(1)包含两种构件:中央数据结构(资源库)–>表示系统当前的状态;独立构件的集合–>对中央数据结构进行操作

(2)根据中央数据单元和构件之间信息交换方式的不同:

  • 根据输入事务选择何种处理
  • 由中央数据结构的当前状态决定何种处理–>黑板体系结构
  • MVC体系结构风格

(1)为需要为同样数据提供多个视图的应用程序设计,实现了数据层与表示层的分离,适合开发与GUI有关的应用程序

(2)组成

  • 模型:维护数据并提供数据访问方法
  • 视图:绘制模型的部分数据或所有数据的可视图
  • 控制器:进行事件的处理

(3)优点

  • 多个视图可以对应一个模型–>可减少代码复制和维护的工作量
  • 降低各层间的耦合,提供了应用的可扩展性
  • 更符合软件工程化管理的精神–>不同的层各司其职

(4)问题

  • 增加了系统结构和实现的复杂性
  • 视图与控制器的连接过于紧密
  • 视图对模型数据的访问效率低
  • 异构体系结构的集成

多种体系结构并存并相互融合,eg:B/S C/S体系结构的组合

  • “内外有别”
    • 企业内部人员利用C/S架构通过局域网访问企业数据库,可提高系统查询和修改的响应速度
    • 外部通过B/S架构从Internet上通过Web服务器浏览企业内部数据库,保证数据库的安全,但响应速度慢
  • “查改有别”
    • 对数据库浏览查询:采用B/S
    • 对数据库维护修改:采用C/S

4.软件体系结构设计方法 

  • 工件驱动的软件体系结构设计方法

(1)软件过程每经历一个阶段,就会发生一次知识转换的过程,最终编码人员把知识固化在软件产品中。

    软件成型前,知识的主要载体是文档和模型–>工件

(2)过程

软件工程 | 第四章 系统设计
  • 用例驱动的软件体系结构设计方法

(1)用例建模:使用用例描述系统需求的过程

    用例模型:所有用例组合在一起,描述系统的全部功能,获取系统的功能需求

(2)迭代构建软件体系结构

  • 根据软件领域范围建立临时的软件体系结构
  • 选取重要的用例,使体系结构支持用例
  • 选取更多用例,建立更加完美的体系结构
  • 每次迭代,选取并实现一组用例–>确认体系结构,每次迭代结束时进行评估

(3)软件开发项目分成如下几个阶段:

  • 初始阶段:设定产品功能范围,建立初始业务案例,从业务角度表明项目的可行性
  • 细化阶段:建立体系结构基线,捕获大多数需求
  • 构造阶段:开发系统,保证产品可移交给客户,即产品达到最初的可操作能力
  • 移交阶段:却被得到准备向用户社团发布的产品

体系结构主要是在细化阶段的迭代过程中发展起来的

  • 模式驱动的软件体系结构设计–>从模式导出体系结构抽象 
软件工程 | 第四章 系统设计
  • 领域驱动的软件体系结构设计DSSA

(1)基本思想

  • 对具体领域的一系列相似系统可重用信息进行识别、提取、收集和组织
  • 对可利用信息进行整理和再加工–>规范化 标准化,有利于重用
  • 软件体系结构模型的建立参考并使用规范化可重用信息
  • 是多系统范围内的体系结构,从一组系统中导出

(2)设计过程

软件工程 | 第四章 系统设计
  • 需求驱动的软件体系结构设计方法

描述解决的问题和解决方案之间的动态关系

软件工程 | 第四章 系统设计

(1)问题空间:定义所解决的问题

(2)需求分析前期阶段:理解问题,考虑组织和非功能需求;后期阶段:描述系统的相关功能和属性

(3)体系结构设计

根据组件或者子系统之间的数据、控制及其他依赖关系描述系统全局结构设计;

        1)把体系结构看做抽象的组件通过连接交互的整体,基于细化的需求模型,确定组件满足的非功能需求和功能需求(用场景表示)

2)通过描述组件和连接的抽象属性,得到软件体系结构的抽象模型;

3) 从需求分析模型确定的解决空间中发现体系结构设计方案,得到具体的体系结构实例;

4)进行评价–>在选定解决方案的同时建立场景模型。

四、系统设计方法(实现设计模型的手段和方法)

 (一)程序流程图

1.基本符号

软件工程 | 第四章 系统设计

 2.控制结构

软件工程 | 第四章 系统设计

3.存在的问题

(1)表示程序控制流程的箭头不受任何约束,容易造成程序控制结构的混乱;

(2)难以描述逐步求精的过程,导致过早考虑细节而忽略全局;

(3)只描述执行过程,难以表示数据结构;

(4)符号繁多,记忆不便

(二)盒图(N-S图)

1.基本控制结构

软件工程 | 第四章 系统设计

 2.在N-S图中,每个处理步骤(语句或者语句序列)使用一个盒子表示;盒子可以嵌套另外一个盒子;只能从盒子上边进入、下边走出,限制了随意的控制转移。

软件工程 | 第四章 系统设计

3.优点

(1)形象直观,具有良好的可见度,容易理解设计意图,为编程、复查、选择测试用例、维护带来了方便

(2)强制设计人员采用结构化程序设计方法进行思考并描述设计方案,有效保证了设计质量

(3)简单 易学 易用

(4)容易表现嵌套关系并且不限制嵌套深度

4.问题:手工修改麻烦

(三)问题分析图(problem analysis diagram, PAD)

1.PAD是面向高级程序设计语言设计的,使用二维树形结构表示程序的控制流

2.基本符号

软件工程 | 第四章 系统设计

3.图例

软件工程 | 第四章 系统设计

4.优点

(1)更容易表示结构化程序控制图。

(2)程序层次增加,PAD向右延伸,每增加一个层次,向右扩展一条竖线。竖线的总数就是程序的层次数量。

(3)表现程序逻辑易读易懂–>程序从图中最左竖线的上端节点开始执行,自上而下、自左向右遍历所有结点。

(4)可以使用工具软件自动转换成高级语言源程序。

(5)支持自顶向下、逐步求精的方法。

(四)HIPO图(Hirearchy plus input/processing/output)

1.表示软件系统结构的设计工具

H图–>描述软件模块层次结构

IPO图–>描述每个模块的输入、输出数据、处理功能、模块调用的详细情况

HIPO图是以模块分解的层次性以及模块内输入、处理输出三大基本部分为基础构建的

2.H图说明软件系统由哪些模块组成以及其控制层次结构

软件工程 | 第四章 系统设计

3.IPO图描述模块输入、输出和处理细节,以及与其他模块间的调用和被调用关系

软件工程 | 第四章 系统设计

(五)判定表

1.判定表是分析和表达多逻辑条件下执行不同操作情况的工具

适合:某些操作的实施依赖多个逻辑条件的组合,即针对不同的逻辑条件组合值,分别执行不同的操作。

2.例子

软件工程 | 第四章 系统设计

3.判定表的组成

(1)条件桩–>问题的所有条件

(2)动作桩–>问题规定可能采取的操作

(3)条件项–>在所有可能情况下的真假值

(4)动作项–>在条件项的各种取值情况下采取的动作

4.判定表的建立

(1)确定规则个数,对于n个条件,有2n种规则

规则:一个条件组合的特定取值以及相应执行的操作称为规则,判定表中贯穿条件项和动作项的一列就是一条规则

(2)列出所有条件桩、动作桩

(3)填入条件项

(4)填入动作项

(5)合并相似规则

软件工程 | 第四章 系统设计

(六)判定树

更加直观表示逻辑判断问题

软件工程 | 第四章 系统设计

树根:加工明

中间:各项条件

最右侧:行动

(七)过程设计语言(Process design language,PDL)

1.用于描述模块中算法和加工的具体细节,具有严格的关键字外部语法,用于定义控制结构和数据结构

2.语法包括外层语法、内层语法

外侧语法:描述程序的结构,采用与一般编程语言类似的关键字

内层语法:描述操作,采用任意自然语句

3.优点

(1)可以作为注释插入源代码–>促使维护人员在修改程序的同时修改PDL注释,保持文档和程序的一致性

(2)易于被计算机处理和存储

(3)可以自动产生程序

(八)Jackson图

1.是面向数据结构的设计方法,即以数据结构作为程序设计的基础

2.基本结构

(1)顺序

软件工程 | 第四章 系统设计

(2)选择

软件工程 | 第四章 系统设计

(3)重复

软件工程 | 第四章 系统设计

3.改进–>增加判定条件

软件工程 | 第四章 系统设计

4.Jackson方法–>构建Jackson图

软件工程 | 第四章 系统设计

(1)确定输入数据和输出数据的逻辑结构

软件工程 | 第四章 系统设计

(2)找输入数据、输出数据结构中有对应关系的数据单元

软件工程 | 第四章 系统设计

(3)导出Jackson图

针对有对应关系的,在相应层次画处理框

输入数据中剩余的数据单元,在相应层次画处理框

输出数据中剩余的数据单元,在相应层次画处理框

软件工程 | 第四章 系统设计

(4)列出操作和条件 使用伪代码表示程序

软件工程 | 第四章 系统设计

五、用户界面设计

1.设计原则

(1)以用户为中心的可视性原则

系统的设计决策结合用户的工作和应用环境,理解用户对系统的需求,同时给出可视性效果良好的界面设计

(2)一致性原则

系统内部具有相似的界面外观、布局、相似的人机交互方式以及信息显示格式

(3)交互性原则

体现系统的状态反馈信息(用户在人机操作过程中,用户从软件系统得到的信息),并对人的操作进行适当的反应

(4)重要性原则

按照管理对象在控制系统中的重要性和全局性水平,设计人机界面的主次菜单、对话窗口的位置和凸显性

(5)功能原则

设计分功能区多级菜单、分层提示信息、多项对话框并举的窗口

(6)合理性原则

2.设计过程

(1)创建系统需求功能的外部设计模型

设计模型考虑软件的数据结构、总体结构、过程性描述

需要充分了解不同类型用户的详细情况、基本需求

(2)确定完成此系统功能的人、计算机分别完成的任务

(3)构建人机界面原型

(4)评估界面设计

3.设计方法

(1)迭代设计

初步设计–>创建第一级原型–>用户试用并评估–>根据修改意见设计并实现下一级原型

(2)以用户为中心

使用户充分理解设计者的指导意图,正确进行实验操作;设计者从使用者那里得到有效的反馈信息以改进界面,二者有效地实现双向互动

软件工程 | 第四章 系统设计
© 版权声明
THE END
喜欢就支持以下吧
点赞1赞赏
分享
评论 抢沙发

请登录后发表评论