信息工程结合面向对象的组合思想

举报
码乐 发表于 2024/12/12 08:43:38 2024/12/12
【摘要】 1 简介本文“聚合/组合”与“实体关系” 的具体实例展示如何结合 面向对象(OO)方法中的“聚合/组合” 和 信息工程方法中的“实体关系” 实现一个简单的部门和子部门人员管理服务。说明两者如何在实际系统中配合使用,以实现功能的模块化和关系清晰化。 2 使用场景描述信息工程方法的“实体关系”设计: 部门(Department)和人员(Employee)是两个实体。 实体之间的关系是“一对多”...

1 简介

本文“聚合/组合”与“实体关系” 的具体实例展示如何结合 面向对象(OO)方法中的“聚合/组合” 和 信息工程方法中的“实体关系” 实现一个简单的部门和子部门人员管理服务。说明两者如何在实际系统中配合使用,以实现功能的模块化和关系清晰化。

2 使用场景描述

信息工程方法的“实体关系”设计:

	部门(Department)和人员(Employee)是两个实体。
	实体之间的关系是“一对多”:一个部门可以有多个员工,一个部门可以包含多个子部门,每个子部门也是一个部门。
	面向对象的“聚合/组合”思想:
	部门包含人员(“部分-整体”聚合关系)。
	部门可以包含子部门(“递归组合”)。

在 Web 服务中,我们实现以下功能:

  创建部门和人员。
  添加子部门。
  查询部门及其包含的人员和子部门。

3 数据模型设计

Department 表示部门,包含通用信息以及聚合关系。
Employee 表示人员,关联到一个具体的部门。
使用聚合和组合的方式建模部门与人员及子部门的关系。

4 Go 实现代码

	package main

	import (
		"encoding/json"
		"fmt"
		"net/http"
		"sync"
	)

	// Employee 表示一个员工实体
	type Employee struct {
		ID         int    `json:"id"`
		Name       string `json:"name"`
		Position   string `json:"position"`
		Department int    `json:"department"` // 所属部门的ID
	}

	// Department 表示一个部门实体,包括子部门和员工
	type Department struct {
		ID          int           `json:"id"`
		Name        string        `json:"name"`
		SubDepartments []int       `json:"sub_departments"` // 子部门ID列表
		Employees   []Employee    `json:"employees"`       // 员工列表
	}

	// 存储库(模拟数据库)
	var (
		departments = struct {
			sync.Mutex
			data map[int]*Department
		}{data: make(map[int]*Department)}

		employees = struct {
			sync.Mutex
			data map[int]*Employee
		}{data: make(map[int]*Employee)}
	)

	// 创建部门的处理函数
	func createDepartmentHandler(w http.ResponseWriter, r *http.Request) {
		var dept Department
		if err := json.NewDecoder(r.Body).Decode(&dept); err != nil {
			http.Error(w, "Invalid input", http.StatusBadRequest)
			return
		}

		departments.Lock()
		defer departments.Unlock()
		dept.ID = len(departments.data) + 1
		departments.data[dept.ID] = &dept

		w.WriteHeader(http.StatusCreated)
		json.NewEncoder(w).Encode(dept)
	}

	// 添加员工的处理函数
	func addEmployeeHandler(w http.ResponseWriter, r *http.Request) {
		var emp Employee
		if err := json.NewDecoder(r.Body).Decode(&emp); err != nil {
			http.Error(w, "Invalid input", http.StatusBadRequest)
			return
		}

		departments.Lock()
		defer departments.Unlock()
		employees.Lock()
		defer employees.Unlock()

		// 检查所属部门是否存在
		dept, exists := departments.data[emp.Department]
		if !exists {
			http.Error(w, "Department not found", http.StatusNotFound)
			return
		}

		// 添加员工到部门
		emp.ID = len(employees.data) + 1
		employees.data[emp.ID] = &emp
		dept.Employees = append(dept.Employees, emp)

		w.WriteHeader(http.StatusCreated)
		json.NewEncoder(w).Encode(emp)
	}

	// 添加子部门的处理函数
	func addSubDepartmentHandler(w http.ResponseWriter, r *http.Request) {
		var input struct {
			ParentDeptID int `json:"parent_dept_id"`
			SubDeptID    int `json:"sub_dept_id"`
		}
		if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
			http.Error(w, "Invalid input", http.StatusBadRequest)
			return
		}

		departments.Lock()
		defer departments.Unlock()

		// 检查父部门和子部门是否存在
		parentDept, parentExists := departments.data[input.ParentDeptID]
		subDept, subExists := departments.data[input.SubDeptID]

		if !parentExists || !subExists {
			http.Error(w, "Parent or sub-department not found", http.StatusNotFound)
			return
		}

		// 添加子部门到父部门的子部门列表
		parentDept.SubDepartments = append(parentDept.SubDepartments, subDept.ID)

		w.WriteHeader(http.StatusOK)
		json.NewEncoder(w).Encode(parentDept)
	}

	// 查询部门详情的处理函数
	func getDepartmentHandler(w http.ResponseWriter, r *http.Request) {
		var input struct {
			DeptID int `json:"dept_id"`
		}
		if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
			http.Error(w, "Invalid input", http.StatusBadRequest)
			return
		}

		departments.Lock()
		defer departments.Unlock()

		// 查找部门
		dept, exists := departments.data[input.DeptID]
		if !exists {
			http.Error(w, "Department not found", http.StatusNotFound)
			return
		}

		// 返回部门信息
		json.NewEncoder(w).Encode(dept)
	}

	func main() {
		// 路由配置
		http.HandleFunc("/departments", createDepartmentHandler) // 创建部门
		http.HandleFunc("/employees", addEmployeeHandler)        // 添加员工
		http.HandleFunc("/subdepartments", addSubDepartmentHandler) // 添加子部门
		http.HandleFunc("/department", getDepartmentHandler)     // 查询部门详情

		// 启动服务器
		fmt.Println("Server is running at http://localhost:8080")
		http.ListenAndServe(":8080", nil)
	}

5 示例说明

  • 信息工程的实体关系实体:

    Department 和 Employee 是两个核心实体。
    Department 包含字段 SubDepartments(子部门ID)和 Employees(员工列表),表示聚合和组合关系。

关系:

一个部门有多个员工(1对多)。
一个部门可以包含多个子部门(递归多对多)。
  • 面向对象的聚合/组合

聚合:

部门包含员工列表,表示弱依赖关系,员工可以独立于部门存在。

组合:

部门包含子部门,表示强依赖关系,子部门的生命周期与父部门绑定。

Web 服务的功能

创建部门:通过 /departments 创建一个新部门。
添加员工:通过 /employees 添加员工到某个部门。
添加子部门:通过 /subdepartments 将一个部门设为另一个部门的子部门。
查询部门详情:通过 /department 获取部门的详细信息,包括员工和子部门。
  • 测试

创建部门

	curl -X POST -H "Content-Type: application/json" -d '{"name": "IT Department"}' http://localhost:8080/departments

添加员工

curl -X POST -H "Content-Type: application/json" -d '{"name": "John Doe", "position": "Developer", "department": 1}' http://localhost:8080/employees

添加子部门

curl -X POST -H "Content-Type: application/json" -d '{"parent_dept_id": 1, "sub_dept_id": 2}' http://localhost:8080/subdepartments

查询部门详情

curl -X POST -H "Content-Type: application/json" -d '{"dept_id": 1}' http://localhost:8080/department

6 总结

信息工程的实体关系:部门和员工建模为两个实体,通过关联字段定义它们的关系。
面向对象的聚合/组合:使用嵌套关系表示部门和员工及子部门之间的聚合与组合。

配合效果:

数据模型清晰,满足业务需求。
代码复用性高,通过组合实现复杂实体关系。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。