产品设计

Beam:把另一台 Mac 的一个窗口带到眼前

Beam 是跨 Mac 使用应用窗口的工具。它让需要同时使用两台电脑的人,把另一台上的编辑器、终端或文档放到眼前的桌面,并继续操作。

先尝试拆解问题、设计和实现,再展开思路,检查状态、边界与取舍,并设计验证用例。思路提供分析路径,不给出完整实现。

01
代码思考进阶

合并窗口事件,避免旧消息复活已关闭实例

为教学用远程窗口列表设计事件合并器,不实现真实 Beam 协议。服务端为每个窗口实例分配永不复用的 instanceId;窗口标题可以重复。

  1. 输入事件为 {instanceId, seq, state, title}。seq 是该实例从1开始严格递增的正整数;每条事件都携带完整状态,state 为 visible、hidden 或 closed。网络会重复或乱序送达;同一实例同一seq的数据必定相同。
  2. closed 是该实例最后一个合法事件,之后不会再产生更大seq。接收端要输出各实例的最新状态,并防止迟到旧事件让关闭实例重新出现。未知实例收到hidden也必须记录;不能假设visible先到。
  3. 手推 A/2/hidden → A/1/visible → A/3/closed → A/2/hidden → B/1/visible,A和B标题相同。说明每一步列表与保留记录的变化。
  4. 交付状态与数据结构说明、合并规则的理由、至少三个反例及时间和空间代价。设ID比较和字典访问均按平均常数时间估计;没有服务端水位线或确认机制,不得以超时为理由丢弃所有关闭记录。
查看思路
  1. 先分开instanceId与标题,用序号比较同一实例的新旧;完整状态意味着无需等齐中间序号,但不同实例的序号不能互相比。
  2. 以题目给定序列检查:A先被记为hidden,迟到的1不能回退;3关闭后2不能复活;B仍是独立的visible实例。
  3. 关闭记录需要保留最新序号或等价墓碑。只有额外协议能证明旧消息不会再来时才能安全回收,本题未提供这种条件。
  4. 再推空输入、重复相同事件、未知实例先收到closed及多个同名窗口。区分每事件平均处理成本和随历史实例数增长的记录空间;不要声称内存天然有固定上限。
02
界面实现进阶

让实时选择器保持焦点与对象一致

为教学用网页窗口选择器设计交互。它是一个模态对话框,背景不能操作;窗口列表每秒刷新一次,条目可消失或改名。每项有稳定instanceId和电脑名,同名条目允许存在。

  1. 用普通按钮构成条目列表,支持Tab、Shift+Tab与Esc,并给对话框可读名称;不要求实现远程视频或自造复杂键盘控件。
  2. 用户聚焦A时,刷新移除A、插入B。说明焦点与已选项怎样变化,不得悄悄把选择转给B。提交前再次核对所选instanceId存在;若提交期间消失,显示失败并允许重新选择。
  3. 关闭对话框后回到打开按钮;如果按钮已不存在,定义合理的后备焦点。提供空列表、断网与重试的状态。
  4. 交付状态图、关键DOM语义与键盘验收步骤,包含“聚焦—刷新—提交”的时间序列。依据W3C模态对话框规范解释选择,不写完整实现。
查看思路
  1. 分别记录焦点、已选instanceId和请求状态。焦点用于键盘导航,选择决定提交对象,两者不能因列表位置变化而混用。
  2. 打开时把焦点放入对话框,Tab在内部循环,Esc关闭;给明确标题和关闭按钮,关闭后恢复到仍存在的触发点或合理后备位置。
  3. A消失时清除无效选择并给出可读提示,将焦点放到明确的仍存控件,例如刷新按钮;B出现不代表用户选择了B。发起连接时重新验证,失败保持可恢复界面。
  4. 用键盘手推空列表、连续刷新、A消失与关闭时触发按钮消失,检查焦点没有落到页面背景,错误能被感知,重试不会保留失效选择。