内聚标志一个模块内各个元素彼此结合的紧密程度,它是信息隐藏和局部化概念的自然扩展。
低内聚:
(1)偶然内聚:如果一个模块完成一组任务,这些任务彼此间即使有关系,关系也是很松散 的,这就叫做偶然内聚;
(2)逻辑内聚:如果一个模块完成的任务在逻辑上属于相同或相似的一类(例如,一个模块产生各种类型的全部输出),称为逻辑模块;
(3)时间内聚:一个模块包含的任务必须在同一段时间内执行(例如,模块完成各种初始化工作),就叫时间内聚。
中内聚:
(1)过程内聚:如果一个模块内的处理元素是相关的,而且必须以特定次序执行,则称为过程内聚;
(2)通信内聚:如果模块中所有元素都使用同一个输入数据和(或)产生同一个输出数据,则称为通信内聚。
高内聚:
(1)顺序内聚:如果一个模块内的处理元素和同一个功能密切相关,而且这些处理必须顺序执行(通常一个处理元素的输出数据作为下一个处理元素的输入数据),则称为顺序内聚。根据数据流图划分模块时,通常得到顺序内聚的模块,这种模块彼此间的连接往往比较简单。
(2)功能内聚:如果模块内所有处理元素属于一个整体,完成一个单一的功能,则称为功能内聚。功能内聚是最高程度的内聚。
-
C++ has-a关系使用包含还是私有继承
2020-03-26 17:53:16举个例子,学生与(学生姓名、考试成绩)的关系就是has-a关系而不是is-a关系,学生不是姓名,也不是一组考试成绩,学生有姓名,也有一组考试成绩 包含 通常,用于建立has-a关系的C++技术是组合(包含),即创建一个...has-a关系
举个例子,学生与(学生姓名、考试成绩)的关系就是has-a关系而不是is-a关系,学生不是姓名,也不是一组考试成绩,学生有姓名,也有一组考试成绩
包含
通常,用于建立has-a关系的C++技术是组合(包含),即创建一个包含其他类对象的类。例如,可以将Student类声明为如下所示:
class Student{ private: string name; // use a string object for name valarray<double> scores; // use a valarray<double> object for scores ... public: double sum() const; };
在派生类中,可以直接通过基类对象来调用基类的方法
double Student::sum() const { return scores.sum(); }
私有继承
C++还有另一种实现has-a关系的途径——私有继承。使用私有继承,基类的公有成员和保护成员都将成为派生类的私有成员。这意味着基类方法将不会成为派生对象公有接口的一部分,但可以在派生类的成员函数中使用它们。
使用私有继承,类将继承实现。例如,如果从string类派生出Student类,后者将有一个string类组件,可用于保存字符串。另外,Student方法可以使用string方法来访问string组件。
包含将对象作为一个命名的成员对象添加到类中,而私有继承将对象作为一个未被命名的继承对象添加到类中。因此私有继承提供的特性与包含相同:获得实现,但不获得接口。所以,私有继承也可以用来实现has-a关系
class Student : private std::string, private std::vallarray<double> { public: double average() const; ... };
在派生类中,可以使用类名和作用域解析运算符来调用基类的方法
double Student::average() const { if(vallarray<double>::size() > 0) return vallarray<double>::sum() / vallarray<double>::size(); else return 0; }
如何选择
由于既可以使用包含,也可以使用私有继承来建立has-a关系,那么应使用哪种方式呢?大多数C++程序员倾向于使用包含。首先,它易于理解。类声明中包含表示被包含类的显示命名对象,代码可以通过名称引用这些对象,而使用继承将使关系更抽象。其次,继承会引起很多问题,尤其从多个基类继承时,可能必须处理很多问题,如包含同名方法的独立的基类或共享祖先的独立基类。总之,使用包含不太可能遇到这样的麻烦。另外,包含能够包括多个同类的子对象。如果某个类需要3个string对象,可以使用包含关系声明3个独立的string成员。而继承则只能使用一个这样的对象(当对象都没有名称时,难以区分)
然而,私有继承所提供的特性确实比包含多。例如,假设类包含保护对象(可以是数据成员,也可以是成员函数),则这样的成员在派生类中是可用的,但在继承层次结构外是不可用的。如果使用组合将这样的类包含在另一个类中,则后者将不是派生类,而是位于继承层次结构之外,因此不能访问保护成员。但通过继承得到的将是派生类,因此它能够访问保护成员。
另一种需要使用私有继承的情况是需要重新定义虚函数。派生类可以重新定义虚函数,但包含类不能。使用私有继承,重新定义的函数将只能在类中使用,而不是公有的。
总结
通常,应使用包含来建立has-a关系;如果新类需要访问原有类的保护成员,或需要重新定义虚函数,则应使用私有继承
-
5.2为每种类型的模块内聚举一个例子
2019-10-04 15:55:32低内聚:(1)偶然内聚:如果一个模块完成一组任务,这些任务彼此间即使有关系,关系也是很松散 的,这就叫做偶然内聚;(2)逻辑内聚:如果一个模块完成的任务在逻辑上属于相同或相似的一类(例如,一个模块产生...转载于:https://www.cnblogs.com/tt10/p/5384483.html
-
过滤掉list中被其他元素所包含的元素
2020-12-30 11:05:10举个例子: 输入list a=['我是卖麻辣烫的小男孩', '小男孩', '麻辣烫', '华中科技大学','大学'],希望返回的结果是['我是卖麻辣烫的小男孩', '华中科技大学'] 解法 由于长字符串不可能被短字符串所包含,即长字符串...背景
有一个list,其中的元素存在之间相互包含的关系,即元素A可能是原始B的子串。举个例子:
输入lista=['我是卖麻辣烫的小男孩', '小男孩', '麻辣烫', '华中科技大学','大学']
,希望返回的结果是['我是卖麻辣烫的小男孩', '华中科技大学']
解法
由于长字符串不可能被短字符串所包含,即长字符串不可能是短字符串的子串,那么只需要按照字符串长度降序排序,并设立一个新的list(比如
new_a
),从长->短,依次判断排序后的字符串是否是new_a
中元素的子串。
具体代码:def get_max_len_string(input_list): input_list.sort(key=lambda x: len(x), reverse=True)#降序排序,因为最长的字符串是不可能是其他字符串的子串 out, filter_list = [], [] for s in input_list: mask_list = [s in o for o in out] if not any(mask_list):#any函数全部为false才返回false out.append(s) else: # 记录是因为那个元素的存在导致被过滤 been_contained_index = mask_list.index(True) large_word = out[been_contained_index] filter_list.append(s) return out, filter_list a = ['我是卖麻辣烫的小男孩', '小男孩', '麻辣烫', '华中科技大学', '大学'] new_a = get_max_len_string(a) print("new list=", new_a[0]) print("abandoned elements=", new_a[1])
运行结果:
new list= ['我是卖麻辣烫的小男孩', '华中科技大学'] abandoned elements= ['小男孩', '麻辣烫', '大学']
-
UML关系
2013-12-10 11:28:22举个网上流行的例子:比如你从1楼要去5楼,那爬楼梯是必须的,则爬楼梯是"包含关系",如果你上到2楼时,顺便去了趟卫生间,则去卫生间是"扩展关系"。 包含关系:使用包含(Inclusion)用例来封装一组跨越多个用例...形象说明UML中的包含与扩展的区别
举个网上流行的例子:比如你从1楼要去5楼,那爬楼梯是必须的,则爬楼梯是"包含关系",如果你上到2楼时,顺便去了趟卫生间,则去卫生间是"扩展关系"。
包含关系:使用包含(Inclusion)用例来封装一组跨越多个用例的相似动作(行为片断),以便多个基(Base)用例复用。基用例控制与包含用例的 关系,以及被包含用例的事件流是否会插入到基用例的事件流中。基用例可以依赖包含用例执行的结果,但是双方都不能访问对方的属性。
包含关系对典型的应用就是复用,也就是定义中说的情景。但是有时当某用例的事件流过于复杂时,为了简化用例的描述,我们也可以把某一段事件流抽象成为一个被包含的用例;相反,用例划分太细时,也可以抽象出一个基用例,来包含这些细颗粒的用例。这种情况类似于在过程设计语言中,将程序的某一段算法封装成一个子过程,然后再从主程序中调用这一子过程。例如:业务中,总是存在着维护某某信息的功能,如果将它作为一个用例,那新建、编辑以及修改都要在用例详述中描述,过于复杂;如果分成新建用例、编辑用例和删除用例,则划分太细。这时包含关系可以用来理清关系。
2、扩展(extend)
扩展关系:将基用例中一段相对独立并且可选的动作,用扩展(Extension)用例加以封装,再让它从基用例中声明的扩展点(Extension Point)上进行扩展,从而使基用例行为更简练和目标更集中。扩展用例为基用例添加新的行为。扩展用例可以访问基用例的属性,因此它能根据基用例中扩展 点的当前状态来判断是否执行自己。但是扩展用例对基用例不可见。
对于一个扩展用例,可以在基用例上有几个扩展点。
例如,系统中允许用户对查询的结果进行导出、打印。对于查询而言,能不能导出、打印查询都是一样的,导出、打印是不可见的。导入、打印和查询相对独立,而且为查询添加了新行为。因此可以采用扩展关系来描述:类与类之间存在以下关系:
(1)泛化(Generalization)
(2)关联(Association)
(3)依赖(Dependency)
(4)聚合(Aggregation)UML图与应用代码例子:
1.泛化(Generalization)
[泛化]
表示类与类之间的继承关系,接口与接口之间的继承关系,或类对接口的实现关系。一般化的关系是从子类指向父类的,与继承或实现的方法相反。
[具体表现]
父类 父类实例=new 子类()
[UML图](图1.1)
图1.1 Animal类与Tiger类,Dog类的泛化关系
[代码表现]- class Animal{}
- class Tiger extends Animal{}
- public class Test
- {
- public void test()
- {
- Animal a=new Tiger();
- }
- }
2.依赖(Dependency)
[依赖]
对于两个相对独立的对象,当一个对象负责构造另一个对象的实例,或者依赖另一个对象的服务时,这两个对象之间主要体现为依赖关系。
[具体表现]
依赖关系表现在局部变量,方法的参数,以及对静态方法的调用
[现实例子]
比如说你要去拧螺丝,你是不是要借助(也就是依赖)螺丝刀(Screwdriver)来帮助你完成拧螺丝(screw)的工作
[UML表现](图1.2)图1.2 Person类与Screwdriver类的依赖关系
[代码表现]- public class Person{
- /** 拧螺丝 */
- public void screw(Screwdriver screwdriver){
- screwdriver.screw();
- }
- }
3.关联(Association)
[关联]
对于两个相对独立的对象,当一个对象的实例与另一个对象的一些特定实例存在固定的对应关系时,这两个对象之间为关联关系。
[具体表现]
关联关系是使用实例变量来实现
[现实例子]
比如客户和订单,每个订单对应特定的客户,每个客户对应一些特定的订单;再例如公司和员工,每个公司对应一些特定的员工,每个员工对应一特定的公司
[UML图] (图1.3)
图1.3 公司和员工的关联关系
[代码表现]- public class Company{
- private Employee employee;
- public Employee getEmployee(){
- return employee;
- }
- public void setEmployee(Employee employee){
- this.employee=employee;
- }
- //公司运作
- public void run(){
- employee.startWorking();
- }
- }
[聚合]
当对象A被加入到对象B中,成为对象B的组成部分时,对象B和对象A之间为聚集关系。聚合是关联关系的一种,是较强的关联关系,强调的是整体与部分之间的关系。
[具体表现]
与关联关系一样,聚合关系也是通过实例变量来实现这样关系的。关联关系和聚合关系来语法上是没办法区分的,从语义上才能更好的区分两者的区别。
[关联与聚合的区别]
(1)关联关系所涉及的两个对象是处在同一个层次上的。比如人和自行车就是一种关联关系,而不是聚合关系,因为人不是由自行车组成的。
聚合关系涉及的两个对象处于不平等的层次上,一个代表整体,一个代表部分。比如电脑和它的显示器、键盘、主板以及内存就是聚集关系,因为主板是电脑的组成部分。
(2) 对于具有聚集关系(尤其是强聚集关系)的两个对象,整体对象会制约它的组成对象的生命周期。部分类的对象不能单独存在,它的生命周期依赖于整体类的对象的 生命周期,当整体消失,部分也就随之消失。比如张三的电脑被偷了,那么电脑的所有组件也不存在了,除非张三事先把一些电脑的组件(比如硬盘和内存)拆了下 来。
[UML图](图1.4)
图1.3 电脑和组件的聚合关系
[代码表现]- public class Computer{
- private CPU cpu;
- public CPU getCPU(){
- return cpu;
- }
- public void setCPU(CPU cpu){
- this.cpu=cpu;
- }
- //开启电脑
- public void start(){
- //cpu运作
- cpu.run();
- }
- }
-
头文件路径包含问题
2018-06-20 10:14:15头文件包含两种,系统头文件和自定义头文件,系统头文件不说了,格式统一,自定义头文件在包含的时候要注意路径,其实是头文件与主文件的相对位置关系的问题。ps:另外,LInux和Windows下也有所区别。举4个例子,... -
类图 关系
2018-11-19 13:17:57在这里不得不说一句维基百科是真的六,对类图的介绍真是好,举得例子更好 关系 ...聚合(Aggregate),弱包含关系,例如,池塘与(池塘中的)鸭子。再例如教授与课程,又例如图书馆包含(owns a... -
自定义头文件路径包含问题
2019-03-21 19:19:48头文件包含两种,系统头文件和自定义头文件,系统头文件不说了,格式...举4个例子,应该就能看明白了。 一. 这种情况下,在main.c中包含头文件如下: #include “fish.h” 或 #include “./fish.h” (Linux) or #... -
头文件相互包含引起的错误(对类前置声明和包含头文件的理解 )
2013-01-07 21:01:53类的前置声明(forward declaration)和包含头文件(#include)的区别常常会迷惑我们,特别...所谓互相包含头文件,我举一个例子:我实现了两个类:图层类CLayer和符号类CSymbol,它们的大致关系是图层里包含有符号,符 -
类前置声明和头文件包含
2014-03-18 19:18:03类的前置声明(forward declaration)和包含头文件(#include)的区别常常会...所谓互相包含头文件,我举一个例子:图层类CLayer和符号类CSymbol,它们的大致关系是图层里包含有符号,符号里定义一个相关图层指针,具 -
对类前置声明和包含头文件的一点理解
2014-09-26 22:22:33转自 类的前置声明(forward declaration)和包含头文件(#include)的区别常常会迷惑我们...所谓互相包含头文件,我举一个例子:我实现了两个类:图层类CLayer和符号类CSymbol,它们的大致关系是图层里包含有符 -
形象说明UML中的包含与扩展的区别(转)
2012-12-06 14:13:12举个网上流行的例子:比如你从1楼要去5楼,那爬楼梯是必须的,则爬楼梯是"包含关系",如果你上到2楼时,顺便去了趟卫生间,则去卫生间是"扩展关系"。 另外转载一篇网上摘录的关于UML中关联,泛化和依赖关系比较说明。... -
对类前置声明和包含头文件的一点理解(类的交叉引用)
2014-09-17 05:08:27类的前置声明(forward declaration)和包含头文件(#include)的区别常常会迷惑我们...所谓互相包含头文件,我举一个例子:我实现了两个类:图层类CLayer和符号类CSymbol,它们的大致关系是图层里包含有符号,符号里定 -
c++中两个类的头文件互相包含编译出错的解决办法
2014-07-14 17:15:59所谓互相包含头文件,我举一个例子:我实现了两个类:图层类CLayer和符号类CSymbol,它们的大致关系是图层里包含有符号,符号里定义一个相关图层指针,具体请参考如下代码(注:以下代码仅供说明问题,不作为类设计... -
anaconda python 版本对应关系
2019-10-14 15:00:36首先解释一下上表。 anaconda在每次发布新版本的时候都会给python3和...举个例子,假设你想安装python2.7.14,在表格中找到它,它下方的三个anaconda包(anaconda2-5.0.1、5.1.0、5.2.0)都包含python2.7.14; ... -
C#里DataSet、DataTable、DataRow的差别和关系,用DataSet、DataTable、DataRow保存查询数据
2019-08-05 15:20:22DataSet、DataTable、DataRow的关系是包含(或着说父子)关系。 举个例子: DataSet 相当于一个数据库; DataTable 相当于一张表; DataRow 相当于一条表里的数据。 写个例子说明一下它们是怎么用的,有什么... -
python与anaconda的版本关系_Anaconda与Python安装版本对应关系 --- 转载
2021-01-14 04:58:11anaconda在每次发布新版本的时候都会给python3和python2都发布一个包,版本号是一样的。表格中,python版本号下方的离它最近的anaconda包就是包含...举个例子,假设你想安装python2.7.14,在表格中找到它,它下方的... -
dll和lib关系及使用
2017-12-01 11:33:00对于dll和lib两者的关系,需要理解的一个概念是编译时和运行时。 lib是编译时的东西,在lib里面包含了方法名和方法所在的dll名字,可以用dumpbin -all XXX.lib...举个例子方便理解: 有两个project,A和B,... -
Anaconda python 版本对应关系
2019-03-06 17:58:14首先解释一下上表。 anaconda在每次发布新版本的时候都会给python3和python2都发布一个包,版本号是一样的。 表格中,python版本号下方的离它最近的anaconda包就是包含它...举个例子,假设你想安装python2.7.14,在... -
【Maven+SSM】Mybatis多表查询或一对多关系的配置
2017-11-16 17:38:33【Maven+SSM】Mybatis多表查询或一对多关系的配置一、举个例子新建两个表:主表,包含书籍id,书名,作者子表:书籍id,书籍内容,真实id(主键自增)两张表的关系显而易见,1对多,左链接关系。SELECT a.idbook, ... -
Anaconda Python 版本对应关系表(附所有版本下载)
2019-06-05 09:33:49一、对应版本 首先解释一下上表。 anaconda在每次发布新版本的时候都会给...举个例子,假设你想安装python2.7.14,在表格中找到它,它下方的三个anaconda包(anaconda2-5.0.1、5.1.0、5.2.0)都包含python2.7.... -
C++ Primer Plus读书笔记—— 13.2 继承:is-a关系
2020-08-26 23:04:19举个例子,苹果是一种水果。 has-a 如果说一种对象包含了一整个其他的对象,或者说一种对象由其他几种对象组成。 这个时候并不适合用继承(派生)来表达这种关系,而是适合使用组合。 也就是说,应该将这种对象作为... -
css里面包含选择符与子对像选择符">"的区别
2010-09-07 10:48:00举个例子:<div> <ul> <li> </li> </ul><div>要定义li的样式,用包含选择符,你写成:div li{...}没有问题若用子选择符,你只能写成:ul> li{...}不能写成div> li{...}... -
socket和tcpip关系,再解析socket函数
2016-09-07 08:15:22书本《图解TCP/IP》 详细阅读概述的tcpip协议,偶尔想到了我们编写程序时使用到的socket.h文件,我们正是使用它来实现tcpip通信的。 那么问题来了,socket到底跟tcpip有什么关系呢?...举个例子:建立socket通 -
Hibernate学习笔记(三)——Hibernate的关联关系映射
2016-09-24 20:27:55在数据库中存在四种关联关系映射,分别是一对一(one-to-one)、一对多(one-to-many)、多对一(many-to-one)和多对多(many-to-many),...举个例子,就好比班级和学生,站在班级的角度来看,一个班级包含多个学生 -
数据库系统概论-----专门关系运算---除运算
2020-04-06 17:43:01上一周学了除运算,书上的定义乍一看完全懵,必须要好好分析一下才能理解。本弱鸡正在进步,下面就来分享一下自己的见解。...举个例子: 给出了R和S,按照定义,T中只包含属性A和属性A的值。A可以取{a1,a2,a3... -
数据源,连接池,数据库连接之间的关系
2017-06-12 17:27:11关于这个问题,我们首先要弄清楚数据库软件mysql(sql server也行举个例子)和其里面的一个具体的数据库实例之间的区别和关系。 mysql即我们平常所说的数据库软件,在这个软件里可以创建很多个数据库实例,...
-
leetcode 203. 移除链表元素
-
美图大数据平台架构实践
-
基于杜鹃搜索的磷虾群算法解决工程优化问题
-
如何利用python做一个简单的天气预报
-
2021-02-25
-
Mac启动Eclipse提示Failed to create the Java Virtual Machine
-
867. 转置矩阵(遍历原矩阵 超简单!!)
-
电影记录-源码
-
ApacheFlink漫谈系列-概述
-
自动释放数据库句柄和结果集(RAII机制)
-
UE4吃鸡模拟器FPS逆向安全开发
-
gdbinit
-
Mycat 实现 MySQL的分库分表、读写分离、主从切换
-
从理论到试验台,WiFi DCF网络的性能评估
-
[CCF-CSP] 201604-1 折点计数
-
在 Linux 上构建企业级 DNS 域名解析服务
-
MMM 集群部署实现 MySQL 高可用和读写分离
-
Samba 服务配置与管理
-
vue的生命周期
-
金三银四,冰河为你整理了这份20万字134页的面试圣经!!