第04章 软件设计方法.docx

上传人:b****8 文档编号:29780374 上传时间:2023-07-26 格式:DOCX 页数:25 大小:303.88KB
下载 相关 举报
第04章 软件设计方法.docx_第1页
第1页 / 共25页
第04章 软件设计方法.docx_第2页
第2页 / 共25页
第04章 软件设计方法.docx_第3页
第3页 / 共25页
第04章 软件设计方法.docx_第4页
第4页 / 共25页
第04章 软件设计方法.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

第04章 软件设计方法.docx

《第04章 软件设计方法.docx》由会员分享,可在线阅读,更多相关《第04章 软件设计方法.docx(25页珍藏版)》请在冰豆网上搜索。

第04章 软件设计方法.docx

第04章软件设计方法

第四章软件设计方法

针对同一问题的逻辑模型,不同的设计思路和方法会产生不同的软件实现方案,上一章讨论了有关软件设计阶段所应遵循的基本原理和原则,这些原理和原则有助于综合评价不同的设计方案,和研究新的软件设计方法。

这一章将讨论一些常用的软件设计表达工具和两个经典的软件设计方法。

需要说明的是,这些表达工具和方法是以往人们在软件设计活动中总结出来的,它们既不是唯一的标准,也不是一成不变的。

在学习中既要学会使用,也要了解它们各自的优缺点,以便于在实际工作中灵活选用,或者结合实际工作的情况和自己的实践经验,进一步改进这些工具和方法,以便于更好的完成自己的设计工作。

目前,软件设计方法可以分为3大类。

第一类是根据系统的数据流进行设计,称为面向数据流的设计,以结构化设计方法(StructuredDesign,SD)为代表。

第二类是根据系统的数据结构进行设计,称为面向数据结构的设计方法或者数据驱动的设计方法,以LCP(LogicalConstructionofPrograms,程序逻辑构造)方法、Jackson系统开发方法和数据结构化系统开发(DSSD,DataStructuredSystemDevelopment)方法为代表。

第三类设计方法即面向对象设计方法。

本章具体讨论以下内容:

1.概要设计工具。

2.详细设计工具。

3.结构化软件设计方法。

4.Jackson软件设计方法。

5.面向对象软件设计方法概述。

4.1软件设计常用工具

4.1.1概要设计工具

概要设计主要是完成软件模块的划分,所以概要设计工具重点是在表达软件的结构,即模块划分和模块之间的关系,最常用的概要设计工具有下面两种:

1、HIPO图

图4-1层次图举例

HIPO图是由层次图(HC图)加上IPO图组成,是美国IBM公司在软件设计中常用的一种表达工具。

层次图中的矩形框表示模块,而针对层次图中的每一个模块再配上IPO图来表达输入、处理、输出。

层次图用来描绘软件的层次结构,与需求分析中介绍的层次图相同,但是表现的内容不同。

层次图中的矩形框代表模块,方框间的连线表示调用关系,而在需求分析中表示组成关系。

如下图所示,最顶层的方框代表主控模块,它调用下层模块完成软件系统的功能。

2、结构图

结构图是进行软件概要设计的另一个工具。

结构图和层次图类似,也是描绘软件模块的图形工具,图中一个方框代表一个模块,框内标明模块的名字或主要功能;方框之间的箭头(或直线)表示模块的调用关系。

在结构图中通常还用带注释的箭头表示模块调用过程中来回传递的信息。

如果希望进一步标明传递的信息是数据还是控制信息,则可以利用注释箭头尾部的形状来区分:

尾部是空心圆表示传递的是数据,实心圆表示传递的是控制信息。

图4-2结构图举例

另外还有一些附加的符号,可以表示模块的选择调用或循环调用。

下图(左)表示当模块M中某个判定为真时调用模块A,为假时调用模块B。

图(右)表示模块M循环调用模块A、B和C。

图4.3结构图的附加符号

4.1.2详细设计工具

描述软件过程的工具称为详细设计的工具,它们可以分为图形、表格和语言三类。

不论是哪类工具,对它们的基本要求都是能提供对设计的无歧义的描述,也就是应该能指明控制流程、处理功能、数据组织以及其它方面的实现细节,从而在编码阶段能把对设计的描述直接翻译成程序代码。

常见的详细设计工具有下面几种:

1、程序流程图(flowchart)

程序流程图能直观地描述软件过程,是最常用的一种软件过程表达工具。

在图中,方框表示一个处理步骤,菱形代表一个逻辑条件,箭头表示控制流向。

如图4-4。

图4-4程序流程图举例

2、N-S流程图

1973年,Nassi和Shneiderman提出了一种程序图形表示工具,称为N-S流程图。

这种表达方式取消了流程线,使得表达出的程序流程一定是结构化的程序流程。

在图中,每个处理步骤都用一个矩形框来表示,这些处理步骤可以是语句或语句序列,在需要时,矩形框中还可以嵌套另一个矩形框,如图4-5。

图4-5N-S流程图

3、PAD图

PAD是问题分析图(ProblemAnalysisDiagram)的英文缩写,1973年由日本日立公司发明。

它是用二维树形结构的图来表示程序的控制流,将这种图翻译成程序代码比较容易。

图4-6给出了PAD图的基本符号。

图4-6PAD图图形符号

PAD图是面向高级程序设计语言的,为FORTRAN、COBOL和PASCAL等各种常用的高级程序设计语言都提供了一整套相应的图形符号。

由于每种控制语句都有一个图形符号与之对应,显然将PAD图转换成与之对应的高级语言程序比较容易。

4、过程设计语言(PDL,ProgramDesignLanguage)

PDL是一种软件过程的文字表达工具。

它是一种伪代码,具有严格的关键字语法,用于定义控制结构和数据结构,同时它的表示实际操作和条件的语法又是灵活自由的,可使用自然语言的词汇,如图4-7。

图4-7用PDL语言表示的程序流程

4.2结构化软件设计方法

结构化设计是目前使用最广泛的一种设计方法。

在软件需求分析阶段,我们利用结构化分析方法得到用DFD和DD描述的需求规格说明书,那么在总体设计阶段,我们将以结构化设计方法为基础得到软件的模块结构。

SA与SD相衔接,构成一个完整的结构化分析设计技术。

面向数据流的设计方法的目标是给出设计软件结构的一个工程化的操作步骤。

在软件工程的需求分析阶段,信息流是一个关键考虑,通常用数据流图描绘信息在系统中加工和流动的情况。

面向数据流的设计方法定义了一些不同的“映射”,利用这些映射可以把数据流图变换成软件结构。

因为任何软件系统都可以用数据流图表示,所以面向数据流的设计方法理论上可以设计任何软件的结构。

通常所说的结构化设计方法(简称SD方法),也就是基于数据流的设计方法。

4.2.1概念

面向数据流的设计方法把信息流映射成软件结构,信息流的类型决定了映射的方法。

信息流有下述两种类型。

1、变换流(transformflow)

根据基本系统模型,信息通常以“外部世界”的形式进入软件系统,经过处理以后再以“外部世界”的形式离开系统。

特点:

从同一数据源进入系统的数据,它在数据流图中流动的逻辑路径是相同的。

参看下图,信息沿输入通路进入系统,同时由外部形式变换成内部形式,进入系统的信息通过变换中心,经加工处理以后再沿输出通路变换成外部形式离开软件系统。

当数据流图具有这些特征时,这种信息流就叫做变换流。

图4-8变换流

变换流的DFD是一个线性结构,由输入、变换和输出三部分组成。

变换是系统的变换中心,变换输入端的数据流为系统的逻辑输入,输出端为逻辑输出。

而系统输入端的DF为物理输入,输出端为物理输出。

图4-9变换型数据流图

变换型数据处理的工作过程大致分为三步,即取得数据、变换数据和给出数据。

这三步反映了变换型问题DFD的基本思想。

其中,变换数据是数据处理过程的核心工作,而取得数据是为它做准备,给出数据则是对变换后的数据进行后处理工作。

2、事务流

基本系统模型意味着变换流。

因此,原则上所有信息流都可以归结为这一类。

但是,当数据流图具有和下图类似的形状时,这种数据流是“以事务为中心的”,也就是说,数据沿输入通路到达一个处理T,这个处理根据输入数据的类型在若干个动作序列中选出一个来执行。

这类数据流应该划为一类特殊的数据流,称为事务流。

图4-10事务型数据流图

上图中的处理T称为事务中心,它完成下述任务:

1)接收输入数据(输入数据又称为事务)

2)分析每个事务以确定它的类型

3)根据事务类型选取一条活动通路

3、基本步骤

Yourdon的结构化设计方法建立在结构化分析的基础上,一般先得到系统的DFD,再建立程序结构图。

可分为五个基本步骤:

1、分析DFD:

即进行系统的结构化分析,把设计表示为整个系统对数据流的处理问题,用一组分层的DFD来表示系统划分的功能、数据流和对数据流所做的处理。

2、确定DFD的特点及边界:

区分事务流、变换流。

3、映射为软件结构:

得到两层结构图,标明接口控制信息及主要DF。

有两个设计映射策略-变换分析和事务分析可供采用。

这两种策略提供了两个不同的两层结构图。

它们可以单独使用,或结合在一起相互补充,用来为每种策略开发一个分层设计和转换过程。

4、细化后,得到初始结构图:

在作进一步分解细化时,一般原则为:

顶层模块负责控制处理服务,实际工作较少;每个下层模块较少执行控制功能而较多作具体处理工作;底层模块应有高度聚合,较少有外部控制的特性。

下层模块可以是DFD种的一个或多个加工,也可以把加工再进行分解,灵活性较高,其重要性也不及上层模块,关键是满足设计的质量标准。

5、获得最终的软件结构图:

按照软件设计的质量标准来改进结构,得到最终的软件结构图。

这一步使用设计的质量度量为标准进行优化。

结构化设计主要提供两种设计度量技术:

耦合性度量和内聚性度量。

高质量的程序设计要求模块之间的耦合尽可能松散,以提高程序的可扩展性和可维护性,减少错误的发生。

与耦合性相反,程序设计要求模块内部的关联程度高。

因此,内聚性较强,设计质量就越好。

必要时还可考虑结构的形态问题等因素。

4.2.2变换分析

变换分析是一系列设计步骤的总结,经过这些步骤把具有变换流特点的数据流图按预先确定的模式映射成软件结构。

举例说明

变换分析方法由以下四步组成:

重画数据流图;区分有效(逻辑)输入、有效(逻辑)输出和中心变换部分;进行一级分解,设计上层模块;进行二级分解,设计中、下层模块。

1)重新分析数据流图

在需求分析阶段得到的数据流图侧重于描述系统如何加工数据,而分析数据流图的出发点是描述系统中的数据是如何流动的,确定其具有变换流特征。

2)在数据流图上区分系统的逻辑输入、逻辑输出和中心变换部分

若设计人员经验丰富,对要设计系统的软件规格说明又很熟悉,那么决定哪些加工是系统的中心变换是比较容易的。

例如,几股数据流汇集的地方往往是系统的中心变换部分。

如下图,框“计算”就是中心变换。

它有一个输入和两个输出,是数据流图内所有加工中数据流比较集中的一个框。

图4-11逻辑输入、变换中心和逻辑输出

另外,可以用以下的试探方法来确定系统的逻辑输入和逻辑输出在那里。

可以从数据流图的物理输入端开始,一步一步向系统的中间移动,一直到遇到的数据流不再被看作是系统的输入为止,则其前一个数据流就是系统的逻辑输入。

也就是说,逻辑输入就是离物理输入端最远的,但仍被看作是系统输入的数据流。

类似地,从物理输出端开始,一步一步地向系统的中间移动,就可以找到离物理输出端最远的,但仍可被看作是系统输出的数据流,它就是系统的逻辑输出。

从物理输入端到逻辑输入,构成系统的输入部分;从物理输出端到逻辑输出,构成输出部分;夹在输入部分和输出部分之间的就是中心变换部分。

中心变换部分是系统的中心加工部分。

从输入设备获得的物理输入一般要经过编辑、数制转换、格式变换、合法性检查等一系列预处理,最后才变成逻辑输入传送给中心变换部分。

同样,从中心变换部分产生的是逻辑输出,它要经过格式转换、组成物理块等一系列后处理,才称为物理输出。

3)进行一级分解,设计系统模块结构的顶层和第一层

首先设计一个主模块,并用系统的名字为它命名,然后将它画在与中心变换相对应的位置上。

作为系统的顶层,它的功能是调用下一层模块,完成系统所要做的各项工作。

主模块设计好之后,下面的程序结构就可按输入、中心变换和输出等分支来处理。

程序结构的第一层可以这样设计:

为每一个逻辑输入设计一个输入模块,它的功能是为主模块提供数据;为每一个逻辑输出设计一个输出模块,它的功能是将主模块提供的数据输出;为中心变换设计一个变换模块,它的功能是将逻辑输入转换成逻辑输出。

第一层模块与主模块之间传送的数据应与数据流图相对应,参看下图。

在图中,主模块控制、协调第一层的输入模块、变换模块和输出模块的工作。

一般说来,它要根据一些逻辑(条件或循环)来控制对这些模块的调用。

图4-12模块结构图

4)进行二级分解,设计输入、中心变换、输出部分的中、下层模块

自顶向下,逐层细化,为第一层的每一个输入模块、输出模块、变换模块设计它们的从属模块。

设计下层模块的顺序是任意的。

但一般是先设计输入模块的下层模块。

输入模块的功能是向调用它的上级模块提供数据,所以它必须要有一个数据来源。

因而它必须有两个下属模块:

一个是接收数据;另一个是把这些数据变换成它的上级模块所需的数据。

而接收数据模块又是输入模块,又要重复上述工作。

如果输入模块已经是原子模块,即物理输入端,则细化工作停止。

因此,对于每一个逻辑输入,在数据流图上向物理输入端方向逆向移动,只要还有加工,就在相应输入模块下面建立一个子输入模块和一个子变换模块。

同样,输出模块是从调用它的上级模块接收数据,用以输出,因而也应当有两个下属模块:

一个是将上级模块提供的数据变换成输出的形式;另一个是将它们输出。

因此,对于每一个逻辑输出,在数据流图上向物理输出端方向正向移动,只要还有加工框,就在相应输出模块下面建立一个子变换模块和一个子输出模块。

设计中心变换模块的下层模块没有通用的方法,一般应参照数据流图的中心变换部分和功能分解的原则来考虑如何对中心变换模块进行分解。

上图是进行设计的例子。

其中的“计算”是系统的核心数据处理部分,即中心变换。

中心变换左边的“编辑”和“检验”是为“计算”做准备的预变换。

预变换以后,送入主模块的数据流就是系统的逻辑输入。

中心变换送出的数据流就是系统的逻辑输出。

中心变换右边的“格式化1”和“格式化2”都是对计算值做格式化处理的后变换。

4.2.3事务分析

在很多应用中,存在某种作业数据流,它可以引发一个或多个处理,这些处理能够完成该作业要求的功能。

这种数据流就叫做事务。

下面讨论如何从数据流图建立系统结构图。

与变换分析一样,事务分析也是从分析数据流图开始,自顶向下,逐步分解,建立系统的结构图。

这里取下图所示的数据流图为例,说明事务分析设计方法的步骤。

图4-13数据流图举例

在上图所示的数据流图中,首先确定了它是具有事务型特征的数据流图。

也就是说,数据流A是一个带有“请求”性质的信息,即为事务源。

而加工I则具有“事务中心”的功能,它后继的三个加工L、M、N是并列的,在加工A的选择控制下完成不同功能的处理。

最后,经过加工O将某一加工处理的结果整理输出。

为此,首先建立一个主模块用以代表整个加工,它位于P-层(主层)。

然后考虑被称为下一层(事务层)的第二层模块。

第二层模块只能是三类:

取得事务、处理事务和给出结果。

在上图中,依据并列的三个加工,在主模块之下建立了三个事务模块,分别完成L、M和N的工作。

并在主模块的下沿以菱形引出这三个事务模块的选择,而在这些事务模块的左右两边则是对应于加工I和O的“取得A”模块和“给出H”模块。

图4-14相应的模块结构图

各个事务模块下层的操作模块,即A-层(活动层)和细节模块,即D-层(细节层),在图中未画出,可以继续分解扩展,直至完成整个结构图。

从以上例子,可以得到事务分析方法的步骤:

1)识别事务源:

利用数据流图和数据字典,从问题定义和需求分析的结果中,找出各种需要处理的事务。

通常,事务来自物理输入装置。

2)规定适当的事务型结构:

在确定了该数据流图具有事务型特征之后,根据模块划分理论,建立适当的事务型结构。

3)识别各种事务和它们定义的操作:

通过问题定义和需求分析规格说明找出所有事务机器操作所必需的全部信息,而对于系统内部产生的事务,必需仔细地定义它们的操作。

4)注意利用公用模块:

在事务分析的过程中,如果不同事务的一些中间模块可由具有类似的语法和语义的若干个低层模块组成,则可以把这些低层模块构造成公用模块。

合并具有相同处理功能的模块。

若干个模块中,存在着相同的处理动作,可将其分离出来,合并成一个动作模块,也可以从一组低层功能组合的模块中产生一个中层模块。

5)对每一事务,或对联系密切的一组事务,建立一个事务处理模块:

如果发现在系统中有类似的事务,可以把它们组成一个事务处理模块。

但如果组合后的模块是低内聚的,则应该再打散重新考虑。

这就是说,应当避免低内聚模块。

6)对事务处理模块规定它们全部的下层操作模块:

下层操作模块的分解方法类似于变换分析。

但要注意,事务处理模块共享公用(操作)模块的情形相当常见。

7)对操作模块规定它们的全部细节模块:

对于大型系统的复杂事务处理,可能有若干层细节模块。

另外,尽可能使类似的操作模块共享公用的细节模块,但要避免内容耦合。

一般地,如果数据流不具有显著的事务流的特点,最好使用变换分析;反之,如果具有明显的事务中心,则应该采用事务分析技术。

变换分析是软件系统结构设计的主要方法。

因为大部分软件系统都可以应用变换分析进行设计。

但是,在一些情况下,仅使用变换分析是不够的,还需要其它方法作为补充。

事务分析就是最重要的一种方法。

虽然不能说全部数据处理系统都是事务型的,但是很多数据处理系统属于事务型系统。

一般,一个大型的软件系统是变换型结构和事务型结构的混合结构。

所以,我们通常利用以变换分析为主,事务分析为辅的方式进行软件结构设计。

在系统结构设计时,首先利用变换分析方法把软件系统分为输入、中心变换和输出三个部分,设计上层模块,即主模块和第一层模块。

然后根据数据流图各部分的结构特点,适当地利用变换分析或事务分析,就可以得到初始系统结构图的某个方案。

4.2.4设计的后处理

在完成结构开发和结构完善之后,还必须做好下列工作:

1.为每个模块开发一份处理说明

处理说明应当是无二义性的,有界的,发生在一个模块内部的处理描述。

该说明主要应包括处理的任务、决策以及I/O。

2.为每个模块提供一份接口描述

接口描述要给出一览表,列出所有进入模块和模块送出的数据,说明应包括通过参量表传递的数据,外部的I/O,以及从全程数据区得到的数据项。

另外,还要给出它的从属模块和上级模块。

3.定义局部的和全程的数据结构

数据结构的设计可能对程序结构和每个模块的过程细节有深远的影响,所以特别要注意局部的和全程的数据结构的设计。

4.给出所有的设计限制和约束

每个模块的设计限制和约束,典型的内容有数据类型或格式的限制、内存容量或时间的限制、数据结构的边界值或数量、没有考虑到的特殊情况,以及个别模块的特殊要求等。

给出限制和约束的目的,在于减少因为“假设的”功能特性而引进的错误的数量。

5.进行概要设计的评审

一旦概要设计文档完成后,还要对概要设计进行评审,评审主要应集中在软件需求的可跟踪性(traceability)、程序结构质量、接口说明、数据结构描述、实现和测试的实用性(practicality),以及可维护性等方面。

6.如果需要和合算的化,对结构进行优化。

关于优化的问题,应贯穿在整个的设计过程中。

即,设计的每一步骤都要考虑结构设计的优化,特别是在设计的开始,就应该给出几个可选方案,并进行比较和修改,以便找出最好的方案。

如果完全放在最后来考虑,这时所花的代价就大了,甚至无法进行。

4.3Jackson设计方法

Jackson方法是最典型的面向数据结构的软件开发方法,Jackson方法把问题分解为可由三种基本结构形式表示的各部分的层次结构。

三种基本的结构形式就是顺序、选择和重复。

三种数据结构可以进行组合,形成复杂的结构体系。

这一方法从目标系统的输入、输出数据结构入手,导出程序框架结构,再补充其它细节,就可得到完整的程序结构图。

这一方法对输入、输出数据结构明确的中小型系统特别有效,如商业应用中的文件表格处理。

该方法也可与其它方法结合,用于模块的详细设计。

4.3.1面向数据结构的设计

和前一章介绍的面向数据流的设计方法不同,Jackson方法是面向数据结构的,Wirth有一个著名的公式:

“程序=算法+数据结构”,可见,在程序设计中算法和数据结构是紧密相连的,稍有程序设计经验的人就会有这样的体会不同的数据结构往往决定了不同的算法结构,也就是说在一定程度上数据结构决定了算法结构。

因此,只要事先弄清楚问题的数据结构,就可以由此导出解决问题的程序结构。

这就是面向数据结构的设计方法思想基础。

4.3.2表示数据结构的Jackson图

Jackson从问题的数据结构入手,给出了表示问题的数据结构的图形表示方法。

图4-15表示了用Jackson图表示的三种基本结构,由方框、连线和一些附加标记组成。

标记“0”代表选择,标记“*”代表重复。

连线可以理解为“包含”或“由……组成”。

图中,子图a表示A由B和C顺序组成,子图b表示A可以包含B或C(选择),子图c表示A由B重复若干次构成。

图4-15用Jackson图表示三种基本结构

3种基本结构可以组合,形成更复杂的结构体系,如图4-16所示。

这种数据结构图可以同样方便地应用于输入、输出和数据库结构。

图4-16用Jackson图表示复杂的结构

这里用一个信用卡记账的例子具体说明数据结构表示法。

信用卡记账系统的输入数据结构是两个实际的账册,它们对应的两个输入文件如图4-17所示。

图4-17信用卡记帐系统的输入

两个实际输入账册都按顾客号码进行登录,所以两个输入文件也是以顾客号码组织记录的。

在支付账册中,每个顾客号码行上要登记支付金额、支付日期。

在支付文件中的每个记录中也对应有支付金额(AMT)和支付日期(DATE)项,当然还有标识这个记录的顾客号码(CNO)项。

在支付账册中是按顾客号码进行排序的,顾客号码相同的支付记录在支付账册中排列在一起,构成关于该顾客的顾客号码组,在支付文件中也有与之对应的顾客号码组。

在顾客主账册中,每个顾客号码行上登记了顾客号码(CNO)和结余(BAL),显示某位顾客的支付能力。

与之对应的顾客主文件每个记录也有这两项。

两个输入文件中相应的内容是一致的。

图4-18(a)给出了信用卡记账系统的输出记账报告,在报告中隐含了一个“店方总计”结构。

报告中其他部分是顾客信息,因此,隐含了一个与“店方总计”相同层次的“顾客数据”子结构。

图4-18(b)表示根据输入和输出数据结构的对应关系建立的输出文件的结构。

图4-18信用卡记账系统的输出

4.3.3表示程序结构的Jackson图

图4-19从输出数据结构导出的程序结构

从层次性的输入和(或)输出数据结构可以直接推导出程序的过程性表示。

也就是那些在表示数据结构的Jackson图,其中的图形单元可以很方便的转化为表示程序结构的处理单元。

例如,从图4-18(b)所示的输出文件中的Jackson数据结构图所导出的程序结构如图4-19所示。

4.3.4Jackson伪代码

最后,利用Jackson图对应的3种伪代码来表示程序的执行逻辑。

这种伪代码类似于程序设计语言。

3种基本控制结构的伪代码如图4-20所示。

图4-203种基本控制结构的图解

在给出程序的过程性描述时,还需要添加一些必要的可执行操作。

例如,打开文件、读文件结束符、读表头数据项、读行数据项、打印符号行、打印数字行、关闭文件等。

把它们分配到程序结构的适当位置,以得到一个完整的过程性描述。

对于上例中“处理顾客数据”部分,给出过程性描述如下:

PROCESS_CUST_DATAseq

OpenPAYFILE:

openCUSTMFILE;{分别打开支付文件和顾客主文件}

PROCESS_CNO_GROPiteruntileof:

PAY_FILE;{处理顾客号码组}

ReadPAYFILE:

{读支付文件一个记录)

PROCESS_CNO;{读顾客主文件一个记

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1