运营弹窗管理

一、场景描述以及所存在的问题

随着业务的发展,业务都有一些运营业务,当用户触发某一个操作时展示业务弹窗,随之而来的会碰到如下场景:

场景一
  • 多个触发时机都需触发业务弹窗
场景导致问题:
  • 弹窗逻辑分散在各处,查找逻辑成本高
  • 后端下发数据形式各种各样,分不清各个场景的使用规则
场景二

一个触发时机会根据不同的情况展示不同的业务弹窗

场景导致问题:
  • 当用户触发操作,没有优先级管理,
场景二
  • 用户触发操作和弹窗展示有时间间隔,在间隔内触发了其他弹窗造成弹窗层叠出现
场景导致问题:

没有弹窗状态,无法知道当前是否已经出现弹窗,出现弹窗层叠出现,影响用户体验: eg:电话后10s弹窗,这时候用户触发了其他操作展示的弹窗,这时候出现层叠情况

根据场景再进行抽象我们要解决的问题

  1. 对弹窗业务逻辑进行集中管理
  2. 规范化后端下发数据的格式
  3. 感知弹窗状态
  4. 提供优先级管理机制

二、针对以上问题设计弹窗模块

1.针对每个场景类型进行抽象,定义枚举区分

ini 复制代码
示例
enum TanChuangType: String {
    case north = "North"
    case south = "South"
    case east = "East"
    case west = "West"
}

2.抽象协议方法,业务弹窗必须要实现的方法

go 复制代码
示例
protocol iTanChuangTypeService {
    func show(type:TanChuangType)
    fucc canTanchuang(type:TanChuangType)
}

3.设计模块管理TanChuangManager

  • 建立场景枚举和弹窗实现的映射关系
  • 对于提供接受后端数据的接口
  • 对于提供使用方的调用接口
  • 记录当前弹窗的状态,检查当前页面是否已经具有了弹窗,有则不弹窗防止层叠的出现

4.数据格式定义

bash 复制代码
[ 
    {
        弹窗场景
        type:North,
        优先级
        priority:1
        业务数据
        business:{ 
        }
        
    }
    
]

三、对于存量问题的改造

常规方案:对触发时机的代码都加上逻辑判断, 调用弹窗处理模块能够弹窗类似
scss 复制代码
示例
if(TanChuangManager.canTanchuang(.north)) {
    TanChuangManager.show(.north)
} else {
    原有逻辑
}

常规方案的问题:

  • 整个业务都需要改动
  • 触发方法中都要加入原有的额外逻辑
  • 后期对原有逻辑修改,会影响弹窗逻辑,造成不要的问题点
hook改进方案:
1.常规hook方案:

通常的hook方案是对现有特定的方法进行hook,比如对viewWillApper等方法这样对所有对象都能生效,但对于我们的场景用户触发操作执行都是开发者自定义的,没有一个统一的方法直接hook行不通

2.改进hook方案:

对于用户的操作在开发者体现就是就是能够响应事件的UI控件,比如UIButton或者手势事件,比如UIGesture 所以就他们添加事件的方法进行hook

  • hook添加事件的方法

  • 在hook自定义事件中构造NSProxy代理对象并设置成响应事件的target对象

objectivec 复制代码
构造的NSProxy代理对象
@interface Proxy : NSProxy
@property (nonatomic, strong) id target;
@property (nonatomic, assign) TanChuangType type;
@property (nonatomic, strong) SEL action;

@end

以UIButton举例hook方法处理

ini 复制代码
构造的NSProxy代理对象
- (void)addTarget:(nullable id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents {
    Proxy *proxy = [[proxy alloc] init];
    proxy.target = target;
    proxy.action = action;
    proxy.type = self.type; 分类的方式给UIButton添加的枚举属性
    替换target对象
    [self addTarget:proxy action:action forControlEvents:controlEvents];
}

这样用户点击的时候是NSProxy代理对象接收事件

  • NSProxy代理对象中事件处理
lua 复制代码
 - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
    if(self.type && [TanChuangManager canTanchuang:self.type]){
        [TanChuangManager show:self.type];
    } else {
        处理原有逻辑
        return [self.target methodSignatureForSelector:sel];
    } 
  }

三、最后的用法

1.在创建手势和UI控件设置定义好的枚举

ini 复制代码
 button.type = .north

2.开发弹窗逻辑并配置到TanChuangManager即可

四、效果

1.动态行:后端通过数据动态通知弹窗展示场景,弹窗优先级

2.开发:新增业务只需关注弹窗业务开发符合单一原则

五、面试场景下,怎么回答能够体现了你在(架构抽象模块化设计系统性思考)方面的能力

1.背景与问题归纳 (体现你的场景理解力和总结抽象能力)

随着业务的发展,出现了大量基于用户触发的运营弹窗需求。但在实践中遇到了几个典型问题:

  • 弹窗逻辑分散在各处,增加维护成本
  • 后端下发数据格式不统一,难以规范接入
  • 弹窗之间无优先级管理,弹窗状态不可感知,易出现层叠等问题

因此,我设计了一个统一的弹窗管理模块,从架构上解决弹窗业务的发展性和复杂性问题。


2. 设计目标归纳 (体现你的系统性设计思维)

设计目标明确四点:

  1. 弹窗业务逻辑集中管理,降低接入和维护成本

  2. 统一后端数据格式,提升数据驱动能力

  3. 感知并管理弹窗状态,保障体验一致性

  4. 引入优先级调度机制,确保多弹窗竞争时体验合理


3. 整体架构设计 (体现你的抽象设计与模块划分能力)

为此,我做了如下抽象和设计:

  • 场景类型枚举化:通过TanChuangType枚举区分不同业务弹窗场景,方便统一管理
  • 弹窗协议化:定义iTanChuangTypeService协议,每个业务弹窗都需遵循,实现规范
  • 集中式管理器:引入TanChuangManager,统一处理弹窗注册、状态感知、优先级调度
  • 标准化数据定义:后端下发的数据统一遵循 [场景 + 优先级 + 业务数据] 格式
  • 弹窗状态管理:模块内部感知弹窗展示与否,防止无序堆叠

4. ### 兼容存量业务的演进策略 ### (体现你的实际落地与渐进式改造能力)

面对已有大量存量业务,有两种接入策略:

  • 常规方案:在触发时机调用TanChuangManager进行弹窗判断和展示

    • 整个业务都需要改动
    • 触发方法中都要加入原有的额外逻辑
    • 后期对原有逻辑修改,会影响弹窗逻辑,造成不要的问题点
  • Hook改进方案

    • 针对UIButton等UI控件的addTarget:action:forControlEvents:方法进行方法交换
    • 通过NSProxy代理方式,保证原业务逻辑不受影响

这样可以最小侵入、动态增强存量业务,极大降低改造成本。

(这里体现你的工程实践能力和对平滑演进的思考)


5.**技术细节亮点(体现你在细节层面有深度)

  • 为什么使用NSProxy
  • 弹窗状态怎么保证线程安全

(这里顺带带出你对架构原则、线程安全等关注)

相关推荐
brzhang7 小时前
代码即图表:dbdiagram.io让数据库建模变得简单高效
前端·后端·架构
MaCa .BaKa7 小时前
35-疫苗预约管理系统(微服务)
spring boot·redis·微服务·云原生·架构·springcloud
三原8 小时前
2025 乾坤(qiankun)和 Vue3 最佳实践(提供模版)
vue.js·架构·前端框架
高桐@BILL10 小时前
1.4 大模型应用产品与技术架构
人工智能·架构·agent
zizisuo10 小时前
6.1.多级缓存架构
缓存·架构
Wgllss11 小时前
按需下载!!全动态插件化框架WXDynamicPlugin解析怎么支持的
android·架构·android jetpack
国际云,接待12 小时前
[特殊字符]服务器性能优化:从硬件到AI的全栈调优指南
运维·服务器·人工智能·阿里云·性能优化·架构·云计算
前端太佬13 小时前
从零到一实现扫码登录:一个前端菜鸟的踩坑实录
前端·javascript·架构
karatttt14 小时前
用go从零构建写一个RPC(仿gRPC,tRPC)--- 版本1
后端·qt·rpc·架构·golang