得物技术 前天 07:38
得物社区活动:组件化的演进与实践
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

得物社区活动业务通过组件化和系统化,打破潮流文化与电商的壁垒,构建更紧密的用户、品牌、文化生态。文章探讨了活动业务的演进、组件化实践,以及如何通过技术创新引领潮流社区电商发展。通过活动玩法、任务、激励的灵活组合,提升运营效率,实现业务的持续迭代和创新。

💡 得物社区活动业务的核心在于融合潮流文化与电商,通过社区活动吸引用户分享和互动,增强用户粘性,从而强化品牌形象和文化。

⚙️ 为了提高活动效果和效率,得物采用了组件化方法,将复杂功能拆解为可复用组件,以适应高频业务迭代,降低开发成本,并提升市场响应速度。

🧩 组件化实践中,得物构建了活动、任务和激励的三层概念,通过抽象激励值、构建关联框架、以及任务判定抽离等方式,实现了灵活的任务配置和业务扩展。

🚀 规则引擎的应用是关键,它将业务决策逻辑从任务模块中抽离,使得业务逻辑可以独立维护和动态更新,提高了系统的可维护性和可扩展性。

原创 小龙 2025-06-12 12:04 上海

得物社区活动业务将以组件化、系统化成果为基石,持续深化创新,进一步打破潮流文化与电商消费的壁垒,通过活动业务构建更紧密的用户、品牌、文化生态闭环。得物将凭借不断进化的技术与创新模式,持续引领潮流社区电商的发展风向,书写行业新篇章。

目录

一、前言:社区与活动

二、业务催化剂

    1. 效果与效率的辩证探索

    2. 现存问题剖析

    3. 破局与机遇

三、组件化:从想法到实践

    1.  OOP

    2. 系统和业务

    3. 事件驱动

    4. 模块与模块

    5. 核心概念 & 设计

    6. 业务协同 

四、新陈更迭与系统化

    1.  新陈更迭

    2. 走进系统化

五、展望潮流生态


  前言:社区与活动

“得物平台上的大量商品都具有文化与精神属性,用户往往通过社区来进行了解和分享。”

得物平台作为潮流文化与电商融合的前沿阵地,其社区活动业务的演进备受瞩目。得物平台的很多商品蕴含深厚的文化与精神内涵,这吸引用户在社区进行深度的了解与分享。潮流以品牌和带有潮流元素的产品为载体,以社区和内容作为传播媒介。

从业务视角审视,种草激励、MCN 入驻、达人签约以及各类活动玩法,本质上皆是内容与品牌之间的博弈。通过活动业务,能够获取更为丰富、优质的内容,而这些内容又能进一步强化品牌文化与形象,进而筑牢得物社区的潮流心智根基。

依据以往大盘数据分析,活动所带来的发布在 UGC 大盘中占比及推荐流阅读时长上均有显著作用。

由此可见,活动业务在得物社区的 UGC 发布等相关指标中,占据着举足轻重的地位。回顾得物社区的发展历程,品牌文化的深耕与品类挖掘的潮流大势清晰可辨。得益于这一趋势,社区活动业务近年来备受关注,各类玩法如雨后春笋般层出不穷。

  业务催化剂

效果与效率的辩证探索

为了探寻活动效果的极致境界,我们始终在活动玩法的搭配上不断推陈出新、勇于尝试。

话题类玩法致力于用户心智的精耕细作、激励类玩法侧重于内容质量的提升拔高、互动类玩法着重于用户粘性的稳固增强。活动效果大多取决于玩法本身,这也正是活动玩法日新月异的根源所在。

然而,效率与效果有着不同的侧重点。

效率并不追求差异化的活动玩法,而是在既定框架内,以最优的流程达成目标。它着眼于资源的高效利用,强调标准化与模板化,让活动能够按部就班、有条不紊地推进。但这并不意味着效果与效率相互对立,相反,我们需要在两者之间找到一个恰到好处的平衡点,使其共同为活动业务的破圈发展添砖加瓦。

现存问题剖析

其一,每当推出新活动,不同玩法和激励功能的显著差异,要求我们必须从零开始进行开发与测试。这一过程不仅耗费大量的人力、物力和时间资源,还极大地拖慢了市场响应速度,导致迭代成本居高不下,且难以有效控制。

以常见的活动玩法为例:

其二,新功能的引入对线上服务的稳定性构成潜在威胁,尤其是涉及资产/交易的业务,其潜在风险不容忽视。

最后,由于不同产品团队对同一玩法的理解和实现方式存在差异,使得功能在迭代过程中难以保持持续性和一致性。这种情况不仅造成同质化功能重复开发,还使得宝贵的开发经验无法有效沉淀和传承,严重制约了业务的长期发展。

在活动玩法体系中,任务判定作为核心环节,其复杂性尤为突出。任务条件具有种类繁多,配置灵活的特点,这不仅增加了业务逻辑的复杂度,还大幅提升了线上问题排查和修复的难度与成本。

破局与机遇

面对上述种种挑战,我们将其组件化,使其成为行之有效的解决思路。

解决思路

※  高频业务迭代的适配

活动业务的频繁更迭为组件化提供了得天独厚的条件。通过将复杂功能拆解为独立、可复用的组件,能够迅速顺应变化,敏捷响应市场需求。

※  业务特性的契合

大部分活动功能具有可拆分和可抽象的特性,这为组件化的实施奠定了坚实的基础,使其得以顺利开展。

※  降本提效的需求驱动

随着业务的持续增长和市场要求的稳步提升,采用组件化方式能够切实有效地降低成本,提升运营效率,为业务的稳健增长提供强大助力。

组件化的核心在于从价值向设计的转变。每一个组件都应具备高内聚、低耦合的特性,确保能够在不同场景下灵活复用,而不受具体业务逻辑的束缚。

模块化设计:需将复杂系统拆解为多个模块,每个模块负责一项独立的功能,便于开发和维护。

大系统小做,做从根本上化解业务复杂度问题,拆分大的功能到最小组件上,注重组件之间的接口与衔接。

小功能大做,从单纯的任务条件判定到规则引擎,小的功能往往多且差异性大,通过系统化的设计将他们的能力聚合并出口,保持对后续业务的灵活适配能力,并将影响最小化。

接口抽象:定义清晰明确的接口,使各组件之间的交互简洁明了,通过实现接口来替代业务的直接依赖,提升系统的灵活性与可扩展性。

标准化配置:制定统一的配置标准,简化配置过程,减少迭代调整的频率与复杂性,提高工作效率。

  组件化:从想法到实践

OOP

现实世界事物纷繁复杂、千头万绪,难以全面认识和深入理解。人类通过分类归纳的方法,将复杂事物系统化、条理化,从而使其变得井然有序。

在业务设计中亦是如此,需求千差万别、形形色色,每个人都可能参与其中,即便在基础编码规范的约束下,仍可能出现风格各异的设计,进而导致维护成本攀升、重复能力难以有效复用等问题。

这便催生了我们所熟知的设计范式。

There are four major benefits to object-oriented programming:

Encapsulation: in OOP, you bundle code into a single unit where you can determine the scope of each piece of data.

Abstraction: by using classes, you are able to generalize your object types, simplifying your program.

Inheritance: because a class can inherit attributes and behaviors from another class, you are able to reuse more code.

Polymorphism: one class can be used to create many objects, all from the same flexible piece of code.

系统和业务

系统,作为整个活动与任务体系的架构基础,必须具备高度的健壮性和灵活的扩展能力。它主要承担数据聚合、规则判定和状态流转三大核心功能。

以抽奖活动玩法为例,系统负责收集整合各个渠道的用户数据,判断用户是否符合参与活动的资格、是否为风险用户、是否符合发布要求,并依据用户行为和活动规则进行状态流转。

业务,则是体系的核心价值体现,具有动态性和多样性的特点。它主要涵盖实时行为、滞后行为和被动行为三种类型。

在抽奖玩法活动中,实时行为包括用户在活动页面的即时交互操作,如分享活动链接、浏览活动页面、订阅直播等;滞后行为涉及用户发布内容后的质量评估和审核流程;被动行为则包含数据清洗、数据回扫等后台处理任务。

事件驱动

系统和业务之间的关系基于事件驱动来实现。在活动业务中,事件驱动宛如一条无形却坚韧的纽带,将系统和业务紧密相连,同时又保持各自的独立性。通过事件驱动,系统能够敏锐感知业务的变化与需求,业务也能借助系统的强大能力实现自身目标。

基于事件驱动机制,我们定义了核心的任务模版方法和激励模版方法。不同的任务和激励形式可以根据具体业务需求进行个性化定制,从而实现系统与业务的有效分离。

模块与模块

除了系统与业务的解耦,系统内部模块之间也需要进行有效的隔离。我们引入事件总线架构的思想,将其作为事件发布者和订阅者之间的通信中介。在标准化各模块输入输出接口的基础上,结合哪吒搭建平台,通过配置关联的方式对各个模块进行编排,实现模块之间的通信与协作,同时避免模块间的直接依赖,达到模块解耦的目的。

核心概念&设计

活动系统整体将业务层和系统层拆分为两大板块,通过事件驱动媒介实现二者的隔离与闭环,确保系统层和业务职能清晰明确,为活动业务的可持续迭代发展保驾护航。

活动和任务

随着近期社区活动业务的蓬勃发展与活跃迭代,当前版本的活动体系在应对诸多玩法时愈发显得力不从心、捉襟见肘,主要体现在以下两个方面:

活动层以及奖励粒度的搭配难以满足多元化玩法的需求,存在明显的适配不足。

活动、任务、奖励等层面的个性化要求配置无法充分满足,限制了业务的创新发展。

为此,我们从 “活动与玩法的适配、任务粒度及激励个性化”几个关键方向发力,进行体系重构。

首先,将激励完全抽象为 “激励值”,无论是抽奖次数、瓜分机会、兑换积分、优惠券金额,都以 “值的形式” 进行抽象化处理。

这一抽象设计极大提高了活动、任务和激励之间关系的灵活性,能够满足当前绝大多数活动业务的设计需求。然而,抽象处理也带来了一些问题,例如在用户界面展示方面,难以直观呈现用户在某活动中是否获得过特定奖励。

其次,构建了新的关联框架。单个页面可以关联多个活动,单个活动可以关联多个任务,单个任务可以进一步关联多个任务明细,抽象化的激励值直接与具体任务相关联。

最后,完成三层概念设计。

在活动层,通过设置严格的报名策略和人群筛选条件,确保活动参与的精准性;在任务层,明确任务下发策略、达成条件和执行频率控制,使任务执行更加规范可控;在激励层,设定激励获取上限并制定智能分配策略,实现激励资源的合理分配。通过这种方式,实现了活动、任务、激励之间的自由组合和灵活配置,有效提升了整体运营效率。

任务判定抽离:规则引擎

在传统任务模块代码中,大量的 case 语句导致条件判定逻辑分散在各处。随着业务的不断迭代,业务逻辑变得愈发复杂,逐渐暴露出以下问题:

每次条件改动,甚至是数值调整,都需要开发人员介入,耗费大量人力和时间。

各种条件判断与业务紧密耦合,开发效率低下且难度极大,增加了开发成本和风险。

任务体系的可扩展性和稳定性差强人意,难以适应快速变化的业务需求。

业务透明度极低,团队协作推进困难,新人难以快速上手。

为解决这些问题,我们引入规则引擎,将业务决策逻辑从任务模块中抽离出来。规则引擎通过接收动态数据输入,依据内部预设规则进行计算和判断,输出决策结果,从而实现业务逻辑的独立维护和动态更新。

任务模型

在活动系统中,任务模块扮演着至关重要的角色,主要体现在以下两个方面:

核心驱动力:任务模块是推动活动进展的核心动力源泉。它通过设置一系列明确的任务,引导用户按照活动预期方向进行操作,从而确保活动目标的顺利实现。例如在电商促销活动中,设置 “分享活动页面至社交平台,邀请 5 位好友助力” 的任务,以此扩大活动影响力,吸引更多潜在用户参与。

数据洞察源:任务模块所产生的数据是了解用户行为和活动效果的关键依据。通过分析用户完成任务的情况,如完成率、完成时间等,可以精准洞察用户的兴趣点和参与度,为优化活动策略提供有力支撑。

为应对任务多元化这一挑战,任务模块化成为必然选择。模块化设计将任务拆解为独立的组件,显著提高了开发效率和灵活性。同时,模块化架构便于维护和更新,当某个模块出现问题或需要升级时,只需单独处理该模块,不会影响其他部分,有效降低了业务定制的成本和风险,使任务模块能够更好地适应复杂多变的业务环境。

根据业务特性,我们首先定义了任务接口,并严格划分接口内外的职责边界,确保接口内部专注于业务逻辑实现,接口外部实现系统功能。

任务模型定义如下:

// TaskMode 任务模型

type TaskMode interface {

    // TaskType 任务类型

    TaskType() consts.ActTaskType

    // TaskUniqueFlag 事件唯一标识

    TaskUniqueFlag() string

    // ExpressFunctions 自定义函数集

    ExpressFunctions(ctx context.Context) map[string]govaluate.ExpressionFunction

    // ExpressArguments 任务条件参数搜集器

    ExpressArguments(ctx context.Context, pending []db.PendingTasks) (dto.ExpressArguments, error)

}

具体实现何种任务模型,则参考业务方的实际诉求,只要按照「TaskMode」接口规范进行实现即可。

这里以 “发布篇数任务-TaskPublishTimes” 的实现为例进行说明:

type TaskPublishTimes struct {

    event *dto.TaskPublishEvent

}


func NewTaskPublishTimes(event *dto.TaskPublishEvent) (taskMode TaskMode, err error) {

    if event.ContentId == 0 {

       return nil, errors.New("missing necessary parameters")

    }

    taskMode = &TaskPublishTimes{

       event: event,

    }

    return

}


// TaskType 任务类型

func (t *TaskPublishTimes) TaskType() consts.ActTaskType {

    return consts.ActTaskTypePublishTimes

}


// TaskUniqueFlag 任务唯一标识

func (t *TaskPublishTimes) TaskUniqueFlag() string {

    return fmt.Sprintf("CNT_ID_%d", t.event.ContentId)

}


// ExpressFunctions 自定义函数集

func (t *TaskPublishTimes) ExpressFunctions(ctx context.Context) map[string]govaluate.ExpressionFunction {

    return map[string]govaluate.ExpressionFunction{

       // "WITH_ANY_TOPIC(tag_ids, (1001,1002)) == TRUE"

       "WITH_ANY_TOPIC"func(args ...interface{}) (interface{}, error) {

          // ...

          var intersect, _ = arrayx.Intersect(carryIds, condIds)

          return float64(len(intersect.Interface().([]uint64))) > 0nil

       },

       // 省略部分...

    }

}


// ExpressArguments 条件参数搜集器

func (t *TaskPublishTimes) ExpressArguments(ctx context.Context, pending []db.PendingTasks) (dto.ExpressArguments, error) {

    var eg = gox.NewErrGroup(ctx)

    var args = dto.ExpressArguments{}

   

    // 基础信息

    eg.Go(func() error { /**/ })

    // 互动信息

    eg.Go(func() error { /**/ })

    // 审核信息

    eg.Go(func() error { /**/ })

    // ...


    err = eg.Wait()

    return args, err

}

与传统面向对象编程实现方式相比,Golang 的接口实现更加灵活。只要 Struct 实现了接口定义的所有方法,即可隐式实现该接口,无需显式声明,这种特性为任务模型的开发提供了更高的灵活性。

任务触发器

任务触发器与任务模型相互独立,不存在直接依赖关系。当系统接收到行为事件时,会实例化具体的任务模型,并将其作为参数注入任务触发器,从而驱动系统与任务的协同运行。

任务触发器应与业务逻辑完全分离,所有与业务相关的改动集中在任务模型中,修改后只需针对相应改动点进行回归测试。而与系统相关的改动则集中在任务触发器中,由于这部分改动可能影响所有任务模型的执行结果,因此需要谨慎处理,并确保进行全面的回归测试。

// TaskTrigger 任务触发器

func (s *ActSysTaskService) TaskTrigger(ctx context.Context, taskMode act_sys.TaskMode) (err error) {

    // 用户粒度任务锁

    // ...

    

    // 列表用户任务

    var pending, err = dao.ListUserTasks(ctx, event.UserId)

    if err != nil {

       return

    }

    

    // 二次过滤(任务状态、活动时间)

    // ...

   

    // 自定义函数集 & 条件参数搜集

    var condFunc = taskMode.ExpressFunctions(ctx)

    var condArgs, err = taskMode.ExpressArguments(ctx, pending)

    if err != nil {

       return

    }


    // 任务达成判定

    for _, v := range pending {

       var reach bool

       reach, err = act_sys.RunTaskExpress(ctx, v.TaskCondExpr, condFunc, condArgs)

       if err != nil {

          continue

       }


       if reach {

           // 更新or写入任务明细记录 & 任务进展 & 发放/回退奖励值

           // ...


           // 执行HOOKS(这里是不同业务的个性化订阅者)

           // ...

       }

    }

    return

}

在任务触发器的设计中,重点涉及任务初始化与下发流程。由于行为事件入口众多,难以采用传统方式进行显性任务下发,因此我们将任务下发逻辑嵌入任务触发器中,使每次事件注入触发器时都成为一次任务下发的机会。

当然,这种设计也存在一定风险,在触发器中添加代码可能会对整个任务体系的运行产生影响,甚至可能增加任务推进逻辑的响应时间(RT)。

业务协同

在实现业务功能的同时,系统的稳定性和健壮性至关重要。模块化架构不应成为阻碍业务定制化发展的因素,而应更好地服务于业务创新。在实际业务场景中,如输出当日各核心节点的数据画像、任务完成后对用户进行消息触达等需求,我们通常采用钩子(HOOK)机制,在各个核心节点完成后执行一系列自定义处理逻辑,实现系统与业务的闭环交互。

以高价值奖品兑换活动为例,当用户完成一系列任务后,系统会触发多个钩子,通知业务模块进行风险评估、收益预判、状态更新等操作。同时,业务模块可以通过注册观察者模式,实时监控系统运行状态,如兑换流程是否正常、服务器是否稳定等,一旦发现异常情况,立即进行处理,确保系统和业务的协同稳定运行。

钩子机制

在任务模块化进程中,HOOK 机制发挥了至关重要的作用。

HOOK 机制本质上是一种程序控制技术,它允许开发者在系统运行的特定阶段插入自定义代码。借助这一特性,我们能够在任务触发时、执行过程中、执行完成后等关键节点灵活添加额外逻辑,最终实现业务差异化。

首先,我们需要定义观察者接口、事件主体及其实现,这里以任务明细达成节点为例进行说明:

// ActSysObserver4TaskDetail 任务明细进展转发

type ActSysObserver4TaskDetail interface {

    Unique() string

    Forward(ctx context.Context, detail *db.ActUserTaskDetail) error

}


type ActSysSubject4TaskDetail struct {

    mutex     sync.Mutex

    observers []ActSysObserver4TaskDetail

}


func (sj *ActSysSubject4TaskDetail) Attach(observer ActSysObserver4TaskDetail) {

    if uk := observer.Unique(); len(uk) > 0 {

       sj.mutex.Lock()

       sj.observers = append(sj.observers, observer)

       sj.mutex.Unlock()

    }

}


func (sj *ActSysSubject4TaskDetail) Notify(ctx context.Context, detail *db.ActUserTaskDetail) error {

    for _, observer := range sj.observers {

      if err := observer.Forward(ctx, detail); err != nil {

         return err

      }

    }

    return nil

}


示例仅伪代码,实际业务上应当考虑重复注册、同步执行 or 异步执行、是否强事务等问题。

然后,对于个性化的业务场景,只需实现业务自己的观察者,以打卡玩法触达提醒为例:

// ActTaskDetailObserver2CheckinReach 任务明细进展·打卡玩法的私信HOOK

type ActTaskDetailObserver2CheckinReach struct {

}


func (ob *ActTaskDetailObserver2CheckinReach) Forward(ctx context.Context, detail *db.ActUserTaskDetail) error {

    // 兜底判断任务明细未完成

    if detail.Status != consts.ActTaskDetailStatusDone {

        return nil

    }

    // 触达用户(动态达标提醒)

   return NewReachClient().Send(ctx, "act_checkin_task_detail_done", detail.userId)

}

最后,在初始化时,将观察者注册到主体中即可。

不同的活动玩法最终都是通过观察者模式的设计来实现差异化,甚至任务模块本身也可以通过该方式来实现更上层的任务架构。

  新陈更迭与系统化

新陈更迭

优秀的系统并非一蹴而就的,而是要历经无数次的业务迭代和市场检验,也就必然存在新陈更迭的过程。

从业务层面来看,我们需要清楚当前业务的真实诉求,明确业务功能的拆分方式(从难易程度、风险系数、影响面等多维度考量)。其次,要了解该业务的历史演进及产品习惯,识别新老业务之间可能存在的关联风险。

从技术层面而言,首先要划分清楚能力和业务的界限,其次通过巧妙的设计思路进行分化与衔接。

综合来讲,业务的高质量交付应始终摆在首位,结合业务的粒度去适配新方案的能力,在测试阶段需要明确对齐并进行全面性回归,老方案的业务和新方案的技术应该具备兜底和互动能力,以确保系统的稳定过渡和持续扩展。

走进系统化

在活动系统组件化的基础上,我们以运营标准化提效、数据可视化赋能、协作体系化破局为核心目标,构建全链路协同能力,推动活动业务从 “模块化” 向 “系统化” 跃迁。

我们以三大核心体系为抓手,全面提升活动业务效能:构建可复用的生产体系,依托标准化活动要素库与低代码平台,实现组件化拼装与流程标准化,大幅降低开发成本、提升上线效率;打造智能决策中枢,整合多维度数据,通过实时监控与智能分析驱动策略优化,助力运营从经验驱动迈向数据决策;打通跨团队协同链路,统一协作标准、集成开发工具链,并成立中台委员会推动能力沉淀,有效减少重复工作、缩短迭代周期,破除部门协作壁垒 ,最终推动活动业务从 “模块化” 向 “系统化” 全面跃迁。

  展望潮流生态

得物社区活动业务将以组件化、系统化成果作为基石,持续深化创新。

随着 AIGC、边缘计算等前沿技术的融合应用,活动系统将朝着 “智能自优化” 加速迈进。一方面,通过 AI 算法精准预测用户兴趣与行为趋势,自动优化活动策略与任务设计,让潮流内容与用户需求实现更高效匹配。另一方面,借助边缘计算降低数据处理时延,为用户带来更流畅、即时的活动交互体验。

在商业价值与文化影响力层面,得物将进一步打破潮流文化与电商消费的壁垒,通过活动业务构建更紧密的用户、品牌、文化生态闭环。未来,无论是小众潮流文化的破圈传播,还是品牌与用户间的深度情感联结,得物都将凭借不断进化的技术与创新模式,持续引领潮流社区电商的发展风向,书写行业新篇章。


往期回顾


1.得物研发自测 & 前端自动化测试体系建设

2.从CPU冒烟到丝滑体验:算法SRE性能优化实战全揭秘|得物技术

3.得物自研DScript2.0脚本能力从0到1演进

4.社区造数服务接入MCP|得物技术

5.CSS闯关指南:从手写地狱到“类”积木之旅|得物技术


文 / 小龙


关注得物技术,每周一、三更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

扫码添加小助手微信

如有任何疑问,或想要了解更多技术资讯,请添加小助手微信:

阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

得物 社区活动 组件化 潮流电商 规则引擎
相关文章