0

0

系统设计:用 Go 构建一个简单的社交媒体平台

DDD

DDD

发布时间:2024-11-08 19:41:11

|

1180人浏览过

|

来源于dev.to

转载

在本文中,我们将演练使用 go 设计一个简化的社交媒体平台,重点关注底层系统设计原则。我们的平台包括用户注册、创建帖子、处理点赞和评论以及通知用户更新等核心功能。此示例说明了如何将这些功能构建到模块化、可扩展且高效的系统中。

我们将使用 go 的并发能力和外观设计模式来创建精简且可维护的结构,使平台能够无缝处理各种用户交互。

我们设计的关键组成部分

我们正在构建的社交媒体平台侧重于以下主要功能:

  • 用户管理:注册和管理用户配置文件。
  • 帖子创建和互动:创建帖子、点赞和评论。
  • 通知:提醒用户相关操作,例如点赞和评论。
  • 并发:有效处理并发用户操作。

系统核心组件

让我们分解一下我们平台的关键组件,看看每个部分如何集成到系统中。

  1. 用户管理

usermanager 组件负责用户注册和配置文件管理。每个用户都有重要的个人资料详细信息,如 id、姓名和个人简介,管理员确保可以有效地添加和检索用户。一些关键功能是:

type user struct {
    type user struct {
    id             int
    name           string
    email          string
    password       string
    displaypicture *string
    bio            *string
    friends        map[int]*user
    posts          []*post
}

type usermanager struct {
    users map[int]*user
    mu    sync.rwmutex
}

func (um *usermanager) adduser(user *user) {
    um.mu.lock()
    defer um.mu.unlock()
    um.users[user.id] = user
    fmt.printf("user added: %d\n", user.id)
}

func (um *usermanager) getuserbyid(userid int) (*user, error) {
    um.mu.rlock()
    defer um.mu.runlock()
    user, ok := um.users[userid]
    if !ok {
        return nil, fmt.errorf("user not found")
    }
    return user, nil
}

func (um *usermanager) addfriend(requesterid, receiverid int) error {
    requester, err := um.getuserbyid(requesterid)
    if err != nil {
        return err
    }

    receiver, err := um.getuserbyid(receiverid)
    if err != nil {
        return err
    }

    requester.addfriend(receiver)
    receiver.addfriend(requester)
    fmt.printf("friendship added between users: %d and %d\n", requesterid, receiverid)
    return nil
}

在现实世界的应用程序中,usermanager 将连接到数据库,但为了简单起见,这里我们使用地图。

  1. 后期管理

postmanager 通过管理帖子、点赞和评论来处理用户生成的内容。该组件允许用户创建帖子、点赞其他人的帖子、评论和检索帖子。一些关键功能是:

type post struct {
    id              int
    userid          int
    content         string
    ispublished     bool
    urls            []*string
    likes           int
    comments        []*comment
    publishedat     time.time
    commentsenabled bool
    hiddenfromusers map[int]bool
}

type postmanager struct {
    posts map[int]*post
    mu    sync.rwmutex
}

func (pm *postmanager) getpost(postid int) (*post, error) {
    pm.mu.rlock()
    defer pm.mu.runlock()

    post, exists := pm.posts[postid]
    if !exists {
        return nil, fmt.errorf("post not found")
    }
    return post, nil
}

func (pm *postmanager) addpost(post *post, user *user) {
    pm.mu.lock()
    defer pm.mu.unlock()
    pm.posts[post.id] = post

    user.addpost(post)
}

func (pm *postmanager) likepost(postid int) (*post, error) {
    pm.mu.lock()
    post := pm.posts[postid]
    pm.mu.unlock()

    if post == nil {
        return nil, fmt.errorf("post not found")
    }

    pm.mu.lock()
    defer pm.mu.unlock()

    post.like()
    return post, nil
}

postmanager 可以与数据库交互来存储和检索帖子,从而允许按各种标准进行过滤。

  1. 通知管理

notificationmanager 负责让用户了解平台活动的最新情况,例如接收对其帖子的点赞或评论。每种通知类型(点赞、评论、好友请求)均通过此管理器发送,确保用户实时收到通知。一些关键功能是:

type notification struct {
    id      string
    type    notificationtype
    content string
    userid  int
}

type notificationmanager struct {
    notifications map[int][]*notification
    mu            sync.rwmutex
}

func (nm *notificationmanager) addnotification(userid int, notificationtype notificationtype, message string) {
    nm.mu.lock()
    defer nm.mu.unlock()

    notification := newnotification(fmt.sprintf("notification-%d", time.now().unixmicro()), notificationtype, message, userid)
    nm.notifications[userid] = append(nm.notifications[userid], notification)
}

func (nm *notificationmanager) getnotificationsforuser(userid int) ([]*notification, error) {
    nm.mu.rlock()
    defer nm.mu.runlock()

    notifications, ok := nm.notifications[userid]
    if !ok {
        return nil, fmt.errorf("user not found")
    }
    return notifications, nil
}

通过notificationmanager,我们可以通知用户与其帖子相关的交互,从而提供更具吸引力的体验。在生产系统中,可以通过通道或推送通知发送通知。

浚心时尚购物商城程序
浚心时尚购物商城程序

时尚购物程序v1.01、全立体设计。此系统由3个Flash动画为主线(正式版带原文件),设计更形象,网站更有吸引力。这种设计在网店系统内绝无仅有,使您的网店与众不同。2、内置音乐播放器,简单灵活的操作即可完成设置,前台任意调用。并带详细说明文件,一看就懂。合理使用此功能,可使网站更富渲染力。3、支持多图显示,每件产品最多可以上传9张图片。4、后台功能强大,销售管理,财务管理,在线支付平台管理等功能

下载

将外观模式与 activityfacade 结合使用

为了简化不同组件之间的交互,我们使用 facade 模式。 activityfacade结合了usermanager、postmanager和notificationmanager的功能,为我们的社交媒体应用程序提供了统一的界面。

type ActivityFacade struct {
    userManager       *UserManager
    postManager       *PostManager
    notificationManager *NotificationManager
}

func (af *ActivityFacade) SendFriendRequest(requesterID, receiverID int) error {
    _, err := af.UserManager.GetUserByID(receiverID)
    if err != nil {
        return err
    }

    af.NotificationManager.AddNotification(receiverID, FriendRequestNotificationType, fmt.Sprintf("%d has sent you a friend request", requesterID))

    fmt.Printf("Friend request sent to user %d\n", receiverID)
    return nil
}

func (af *ActivityFacade) CommentPost(userID, postID int, content string) error {
    user, err := af.UserManager.GetUserByID(userID)
    if err != nil {
        return err
    }

    post, err := af.PostManager.CommentPost(user, postID, content)

    af.NotificationManager.AddNotification(post.UserID, CommentNotificationType, fmt.Sprintf("%d has commented on your post: %d", userID, post.ID))

    fmt.Printf("Comment added to post: %d\n", post.ID)
    return nil
}

func (af *ActivityFacade) HidePostFromUser(postID int, userID int) error {
    _, err := af.UserManager.GetUserByID(userID)
    if err != nil {
        return err
    }

    return af.PostManager.HidePostFromUser(postID, userID)
}

通过 activityfacade,我们可以简化用户与平台的交互,降低直接管理每个子系统的复杂性。这种方法使代码更加模块化、可维护且更易于扩展。


处理并发

在任何社交媒体平台中,多个用户同时执行操作。 go 的并发工具,特别是sync的 rwmutex,非常适合以安全的方式处理并发读写。

使用 rwmutex,我们确保多个用户可以同时阅读帖子,但一次只有一个用户可以点赞或评论,从而防止竞争条件和数据损坏。


结论和后续步骤

我们针对 go 社交媒体平台的底层系统设计为扩展功能奠定了坚实的基础,使其可扩展且易于维护。

未来增强的潜在领域包括:

  • 使用 websocket 或推送通知的实时通知。
  • 针对好友请求和帖子的高级隐私控制。
  • 使用数据库的持久数据存储来替换内存中的映射。

完整的代码实现,请检查以下存储库:

系统设计:用 Go 构建一个简单的社交媒体平台 主题树 / 低级设计 golang

golang 中的底层系统设计解决方案

go 中的底层系统设计

欢迎来到go 中的低级系统设计 存储库!该存储库包含各种低级系统设计问题及其在 go 中实现的解决方案。主要目的是通过实际示例展示系统的设计和架构。

目录

  • 概述
  • 停车场系统
  • 电梯系统
  • 图书馆管理系统
  • 自动售货机系统
  • 社交媒体平台

概述

底层系统设计涉及理解系统架构的核心概念以及设计可扩展、可维护和高效的系统。该存储库将尝试涵盖使用 go 的各种问题和场景的解决方案。

停车场系统

此存储库中的第一个项目是停车场系统。该系统模拟一个可以停放车辆和出库车辆的停车场。它演示了:

  • 用于管理停车场实例的单例设计模式。
  • 处理不同类型的车辆(例如汽车、卡车)。
  • 多个楼层的停车位管理。
  • 付款处理...


github 上查看


相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

178

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

226

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

337

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

208

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

388

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

195

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

189

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

192

2025.06.17

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

11

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.6万人学习

Git版本控制工具
Git版本控制工具

共8课时 | 1.5万人学习

Git中文开发手册
Git中文开发手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号