结构化设计(耦合)

1. 非直接耦合
  • 定义:两个模块之间没有直接的联系,它们分别从属于不同的上层模块控制与调用。
  • 示例:在一个电商系统中,用户管理模块负责处理用户的注册、登录等操作,而商品库存管理模块负责管理商品的库存数量。这两个模块分别由不同的业务逻辑模块调用,它们之间没有直接的交互。
    class UserManagement {
        public void manageUser() {
            System.out.println("正在进行用户管理操作");
        }
    }
    
    class ProductInventoryManagement {
        public void manageInventory() {
            System.out.println("正在进行商品库存管理操作");
        }
    }
    
    class Main {
        public static void main(String[] args) {
            UserManagement userManagement = new UserManagement();
            ProductInventoryManagement productInventoryManagement = new ProductInventoryManagement();
    
            userManagement.manageUser();
            productInventoryManagement.manageInventory();
        }
    }

在上述代码里,UserManagement 和 ProductInventoryManagement 这两个类之间没有直接交互,它们分别执行各自的功能。

2. 数据耦合
  • 定义:模块间通过传递简单的数据参数来交换信息。
  • 示例:在一个简单的数学计算程序中,有一个模块负责读取用户输入的两个整数,另一个模块负责计算这两个整数的和。读取模块将两个整数作为参数传递给计算模块,计算模块返回计算结果。
    class InputReader {
        public int[] readNumbers() {
            java.util.Scanner scanner = new java.util.Scanner(System.in);
            System.out.print("请输入第一个整数: ");
            int num1 = scanner.nextInt();
            System.out.print("请输入第二个整数: ");
            int num2 = scanner.nextInt();
            return new int[]{num1, num2};
        }
    }
    
    class Calculator {
        public int calculateSum(int num1, int num2) {
            return num1 + num2;
        }
    }
    
    class Main {
        public static void main(String[] args) {
            InputReader inputReader = new InputReader();
            Calculator calculator = new Calculator();
    
            int[] numbers = inputReader.readNumbers();
            int result = calculator.calculateSum(numbers[0], numbers[1]);
            System.out.println("两数之和为: " + result);
        }
    }

此代码中,InputReader 类读取用户输入的两个整数,Calculator 类接收这两个整数并计算它们的和。 

3. 标记耦合
  • 定义:模块间传递的是数据结构,接收模块需要了解该数据结构的具体内容。
  • 示例:在一个学生信息管理系统中,有一个模块负责收集学生的基本信息(如姓名、年龄、学号等)并封装成一个字典,另一个模块负责将这些信息保存到数据库中。
    import java.util.HashMap;
    import java.util.Map;
    
    class StudentInfoCollector {
        public Map collectStudentInfo() {
            java.util.Scanner scanner = new java.util.Scanner(System.in);
            Map student = new HashMap<>();
            System.out.print("请输入学生姓名: ");
            student.put("name", scanner.nextLine());
            System.out.print("请输入学生年龄: ");
            student.put("age", scanner.nextInt());
            scanner.nextLine(); // 消耗换行符
            System.out.print("请输入学生学号: ");
            student.put("student_id", scanner.nextLine());
            return student;
        }
    }
    
    class StudentInfoSaver {
        public void saveStudentInfo(Map student) {
            System.out.println("将学生 " + student.get("name") + " 的信息保存到数据库中...");
        }
    }
    
    class Main {
        public static void main(String[] args) {
            StudentInfoCollector collector = new StudentInfoCollector();
            StudentInfoSaver saver = new StudentInfoSaver();
    
            Map studentInfo = collector.collectStudentInfo();
            saver.saveStudentInfo(studentInfo);
        }
    }

这里,StudentInfoCollector 类收集学生信息并封装成 MapStudentInfoSaver 类接收该 Map 并处理信息。

4. 控制耦合
  • 定义:一个模块向另一个模块传递控制信息,影响另一个模块的执行逻辑。
  • 示例:在一个游戏系统中,有一个主控制模块和一个角色移动模块。主控制模块根据用户的输入(如按下方向键)向角色移动模块传递控制信息(如向左移动、向右移动等),角色移动模块根据这些信息来控制角色的移动方向。
    import java.util.Scanner;
    
    class MainControl {
        public String getDirection() {
            Scanner scanner = new Scanner(System.in);
            System.out.print("请输入移动方向 (左/右): ");
            return scanner.nextLine();
        }
    }
    
    class CharacterMove {
        public void move(String direction) {
            if ("左".equals(direction)) {
                System.out.println("角色向左移动");
            } else if ("右".equals(direction)) {
                System.out.println("角色向右移动");
            } else {
                System.out.println("无效的移动方向");
            }
        }
    }
    
    class Main {
        public static void main(String[] args) {
            MainControl mainControl = new MainControl();
            CharacterMove characterMove = new CharacterMove();
    
            String direction = mainControl.getDirection();
            characterMove.move(direction);
        }
    }

在这个例子中,MainControl 类获取用户输入的移动方向,CharacterMove 类根据该方向控制角色移动。

5. 外部耦合
  • 定义:模块间通过软件之外的环境(如 I/O 设备、共享的通信协议等)进行交互。
  • 示例:在一个网络通信系统中,两个模块分别负责数据的发送和接收,它们通过网络协议(如 TCP/IP)进行通信。发送模块将数据按照协议格式封装后通过网络发送出去,接收模块按照相同的协议格式解析接收到的数据。
6. 公共耦合
  • 定义:多个模块访问同一个公共数据环境,如全局变量、共享的内存区域等。
  • 示例:在一个多模块的财务系统中,多个模块都需要访问一个全局的税率变量来进行财务计算。
    class TaxCalculator {
        // 公共税率变量
        public static final double TAX_RATE = 0.1;
    
        public static double calculateTax(double amount) {
            return amount * TAX_RATE;
        }
    
        public static double calculateTotal(double amount) {
            double tax = calculateTax(amount);
            return amount + tax;
        }
    }
    
    class Main {
        public static void main(String[] args) {
            double price = 100;
            double total = TaxCalculator.calculateTotal(price);
            System.out.println("总价为: " + total);
        }
    }

代码里,TaxCalculator 类中的 TAX_RATE 是公共变量,多个方法使用该变量进行财务计算。 

7. 内容耦合(不推荐使用)
  • 定义:一个模块直接访问另一个模块的内部数据,或者一个模块不通过正常入口而直接转入另一个模块内部。
  • 示例:在一个面向对象的程序中,一个类的方法直接访问另一个类的私有属性,这违反了面向对象的封装原则。
    class ClassA {
        private int privateData = 10;
    
        public void printPrivateData() {
            System.out.println("ClassA 的私有数据: " + privateData);
        }
    }
    
    class ClassB {
        public void accessClassAPrivateData(ClassA classA) {
            // 直接访问 ClassA 的私有数据(违反封装原则)
            System.out.println("通过 ClassB 访问 ClassA 的私有数据: " + classA.privateData);
        }
    }
    
    class Main {
        public static void main(String[] args) {
            ClassA classA = new ClassA();
            ClassB classB = new ClassB();
    
            classA.printPrivateData();
            classB.accessClassAPrivateData(classA);
        }
    }

这里 ClassB 直接访问了 ClassA 的私有数据,这破坏了封装性,应尽量避免。 

你可能感兴趣的:(软件工程)