模块化

Posted by serrini on February 18, 2020

单选

  • Receiver.message和MyType.doSomethingForMe方法数据耦合

  • 最好的内聚是功能内聚、信息内聚
    • 通信内聚:可接受无法避免,与步骤有关且这些操作都在相同的数据上进行
  • 最好的耦合是数据耦合

  • Process_customer_record与Calculate_sales_tax之间是数据耦合

  • valide_checkout——request和valid方法之间是控制耦合:一个模块给另一个模块传递控制信息

  • TightCoupling.showWelconMsg和TightCoupling2.TightCoupling2两个方法之间是控制耦合:GE不是实际的数据,是控制信号,所以是控制耦合,不是印记耦合,印记耦合是共享一个数据结构,但只用了其中一部分

  • Process_input_code与Choose_appropriate_Action方法之间是控制耦合

  • validate_checkout_request和valid_month 之间是印记耦合

  • WorkItem.notice与Emailer.sendEmail之间是印记耦合
Class Employee{
	private int id;
	private String name;
	private String email;
	//...
}
Class WorkItem{
	private Employee leader;
	private String description;
	private Emailer email;
	//...
	public notice(){
		//...
		email.sendEmail(leader,description);
		//...
	}
}
Class Emailer{
//Emailer只使用了Employee传递的部分数据,所以是印记耦合
	public void sendEmail(Emoloyee e,String text){
		EmailerService.send(e.getName(),e.getEmail(),text);
		}
	//...
}		
  • Log.notice与Email.sendEmail之间是数据耦合
Struct User{
	String name;
	String email;
}
Class Log{
	private User user;
	private Emailer email;
	//...
	public notice(){
		//...
		email.sendEmail(user,message);
		//...
	}
}
Class Emailer{
	public void sendEmail(user a, String text){
		EmailerService.send(u.name,u.email,text);
		}
	//...
}
  • 印记耦合:传递的数值是三个数据,只用了两个

  • 印记耦合:传递的list中,topTen只使用了前十个,其他都是多余数据,所以是印记耦合

  • 公共耦合:不能接受,模块之间共享全局变量,这两个方法之间共享了数据checkout_data

  • 公共耦合:两个方法共享了x变量,所以是公共耦合

  • 公共耦合:共享了sales_tax变量

  • 公共耦合:两个方法公共使用了同一个文件customer record

  • 公共耦合:**两个类共享了同一个变量todaysDow **

  • 内容耦合:Arch.slant访问了Vector3D的内部的xy,所以是内容耦合

  • 内容耦合:一个类中的方法访问另一个类的内部

  • 内容耦合:SneekyModifier访问了Person的内部成员变量,所以是内容耦合

  • 内部类访问外部类的成员变量,是内容耦合。内部类一般都与外部类构成内容耦合,但是是一种受限和特殊标记的内容耦合

  • 功能内聚的要求是一个模块只能有一个目标

  • 通信内聚是可接受无法避免的,操作与步骤有关,且这些操作都在相同的数据上进行

  • 计算total_purchases,再基于total_purchases计算sales_tax,再基于total_purchases和sales_tax计算amount_due,构成了明显的问题解决过程,所以是过程内聚。同时几个行为都使用了total_purchases,这种使用相同数据的行为是通信内聚即是过程又是通信的,所以是顺序内聚

  • 功能内聚

  • 两种目的构成了处理的先后顺序,是过程内聚

  • 再同一时间(初始化时)执行了多个不同目的的活动,是时间内聚

  • 逻辑内聚基于switch对参数的判定执行不同的功能路径是典型的逻辑内聚,这些不同路径之间是完全不同的事情,他们之前只是相似而已

Read_all_files(file_code)
	switch(file_code)
	case 1:
	case 2:
	case 3:
	ENDSWITCH
END
  • 整个方法只有一个目标为功能内聚

  • 通信内聚:都是为了处理error_flag、error_massage和error_report,所以是相同的数据,属于通信内聚

  • 三个职责都使用相关的数据connection,所以是通信内聚。行为包括,获得get和释放release connection;得到connection的统计数据、持久化使用数据(requested、released)

  • 过程内聚:该方法是典型的过程三段式:初始化、数据处理、输出(打印)

  • 逻辑内聚:从代码上看,sample是把逻辑相似但目的不同的多个片段组合在了一起,然后通过flag选择实际的执行路径。典型的逻辑内聚

  • 偶然内聚:电梯类如下,行为之间没有明显的绑定因素。

  • 偶然内聚;顾客的四个行为:租借、付费、建立界面编辑顾客信息、保持数据

  • utils、tools等公用代码库往往是偶然内聚的,他们可能就是把多个独立函数封装在一起而已,这些函数之间没有什么联系

多选题

  • 偶然内聚和逻辑内聚是非常不理想的,应该避免使用
  • 方法Method、包Package、类Class都可以被看作是模块化中的模块,从而适用高内聚、低耦合设计思路。模块是代码段,包、类和方法都包含了一个代码段,语句块虽然也包括了代码段,但语句块是基于控制结构的,不适用内聚耦合思想。界面、数据库、网络节点等都不表现为代码段,所以不能算是模块。
  • 哪些联系会产生耦合
    • 类A继承B
    • 类A访问B的成员变量
    • 类A包含B
    • 方法f调用方法q
    • 方法f和方法q访问同一个公共数据
  • 类A和类B都包含类C不产生耦合、方法f和方法q调用同一个方法m不产生耦合
  • 高内聚低耦合的模块化方法是为了易修改、易理解、易复用
  • 模块化追求的效果是
    • 理解一个模块非常简单、清晰
    • 一个模块显而易见的正确
    • 修改一个模块不会对外产生连锁反应
  • 模块性能优异、可靠性高;模块是黑盒、安全性高不是模块化追求的效果

判断题

  • 模块化的本质是如何高质量的把一段复杂代码分割成多个简单片段
  • 内聚服从于耦合,高内聚是为了实现低耦合
  • 耦合是指两个模块之间存在着连接,体现为底层命令的指令地址转换、数据标识访问等
  • 时间内聚基于相同的时间,过程内聚基于相同的问题,通信内聚基于相同的数据,所以他们之间的内聚强度没有本质上的差别,都是可以接受的
  • 功能分解的方式能够提升内聚,但并不一定能降低耦合。高内聚要从属于低耦合,低耦合才是设计的第一准则,所以按照功能分解并不是最佳的设计方式
  • 区分控制耦合和数据耦合的关键是区分数据和控制信号。数据是有实际意义的信息,控制信号是人为设置的标记。
  • flag标志是控制信号,但只有控制信号影响了被调用者执行路径分支选择的情况下,才是控制耦合。如果q只是简单加工flag标志,没有因为flag影响执行路径,就不构成控制耦合。
  • 公共耦合是指共享了相同的外部环境,包括数据、文件、设备等,但第三方模块不属于公共环境。