Maison >développement back-end >Golang >Conception du système : créer une plate-forme de médias sociaux simple en Go
Dans cet article, nous expliquerons la conception d'une plate-forme de médias sociaux simplifiée à l'aide de Go, en nous concentrant sur les principes de conception de systèmes de bas niveau. Notre plate-forme comprend des fonctionnalités de base telles que l'enregistrement des utilisateurs, la création de publications, la gestion des likes et des commentaires, ainsi qu'un système de notification pour tenir les utilisateurs informés. Cet exemple illustre comment ces fonctionnalités peuvent être intégrées dans un système modulaire, évolutif et efficace.
Nous utiliserons les capacités de concurrence et les modèles de conception de Go comme la façade pour créer une structure rationalisée et maintenable, permettant à la plate-forme de gérer diverses interactions utilisateur de manière transparente.
La plateforme de médias sociaux que nous construisons se concentre sur ces fonctionnalités principales :
Décomposons les composants clés de notre plateforme et voyons comment chaque partie s'intègre dans le système.
Le composant UserManager est responsable de l'enregistrement des utilisateurs et de la gestion des profils. Chaque utilisateur dispose de détails de profil essentiels tels que son identifiant, son nom et sa biographie, et le gestionnaire garantit que les utilisateurs peuvent être ajoutés et récupérés efficacement. Certaines fonctions clés sont :
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 }
Dans une application réelle, le UserManager se connecterait à une base de données, mais ici nous utilisons une carte pour plus de simplicité.
Le PostManager gère le contenu généré par les utilisateurs en gérant les publications, les likes et les commentaires. Ce composant permet aux utilisateurs de créer des publications, comme celles des autres, de commenter et de récupérer des publications. Certaines fonctions clés sont :
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 }
Le PostManager pourrait interagir avec une base de données pour stocker et récupérer les publications, permettant un filtrage selon divers critères.
Le NotificationManager est chargé de tenir les utilisateurs informés des activités de la plateforme, comme recevoir un like ou un commentaire sur leurs publications. Chaque type de notification (comme, commentaire, demande d'ami) est envoyé via ce gestionnaire, garantissant que les utilisateurs sont informés en temps réel. Certaines fonctions clés sont :
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 }
Avec NotificationManager, nous pouvons informer les utilisateurs des interactions liées à leurs publications, permettant une expérience plus engageante. Dans un système de production, les notifications peuvent être envoyées via des canaux ou des notifications push.
Pour simplifier les interactions entre les différents composants, nous utilisons le motif Façade. ActivityFacade combine les fonctionnalités de UserManager, PostManager et NotificationManager, fournissant une interface unifiée pour notre application de médias sociaux.
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 }
Avec ActivityFacade, nous pouvons rationaliser les interactions des utilisateurs avec la plateforme, réduisant ainsi la complexité de la gestion directe de chaque sous-système. Cette approche rend le code plus modulaire, maintenable et plus facile à développer.
Sur n'importe quelle plateforme de médias sociaux, plusieurs utilisateurs effectuent des actions simultanément. Les outils de concurrence de Go, en particulier RWMutex de sync, sont idéaux pour gérer les lectures et écritures simultanées en toute sécurité.
En utilisant RWMutex, nous garantissons que plusieurs utilisateurs peuvent lire les publications simultanément, mais qu'un seul peut aimer ou commenter à la fois, évitant ainsi les conditions de concurrence et la corruption des données.
Notre conception de système de bas niveau pour une plate-forme de médias sociaux dans Go fournit une base solide pour étendre les fonctionnalités, la rendant évolutive et facile à entretenir.
Les domaines potentiels d'amélioration future comprennent :
Pour l'implémentation complète du code, veuillez consulter le référentiel suivant :
Bienvenue dans le référentiel Conception de systèmes de bas niveau dans Go ! Ce référentiel contient divers problèmes de conception de systèmes de bas niveau et leurs solutions implémentées dans Go. L'objectif principal est de démontrer la conception et l'architecture des systèmes à travers des exemples pratiques.
La conception de systèmes de bas niveau implique de comprendre les concepts fondamentaux de l'architecture système et de concevoir des systèmes évolutifs, maintenables et efficaces. Ce référentiel tentera de couvrir les solutions de divers problèmes et scénarios utilisant Go.
Le premier projet de ce référentiel est un Système de parking. Ce système simule un parking où les véhicules peuvent être garés et déchargés. Cela démontre :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!