1. 内聚和耦合举例
内聚和耦合是衡量模块独立性的两种标准。
内聚——衡量一个模块内部各元素之间的关系;耦合——衡量模块间的关系。
1.1 内聚类型
1) 功能内聚:一个模块只完成一个单一功能。例:用户权限模块,该模块只负责与权限相关的实现。
2) 分层内聚:分层实现,上层能访问底层,底层不可访问上层。例:业务逻辑层能访问数据库实现层,反之不可。
3) 通信内聚:访问相同数据的操作集中放到一个类或模块中实现。例:对数据库中某个表的增删改查定义在一个类中实现。
4) 顺序内聚:模块内的处理按照顺序执行,且前者的输出做为后者的输入。例:将一个集合内的元素按指定规则排序,然后将排序后的集合输出。
5) 过程内聚:模块内部的处理按照顺序执行,前者与后者之间没有数据传递。例:先校验参数的合法性,校验通过后将参数在控制台输出。
6) 暂时内聚:模块内的操作是为了完成某一特定要求或状态。
7) 实用内聚:模块各部分之间没有联系或联系松散。例:一个处理字符串的工具类。
内聚举例: 参见EmployeeManager类中的各个方法
通信内聚: getEmployeeAge(Date birthDate)与isEmployeeRetired(Date birthDate)间存在通信内聚。
public class EmployeeManager {
// 功能内聚
private int getEmployeeAge(Date birthDate) {
int employeeAge = 0;
// TODO: 用当前日期计算与出生日期计算员工年龄
return employeeAge;
}
// 功能内聚
private boolean isEmployeeRetired(Date birthDate) {
int employeeAge = getEmployeeAge(birthDate);
if (employeeAge > 60) {
return true;
} else {
return false;
}
}
// 顺序内聚
private boolean isEmployeeRetired(Date birthDate) {
int employeeAge = 0;
// TODO: 用当前日期计算与出生日期计算员工年龄
if (employeeAge > 60) {
return true;
} else {
return false;
}
}
// 逻辑内聚
private void printEmployeeSalary(int flag, int daySalary) {
int monthSalary = daySalary * 30;
int yearSalary = monthSalary * 12;
switch (flag) {
case 0:
// 打印日工资;
System.out.println(daySalary);
case 1:
// 打印月工资;
System.out.println(monthSalary);
case 2:
// 打印年工资;
System.out.println(yearSalary);
default:
// 打印月工资;
System.out.println(monthSalary);
}
}
// 过程内聚, 暂时内聚
private void printEmployeeInfo(Employee employee){
String name = employee.getName();
String sex = employee.getSex();
String address = employee.getAddress();
StringBulider printInfo = new StringBuilder();
printInfo.append("雇员的个人信息————");
printInfo.append("姓名:");
printInfo.append(name);
printInfo.append(" | 性别:");
printInfo.append(sex);
printInfo.append(" | 地址:");
printInfo.append(address);
System.out.println(printInfo.toString());
}
}
1.2 耦合类型
1) 内容耦合:类Employee与TestB间存在内容耦合
public class Employee {
// 雇员当前年龄
public int curAge ;
// 雇员还有多少年退休
public int retireYear;
}
public class TestB {
private void printEmployeeInfo(){
Employee employeeA = new Employee();
employeeA.curAge = 20;
employeeA.retireYear = 65 - employeeA.curAge;
System.out.println("employeeA curAge is ", employeeA.curAge);
System.out.println("employeeA retireYear is ", employeeA.retireYear);
}
}
2) 共用耦合:类ScoreUtil与TestA间存在共用耦合
public class ScoreUtil {
public static int MinScore = 60;
public static int getAvgScore(int score1, int score2){
int sumScore = score1 + score2;
return sumScore/2;
}
}
public class TestA {
private void printScoreLevel(){
int score1 = 50;
int score2 = 100;
int avgScore = ScoreUtil.getAvgScore(score1, score2);
if(avgScore>ScoreUtil.MinScore){
System.out.println("Score is higher than min score.");
}else{
System.out.println("Score is lower than min score.");
}
}
}
3) 控制耦合:类ScoreUtil与TestA间存在控制耦合
public class ScoreUtil {
public static int getScore(boolean isGetAvg){
int score = 0;
if(isGetAvg){
//TODO get avg score
}else{
//TODO get max score }
return score;
}
}
public class TestA {
private int getAvgScore(){
return ScoreUtil.getScore(true);
}
}
4) 数据耦合:类ScoreUtil与TestA间存在数据耦合
public class ScoreUtil {
public static int getAvgScore(int score1, int score2){
int sumScore = score1 + score2;
return sumScore/2;
}
}
public class TestA {
private void printAvgScore(){
int score1 = 50;
int score2 = 100;
System.out.println(ScoreUtil.getAvgScore(score1, score2));
}
}
5) 印记耦合:printStudentNames和printStudentAvgAge之间存在印记耦合
import java.util.List;
public class TestB {
private void printStudentNames(List<Student> students){
for(Student student: students){
System.out.println(student.getName());
}
}
private void printStudentAvgAge(List<Student> students){
int totalAge = 0;
for(Student student: students){
totalAge = totalAge + student.getAge();
}
System.out.println(totalAge/students.size());
}
}
6) 类型使用耦合: 印记耦合的例子中的TestB类与Student类存在类型调用耦合
7) 例程调用耦合: 印记耦合的例子中的TestB类中的printStudentNames()调用了Student类中的getName(),存在例程调用耦合。
8) 包含/导入耦合:印记耦合的例子中的TestB类中引入了java.util.List。
9) 外部耦合:main方法与getStudentAvgScore方法,printAvgScore方法存在外部耦合
public class Test {
public static void main(String[] args) {
int avgScore = getStudentAvgScore();
printAvgScore(avgScore);
}
private static int getStudentAvgScore(){
int avgScore = 0;
//TODO
return avgScore;
}
private static void printAvgScore(int avgScore){
}
}
2. 进度条列示
2.1 代码行数累积线段图
2.2 博客字数累积线段图
3. PSP
job | type | date | start | end | total(min) |
写随笔 | 随笔 | 2016.4.20 | 12:30 | 13:15 | 45 |
添加耦合例子 | 随笔 | 2016.4.21 | 21:30 | 22:51 | 81 |
添加聚合例子,进度条,博客字数累积线段图 | 随笔 | 2016.4.22 | 12:00 | 13:02 | 62 |
4. 工作量表
代码行数 | 博客字数 | 知识点 | |
第七周 | 0 | 1380 | β发布
|