使用对象模型实现订阅服务
0 简介
面向对象方法开发软件时,通常使用对象模型、动态模型和功能模型来描述系统的不同方面。这三种模型各自关注的方面不同,但它们紧密关联,构成了系统的整体设计。
对象模型关注系统的静态结构,定义类及其关系。本文假设在预约系统中,对象模型可用于描述预约界面组件、数据库访问类、医生列表及出诊时段表。通过Go语言Web框架Gin实现患者和医生类,展示继承、聚合与关联的应用。
1. 对象模型(Object Model)
对象模型主要用于描述系统中的静态结构。它定义了系统中的类、对象及它们之间的关系(例如继承、聚合、关联等)。对象模型类似于类图,描述了系统的实体以及实体之间的静态关系。
在预约系统中的应用:
预约界面(Appointment Interface):可以用对象模型来定义预约界面中的组件,例如“预约表单”、“确认按钮”等组件作为对象,并描述它们与“预约对象”(Appointment)之间的关联关系。
数据库访问类(Database Access Class):对象模型可以定义数据库访问类,负责封装数据库的CRUD操作,并与其他业务实体(如医生、患者等)进行关联。
医生列表(Doctor List):医生作为系统中的一个对象类(Doctor),医生列表则可能是一个集合类,与医生类有关联。
医生出诊时段表(Doctor Schedule):出诊时段表可以定义为医生对象的一个属性或是一个独立的类,与医生类相关联。
2 模型设计对象关系的实践
在Go语言的Web框架Gin中实现患者和医生类,同时体现继承、聚合和关联等对象模型关系,涉及面向对象的概念在Go中的实际应用。Go语言本身不支持传统的继承概念,但可以通过组合(embedding)来模拟继承行为。接下来我们将定义患者和医生类,并实现一个简易的患者订阅Web服务。
继承:Go通过结构体的组合来实现类似继承的功能。我们会定义一个Person结构体,包含患者和医生的公共属性,然后让Patient和Doctor类通过组合来继承Person的属性。
聚合:患者类可以包含一个医生的引用,表示某患者关注某位医生。
关联:医生和患者可以通过ID进行关联,患者可以订阅医生的服务。
3 代码实现和说明
继承:Patient和Doctor类通过嵌入Person结构体实现了类似继承的行为,这意味着它们继承了Person的属性(ID、Name、Age)。
聚合:Patient结构体包含一个SubscribedDoctor指针,该指针指向患者订阅的医生对象,体现了聚合关系。
关联:患者和医生通过ID进行关联,subscribeDoctor方法接收两个参数:patientID和doctorID,用于找到对应的医生和患者并建立订阅关系。
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
定义Person结构体,作为患者和医生的基类
type Person struct {
ID int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
Doctor 结构体,继承Person
type Doctor struct {
Person
Specialty string `json:"specialty"`
}
Patient 结构体,继承Person,并聚合Doctor
type Patient struct {
Person
SubscribedDoctor *Doctor `json:"subscribed_doctor"`
}
用于存储医生和患者的全局变量
var doctors = []Doctor{
{Person: Person{ID: 1, Name: "Dr. Smith", Age: 45}, Specialty: "Cardiology"},
{Person: Person{ID: 2, Name: "Dr. Johnson", Age: 50}, Specialty: "Neurology"},
}
var patients = []Patient{
{Person: Person{ID: 1, Name: "Alice", Age: 30}, SubscribedDoctor: nil},
{Person: Person{ID: 2, Name: "Bob", Age: 40}, SubscribedDoctor: nil},
}
获取所有医生列表
func getDoctors(c *gin.Context) {
c.JSON(http.StatusOK, doctors)
}
获取所有患者列表
func getPatients(c *gin.Context) {
c.JSON(http.StatusOK, patients)
}
患者订阅医生服务
func subscribeDoctor(c *gin.Context) {
patientID := c.Param("patientID")
doctorID := c.Param("doctorID")
var patient *Patient
var doctor *Doctor
// 查找患者
for i := range patients {
if patients[i].Person.ID == patientID {
patient = &patients[i]
break
}
}
// 查找医生
for i := range doctors {
if doctors[i].Person.ID == doctorID {
doctor = &doctors[i]
break
}
}
// 如果找到患者和医生,则进行订阅
if patient != nil && doctor != nil {
patient.SubscribedDoctor = doctor
c.JSON(http.StatusOK, gin.H{
"message": "Subscription successful",
"patient": patient,
"doctor": doctor,
})
} else {
c.JSON(http.StatusNotFound, gin.H{"message": "Patient or Doctor not found"})
}
}
func main() {
r := gin.Default()
// 定义路由
r.GET("/doctors", getDoctors)
r.GET("/patients", getPatients)
r.POST("/patients/:patientID/subscribe/:doctorID", subscribeDoctor)
// 启动服务
r.Run(":8080")
}
4 使用流程
1 用户访问/doctors路由获取医生列表。
2 用户访问/patients路由获取患者列表。
3 用户通过POST请求访问/patients/:patientID/subscribe/:doctorID来订阅某位医生,
例如:
POST /patients/1/subscribe/2
这将让ID为1的患者订阅ID为2的医生。
5 小结
本文介绍面向对象方法采用对象模型如何描述软件的不同方面。对象模式规定了执行事情的实体。
并且提供代码示例展示了如何通过结构体组合实现继承,并利用全局变量存储医生和患者信息,实现患者订阅医生服务。用户可通过API获取医生和患者列表并完成订阅操作。
- 点赞
- 收藏
- 关注作者
评论(0)