曲靖市网站建设_网站建设公司_虚拟主机_seo优化
2026/1/13 16:51:22 网站建设 项目流程

针对线上培训系统,我来帮你梳理核心领域模型。这是一个教育领域的DDD建模,主要涉及用户域学习资源域

核心领域模型分层

复制

用户域 (User Domain) ├── 学生 (Student) - 核心聚合根 ├── 老师 (Teacher) - 独立聚合根 ├── 家长 (Parent) - 独立聚合根 └── 平台管理员 (Admin) - 独立聚合根 学习资源域 (Learning Resource Domain) ├── 课程 (Course) - 聚合根 │ ├── 单词 (Word) - 实体 │ └── 语法 (Grammar) - 实体 学习记录域 (Learning Record Domain) └── 学习进度 (LearningProgress) - 聚合根

详细领域模型

1.用户域模型

java

复制

// 用户基类(值对象) class User { String userId; String username; String email; String phone; UserStatus status; // ACTIVE, INACTIVE } // 学生 - 核心聚合根 class Student { User baseInfo; Grade grade; // 年级 Parent parent; // 关联家长 List<Teacher> teachers; // 关联老师 LearningPreferences preferences; // 学习偏好 } // 老师 - 聚合根 class Teacher { User baseInfo; String qualification; // 资质 List<Subject> teachableSubjects; // 可教科目 Schedule availability; // 可用时间表 } // 家长 - 聚合根 class Parent { User baseInfo; List<Student> children; // 关联的孩子 NotificationPreferences notificationPrefs; // 通知偏好 } // 管理员 - 聚合根 class Admin { User baseInfo; AdminRole role; // SUPER_ADMIN, CONTENT_ADMIN, etc. }
2.学习资源域模型

java

复制

// 课程 - 聚合根(包含单词和语法) class Course { String courseId; String name; Subject subject; // ENGLISH, MATH, etc. Teacher createdBy; DifficultyLevel level; List<Word> vocabulary; // 单词列表 List<Grammar> grammars; // 语法点列表 void addWord(Word word); void removeWord(String wordId); void addGrammar(Grammar grammar); } // 单词 - 实体 class Word { String wordId; String spelling; String phonetic; String meaning; String exampleSentence; DifficultyLevel level; List<String> tags; // 标签:如"高考必备", "四级" } // 语法 - 实体 class Grammar { String grammarId; String title; String description; String usage; List<String> exampleSentences; DifficultyLevel level; }
3.学习记录域模型

java

复制

// 学习进度 - 聚合根 class LearningProgress { String progressId; Student student; Course course; Map<String, WordProgress> wordProgress; // 单词ID -> 掌握进度 Map<String, GrammarProgress> grammarProgress; // 语法ID -> 掌握进度 Date startDate; Date lastStudyDate; OverallMasteryLevel masteryLevel; // 整体掌握程度 } // 单词学习进度 - 值对象 class WordProgress { String wordId; MasteryLevel level; // NOT_STARTED, LEARNING, FAMILIAR, MASTERED int reviewCount; Date lastReviewed; Date nextReviewDate; // 用于 spaced repetition } // 语法学习进度 - 值对象 class GrammarProgress { String grammarId; MasteryLevel level; int exerciseCorrectRate; List<String> mistakeRecords; }

关键关系说明

表格

复制

关系类型主体客体说明
关联StudentParent1个学生可有1-2个家长,家长可多个孩子
关联StudentTeacher多对多,老师教多个学生,学生多个老师
聚合CourseWord强聚合,单词生命周期依赖课程
聚合CourseGrammar强聚合,语法生命周期依赖课程
关联LearningProgressStudent学习进度记录特定学生的
关联LearningProgressCourse学习进度针对特定课程的

领域事件(可选)

java

复制

// 关键业务事件 class WordMasteredEvent { Student student; Word word; Date masteredAt; } class ExerciseCompletedEvent { Student student; Course course; int score; } class ParentNotificationEvent { Parent parent; NotificationType type; // 学习报告、成绩预警等 }

建模建议

  1. 学生是核心聚合根:系统围绕学生展开,所有学习行为都以学生为中心

  2. 课程是资源聚合根:单词和语法作为课程内部实体,不独立存在

  3. 分离读写模型:查询学习进度可独立建READ MODEL,避免聚合根过大

  4. 值对象:User、WordProgress等作为不可变值对象,确保数据一致性

  5. 边界上下文:用户管理、内容管理、学习记录三个子域可独立演进

这样的模型能支撑单词语法学习进度跟踪家长监督老师指导等核心业务流程,也方便后续扩展如智能推荐、** spaced repetition**等高级功能。

需要我展开某个特定部分的详细设计吗?

下面是用Go语言实现的线上培训系统领域模型,遵循DDD原则和Go的最佳实践。

项目目录结构

复制

online-training/ ├── domain/ # 领域层 │ ├── user/ # 用户子域 │ │ ├── user.go # 用户基类(值对象) │ │ ├── student.go # 学生聚合根 │ │ ├── teacher.go # 老师聚合根 │ │ ├── parent.go # 家长聚合根 │ │ └── admin.go # 管理员聚合根 │ ├── resource/ # 学习资源子域 │ │ ├── course.go # 课程聚合根 │ │ ├── word.go # 单词实体 │ │ └── grammar.go # 语法实体 │ ├── progress/ # 学习记录子域 │ │ ├── learning_progress.go # 学习进度聚合根 │ │ ├── word_progress.go # 单词进度值对象 │ │ └── grammar_progress.go # 语法进度值对象 │ └── vo/ # 共享值对象 │ ├── user_status.go │ ├── difficulty_level.go │ └── mastery_level.go ├── repository/ # 仓储接口 │ ├── student_repository.go │ ├── course_repository.go │ └── progress_repository.go └── service/ # 应用服务层 └── student_service.go

1. 共享值对象

go

复制

// domain/vo/user_status.go package vo type UserStatus string const ( StatusActive UserStatus = "ACTIVE" StatusInactive UserStatus = "INACTIVE" ) // domain/vo/difficulty_level.go package vo type DifficultyLevel string const ( LevelBeginner DifficultyLevel = "BEGINNER" LevelIntermediate DifficultyLevel = "INTERMEDIATE" LevelAdvanced DifficultyLevel = "ADVANCED" ) // domain/vo/mastery_level.go package vo type MasteryLevel string const ( MasteryNotStarted MasteryLevel = "NOT_STARTED" MasteryLearning MasteryLevel = "LEARNING" MasteryFamiliar MasteryLevel = "FAMILIAR" MasteryMastered MasteryLevel = "MASTERED" )

2. 用户域实现

go

复制

// domain/user/user.go package user import "online-training/domain/vo" // User 用户基类(值对象) type User struct { UserID string Username string Email string Phone string Status vo.UserStatus } // Equals 值对象相等性判断 func (u User) Equals(other User) bool { return u.UserID == other.UserID } // domain/user/student.go package user import ( "time" "online-training/domain/vo" ) // Student 学生聚合根 type Student struct { User User Grade string ParentID string TeacherIDs []string LearningPrefs LearningPreferences CreatedAt time.Time UpdatedAt time.Time } // LearningPreferences 学习偏好(值对象) type LearningPreferences struct { DailyGoal int // 每日学习目标 PreferredTime string // 偏好学习时间 ReminderEnabled bool // 是否开启提醒 } // NewStudent 工厂函数 func NewStudent(user User, grade string, parentID string) *Student { return &Student{ User: user, Grade: grade, ParentID: parentID, TeacherIDs: make([]string, 0), LearningPrefs: LearningPreferences{}, CreatedAt: time.Now(), UpdatedAt: time.Now(), } } // AddTeacher 聚合根方法:添加老师 func (s *Student) AddTeacher(teacherID string) { for _, id := range s.TeacherIDs { if id == teacherID { return // 已存在 } } s.TeacherIDs = append(s.TeacherIDs, teacherID) s.UpdatedAt = time.Now() } // VerifyLearningAbility 业务规则验证 func (s *Student) VerifyLearningAbility() error { if s.User.Status != vo.StatusActive { return &domainError{message: "学生账号未激活"} } return nil } // domain/user/teacher.go package user import "time" type Teacher struct { User User Qualification string TeachableSubjects []string Availability Schedule CreatedAt time.Time UpdatedAt time.Time } type Schedule struct { Weekdays []int // 可用的星期几 TimeSlots []string // 时间段 } // domain/user/parent.go package user type Parent struct { User User ChildIDs []string NotificationPrefs NotificationPreferences } type NotificationPreferences struct { EmailEnabled bool SMSEnabled bool WeChatEnabled bool DailyReport bool }

3. 学习资源域实现

go

复制

// domain/resource/course.go package resource import ( "time" "online-training/domain/user" "online-training/domain/vo" ) // Course 课程聚合根 type Course struct { CourseID string Name string Subject string Teacher user.Teacher Level vo.DifficultyLevel Vocabulary []Word // 单词列表(实体) Grammars []Grammar // 语法列表(实体) CreatedAt time.Time UpdatedAt time.Time } // AddWord 聚合根方法:添加单词(业务规则:防止重复) func (c *Course) AddWord(word Word) error { for _, w := range c.Vocabulary { if w.WordID == word.WordID { return &domainError{message: "单词已存在"} } } c.Vocabulary = append(c.Vocabulary, word) c.UpdatedAt = time.Now() return nil } // RemoveWord 聚合根方法:删除单词 func (c *Course) RemoveWord(wordID string) { for i, w := range c.Vocabulary { if w.WordID == wordID { c.Vocabulary = append(c.Vocabulary[:i], c.Vocabulary[i+1:]...) c.UpdatedAt = time.Now() return } } } // domain/resource/word.go package resource import "online-training/domain/vo" // Word 单词实体 type Word struct { WordID string Spelling string Phonetic string Meaning string ExampleSentence string Level vo.DifficultyLevel Tags []string } // Equals 实体相等性判断(基于ID) func (w Word) Equals(other Word) bool { return w.WordID == other.WordID } // domain/resource/grammar.go package resource import "online-training/domain/vo" // Grammar 语法实体 type Grammar struct { GrammarID string Title string Description string Usage string ExampleSentences []string Level vo.DifficultyLevel }

4. 学习记录域实现

go

复制

// domain/progress/learning_progress.go package progress import ( "time" "online-training/domain/resource" "online-training/domain/user" "online-training/domain/vo" ) // LearningProgress 学习进度聚合根 type LearningProgress struct { ProgressID string StudentID string CourseID string WordProgress map[string]WordProgress // 单词ID -> 进度 GrammarProgress map[string]GrammarProgress // 语法ID -> 进度 StartDate time.Time LastStudyDate time.Time MasteryLevel vo.MasteryLevel } // UpdateWordProgress 更新单词进度(核心领域逻辑) func (lp *LearningProgress) UpdateWordProgress(wordID string, newLevel vo.MasteryLevel) error { progress, exists := lp.WordProgress[wordID] if !exists { return &domainError{message: "单词不在课程中"} } // 业务规则:掌握程度只能向前推进 if !lp.canTransition(progress.Level, newLevel) { return &domainError{message: "无效的进度状态转换"} } progress.Level = newLevel progress.ReviewCount++ progress.LastReviewed = time.Now() progress.NextReviewDate = lp.calculateNextReviewDate(newLevel) lp.WordProgress[wordID] = progress lp.LastStudyDate = time.Now() lp.updateOverallMastery() return nil } // 计算下次复习时间( spaced repetition算法 ) func (lp *LearningProgress) calculateNextReviewDate(level vo.MasteryLevel) time.Time { intervals := map[vo.MasteryLevel]time.Duration{ vo.MasteryLearning: 24 * time.Hour, vo.MasteryFamiliar: 72 * time.Hour, vo.MasteryMastered: 168 * time.Hour, } return time.Now().Add(intervals[level]) } // domain/progress/word_progress.go package progress import ( "time" "online-training/domain/vo" ) // WordProgress 单词进度值对象 type WordProgress struct { WordID string Level vo.MasteryLevel ReviewCount int LastReviewed time.Time NextReviewDate time.Time } // IsDueForReview 判断是否该复习了 func (wp WordProgress) IsDueForReview() bool { return time.Now().After(wp.NextReviewDate) }

5. 仓储接口定义

go

复制

// repository/student_repository.go package repository import "online-training/domain/user" type StudentRepository interface { Save(student *user.Student) error FindByID(id string) (*user.Student, error) FindByParentID(parentID string) ([]*user.Student, error) } // repository/course_repository.go package repository import "online-training/domain/resource" type CourseRepository interface { Save(course *resource.Course) error FindByID(id string) (*resource.Course, error) FindByTeacherID(teacherID string) ([]*resource.Course, error) }

6. 应用服务示例

go

复制

// service/student_service.go package service import ( "online-training/domain/user" "online-training/domain/progress" "online-training/repository" ) type StudentService struct { studentRepo repository.StudentRepository progressRepo repository.ProgressRepository } // EnrollCourse 学生选课 func (s *StudentService) EnrollCourse(studentID string, courseID string) error { // 加载聚合根 student, err := s.studentRepo.FindByID(studentID) if err != nil { return err } // 执行业务逻辑 if err := student.VerifyLearningAbility(); err != nil { return err } // 创建学习进度 progress := progress.NewLearningProgress(studentID, courseID) // 保存到仓储 return s.progressRepo.Save(progress) } // domainError 领域错误 type domainError struct { message string } func (e *domainError) Error() string { return e.message }

Go实现的关键设计要点

表格

复制

设计点Go实现方式说明
聚合根结构体+方法通过方法实现业务规则,控制内部状态
值对象结构体+Equals()不可变,通过相等性判断比较
工厂函数NewXXX()函数封装聚合根创建逻辑,确保不变性
仓储接口Interface定义在领域层,实现在基础设施层
领域错误自定义error类型明确区分业务异常和技术异常
依赖方向领域层不依赖其他层通过接口解耦,符合整洁架构

这个实现严格遵循DDD原则,同时充分利用了Go的特性(接口、组合、包管理)。需要我展开某个特定部分的实现细节吗?

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询