底层设计:轮询系统
目录
- 问题陈述
- 假设
-
要求
- 创建投票
- 管理投票
- 参与投票
- 查看投票结果
- 民意调查数据
-
实施细节
-
函数/方法
- 创建投票
- 更新民意调查
- 删除投票
- 参与投票
- 查看投票结果
-
函数/方法
-
数据模型
- 投票
- 投票
- 实施细节
- 代码
问题陈述
您需要设计并实现一个在线投票系统。系统应允许用户创建、管理和参与民意调查。每个民意调查都包含一个问题和多个答案选项。用户可以对民意调查进行投票并查看结果。
假设:
- 我们正在使用基于类的实现
- 我们没有使用额外的数据库来存储此信息
- 由于不涉及数据库和服务器,因此没有REST API
- 投票系统的简单低级方法
要求
创建投票:
- 用户应该能够创建一个包含问题和多个答案选项的新民意调查。
- 每个民意调查都必须有唯一的标识符、问题、选项列表和创建时间戳。
管理民意调查:
- 用户应该能够更新现有民意调查的问题或选项。
- 用户应该能够删除投票。
投票:
- 用户应该能够对民意调查中的其中一个选项进行投票。
- 每个用户每次投票只能投票一次。
查看投票结果:
- 用户应该能够查看当前的投票结果,包括每个选项的得票数。
民意调查数据:
- 以允许高效检索和更新的方式存储民意调查、选项和投票。
- 确保数据完整性和一致性,尤其是当多个用户同时投票时。
实施细节
功能/方法:
创建投票
createPoll :
- 输入:问题(字符串),选项(字符串数组)
- 输出:pollId(字符串),消息(字符串)
- 示例:createPoll("你最喜欢的颜色是什么?", ["Red", "Blue", "Green", "Yellow"]) 返回 {"pollId": "123", "message" :“投票创建成功。”}
更新投票
更新投票 :
- 输入:pollId(字符串),问题(字符串),选项(字符串数组)
- 输出:消息(字符串)
- 示例:updatePoll("123", "更新问题?", ["Option1", "Option2"]) 返回 {"message": "投票更新成功。"}
删除投票
删除投票 :
- 输入:pollId(字符串)
- 输出:消息(字符串)
- 示例:deletePoll("123") 返回 {"message": "投票已成功删除。"}
投票
投票投票 :
- 输入:pollId(字符串)、userId(字符串)、选项(字符串)
- 输出:消息(字符串)
- 示例: voteInPoll("123", "user1", "Option1") 返回 {"message": "投票成功。"}
查看投票结果
viewPollResults :
- 输入:pollId(字符串)
- 输出:pollId(字符串),问题(字符串),结果(带有选项键和投票计数值的对象)
- 示例: viewPollResults("123") returns {"pollId": "123", "question": "你最喜欢的颜色是什么?", "results": {"Red": 10, "Blue “:5,“绿色”:3,“黄色”:2}}
数据模型
- 民意调查:
{ "pollId": "123", "question": "What is your favorite color?", "options": ["Red", "Blue", "Green", "Yellow"], "createdAt": "2024-07-11T00:00:00Z" }
- 投票:
{ "pollId": "123", "userId": "user1", "option": "Red", "timestamp": "2024-07-11T01:00:00Z" }
实施细节
这段代码使用 JavaScript 类定义了一个基本的轮询系统。它允许创建、管理和投票。让我们分解一下代码的各个部分:
1. Class Definitions
Poll Class
- Purpose: Represents an individual poll.
-
Constructor Parameters:
- id: A unique identifier for the poll.
- question: The question being asked in the poll.
- options: An array of possible options that users can vote on.
-
Properties:
- pollId: Stores the unique ID of the poll.
- question: Stores the poll question.
- options: Stores the array of options.
- createdAt: Stores the creation date and time of the poll.
Vote Class
- Purpose: Represents an individual vote cast by a user.
-
Constructor Parameters:
- pollId: The ID of the poll the vote is associated with.
- userId: The ID of the user who cast the vote.
- option: The option that the user voted for.
-
Properties:
- pollId: Stores the poll ID for which the vote was cast.
- userId: Stores the user ID of the voter.
- option: Stores the option that the user voted for.
- timestamp: Stores the date and time when the vote was cast.
2. PollManager Class
Purpose: Manages the entire polling system, including creating polls, managing votes, and viewing results.
Constructor:
-
Properties:
- polls: A Map that stores all polls, where the key is the poll ID and the value is the Poll object.
- pollResults: A Map that stores the results of each poll, where the key is the poll ID and the value is another Map that tracks votes for each option.
- userVotes: A Map that stores the votes by each user, where the key is the poll ID and the value is another Map that tracks whether a user has voted in that poll.
Methods:
-
createPoll(question, options)
- Generates a new poll with a unique ID.
- Initializes the poll results, setting the vote count for each option to 0.
- Stores the poll and returns the generated poll ID.
-
updatePoll(pollId, question, options)
- Updates the question and options for an existing poll.
- Resets the poll results to 0 for the updated options.
- Returns a success message if the poll is found, otherwise returns "Poll not found."
-
deletePoll(pollId)
- Deletes a poll by its ID.
- Also removes associated poll results and user votes.
- Returns a success message if the poll is found, otherwise returns "Poll not found."
-
voteInPoll(pollId, userId, option)
- Allows a user to cast a vote in a specific poll.
- Ensures a user can only vote once per poll.
- Updates the vote count for the selected option if valid.
- Returns appropriate messages depending on whether the vote was successful, the user had already voted, or the poll or option was invalid.
-
viewPollResults(pollId)
- Returns the results of a specific poll in an array format, where each entry is a tuple of the option and its vote count.
- Returns "Poll not found" if the poll doesn't exist.
3. Example Usage
- Poll Creation: A poll is created asking, "What is your favorite color?" with options ["Red", "Blue", "Green", "Yellow"]. The poll ID is generated as "1".
- Voting: Multiple users vote in the poll, and the system ensures users can only vote once.
- Viewing Results: The poll results are displayed, showing the vote counts for each option.
- Updating the Poll: The poll's question and options are updated, resetting the results.
- Voting in Updated Poll: A user votes in the updated poll, and the results are displayed.
- Poll Deletion: The poll is deleted, and an attempt to view the results afterward confirms the poll no longer exists.
This implementation provides a basic but functional polling system, handling common scenarios such as poll creation, updating, voting, and deletion.
CODE
class Poll { constructor(id, question, options) { this.pollId = id; this.question = question; this.options = options; this.createdAt = new Date(); } } class Vote { constructor(pollId, userId, option) { this.pollId = pollId; this.userId = userId; this.option = option; this.timestamp = new Date(); } } class PollManager { constructor() { this.polls = new Map(); this.pollResults = new Map(); this.userVotes = new Map(); } createPoll(question, options) { const pollId = (this.polls.size + 1).toString(); const poll = new Poll(pollId, question, options); this.polls.set(pollId, poll); const result = new Map(); options.forEach(option => result.set(option, 0)); this.pollResults.set(pollId, result); return pollId; } updatePoll(pollId, question, options) { const poll = this.polls.get(pollId); if (poll) { poll.question = question; poll.options = options; // Update results for the new options const result = new Map(); options.forEach(option => result.set(option, 0)); this.pollResults.set(pollId, result); return "Poll updated successfully."; } return "Poll not found."; } deletePoll(pollId) { if (this.polls.delete(pollId)) { this.pollResults.delete(pollId); this.userVotes.delete(pollId); return "Poll deleted successfully."; } return "Poll not found."; } voteInPoll(pollId, userId, option) { const poll = this.polls.get(pollId); if (poll) { if (!this.userVotes.has(pollId)) { this.userVotes.set(pollId, new Map()); } const userVote = this.userVotes.get(pollId); if (userVote.get(userId)) { return "User has already voted."; } const result = this.pollResults.get(pollId); if (result.has(option)) { result.set(option, result.get(option) + 1); userVote.set(userId, true); return "Vote cast successfully."; } else { return "Invalid option."; } } return "Poll not found."; } viewPollResults(pollId) { const results = this.pollResults.get(pollId); if (results) { return Array.from(results.entries()); } return "Poll not found."; } } // Example usage const pollManager = new PollManager(); // Creating a poll const pollId = pollManager.createPoll("What is your favorite color?", ["Red", "Blue", "Green", "Yellow"]); console.log("Poll created with ID:", pollId); // Voting in the poll let voteMessage = pollManager.voteInPoll(pollId, "user1", "Red"); console.log(voteMessage); voteMessage = pollManager.voteInPoll(pollId, "user2", "Blue"); console.log(voteMessage); voteMessage = pollManager.voteInPoll(pollId, "user1", "Green"); console.log(voteMessage); // Should inform the user has already voted // Viewing poll results let results = pollManager.viewPollResults(pollId); console.log("Poll results for poll ID", pollId, ":", results); // Updating the poll let updateMessage = pollManager.updatePoll(pollId, "What is your favorite primary color?", ["Red", "Blue", "Yellow"]); console.log(updateMessage); // Voting in the updated poll voteMessage = pollManager.voteInPoll(pollId, "user3", "Yellow"); console.log(voteMessage); // Viewing updated poll results results = pollManager.viewPollResults(pollId); console.log("Updated poll results for poll ID", pollId, ":", results); // Deleting the poll let deleteMessage = pollManager.deletePoll(pollId); console.log(deleteMessage); // Attempting to view results of a deleted poll results = pollManager.viewPollResults(pollId); if (typeof results === "string") { console.log(results); } // Response // Poll created with ID: 1 // Vote cast successfully. // Vote cast successfully. // User has already voted. // Poll results for poll ID 1 : [['Red', 1], ['Blue', 1], ['Green', 0], ['Yellow', 0]] // Poll updated successfully. // Vote cast successfully. // Updated poll results for poll ID 1 : [['Red', 0], ['Blue', 0], ['Yellow', 1]] // Poll deleted successfully. // Poll not found.
Note: Please follow for more detail & Enchanced version of this article with DB, API & other system Design Concept.
More Details:
Get all articles related to system design
Hastag: SystemDesignWithZeeshanAli
系统设计与zeeshanali
Git:https://github.com/ZeeshanAli-0704/SystemDesignWithZeeshanAli
以上是底层设计:轮询系统的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undress AI Tool
免费脱衣服图片

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Microfrontendssolvescalingchallengesinlargeteamsbyenablingindependentdevelopmentanddeployment.1)Chooseanintegrationstrategy:useModuleFederationinWebpack5forruntimeloadingandtrueindependence,build-timeintegrationforsimplesetups,oriframes/webcomponents

TypeScript的高级条件类型通过TextendsU?X:Y语法实现类型间的逻辑判断,其核心能力体现在分布式条件类型、infer类型推断和复杂类型工具的构建。1.条件类型在裸类型参数上具有分布性,能自动对联合类型拆分处理,如ToArray得到string[]|number[]。2.利用分布性可构建过滤与提取工具:Exclude通过TextendsU?never:T排除类型,Extract通过TextendsU?T:never提取共性,NonNullable过滤null/undefined。3

varisfunction-scoped,canbereassigned,hoistedwithundefined,andattachedtotheglobalwindowobject;2.letandconstareblock-scoped,withletallowingreassignmentandconstnotallowingit,thoughconstobjectscanhavemutableproperties;3.letandconstarehoistedbutnotinitial

本文深入探讨了如何为“双巧克力”(Double-Choco)谜题游戏自动生成可解谜题。我们将介绍一种高效的数据结构——基于2D网格的单元格对象,该对象包含边界信息、颜色和状态。在此基础上,我们将详细阐述一种递归的块识别算法(类似于深度优先搜索),以及如何将其整合到迭代式谜题生成流程中,以确保生成的谜题满足游戏规则,并具备可解性。文章将提供示例代码,并讨论生成过程中的关键考量与优化策略。

可选的(?。)InjavascriptsafelyAcccessesnestedPropertiesByRoturningUndUndEfendEfinefinefinefineFanifThainisNullOrundEffined,deskingruntimeErrors.1.itallowssafealowssafeccesstodeeplynestedobjectedobjectproperties

使用JavaScript从DOM元素中删除CSS类最常用且推荐的方法是通过classList属性的remove()方法。1.使用element.classList.remove('className')可安全删除单个或多个类,即使类不存在也不会报错;2.替代方法是直接操作className属性并通过字符串替换移除类,但易因正则匹配不准确或空格处理不当引发问题,因此不推荐;3.可通过element.classList.contains()先判断类是否存在再删除,但通常非必需;4.classList

JavaScript的class语法是原型继承的语法糖,1.class定义的类本质是函数,方法添加到原型上;2.实例通过原型链查找方法;3.static方法属于类本身;4.extends通过原型链实现继承,底层仍使用prototype机制,class未改变JavaScript原型继承的本质。

首先使用npxstorybookinit在React项目中安装并配置Storybook,运行npmrunstorybook启动本地开发服务器;2.按功能或类型组织组件文件结构,在每个组件目录下创建对应的.stories.js文件定义不同状态的展示;3.利用Storybook的Args和Controls系统实现属性动态调整,方便测试各种交互状态;4.使用MDX文件编写包含设计规范、可访问性说明等内容的富文本文档,并通过配置支持MDX加载;5.通过theme.js定义设计令牌并在preview.js
