目录
一、快速了解抽象思维
(一)抽象思维的本质理解
(二)系统架构中的重要性
(三)软件开发中抽象的基本过程思考
意识和手段
抽象的方式
抽象层次的权衡
二、业务中的应用实践
(一)业务背景和研发挑战
(二)营销系统目标架构
(三)实践解决方案
问题域的顶层抽象
子问题的抽象与解决
共性统一解决、差异开放扩展的展品子系统
基于模块化、模板化和函数化的互动子系统
产品功能标准化、安防体系化的优惠子系统
横纵向稳定性建设
参考文章链接
一、快速了解抽象思维
(一)抽象思维的本质理解
抽象思维是一种认知和思维方式,通过在众多事物中提取共同的、本质性的特征,舍弃非本质的特征,形成概念、判断、推理等思维形式,以反映事物的本质和规律。抽象是将复杂的现实世界简化为更易于理解和处理的概念或模型的过程。这种思维方式使人们能够通过一般性的规律和原则来理解和处理复杂的现实情境。
在抽象思维中,人们通过对感性材料的加工制作,去粗取精、去伪存真,从具体事物中提炼出普遍性的特征。这有助于人们更有效地组织和理解信息,提高认知效率,并使得复杂的问题变得更加可管理。抽象是认知过程中的一种重要手段,常常涉及到将具体事物归纳为更一般的概念,从而使得我们能够处理更广泛和复杂的信息。
比如,当我们面对如地球上大约150万种不同的动物这样庞大而复杂的现实情境时,要一一认知和理解每一种动物几乎是不可能的任务。这是因为每种动物都有其独特的特征、行为和生态系统,涉及的信息量巨大且复杂。
动物学家们采用了抽象思维的方法,将这些多样性的动物进行分类。他们从所有动物中提取了一个共同的、本质性的特征,即是否有脊椎。这一抽象分类首先将动物分为两大类:脊椎动物和无脊椎动物。这是一个对复杂事物进行简化的抽象过程。
然后,对脊椎动物这一类别进行进一步的抽象和细分,将其分为鱼类、爬行类、两栖类、鸟类以及哺乳类等亚类。这一层次的抽象进一步简化了分类,使我们能够更轻松地理解动物的整体组织结构,而不必深入研究每个具体的物种。
通过这种抽象分类,我们可以以更高效的方式了解动物界的多样性,而不必被每个具体动物的细节所淹没。这个过程不仅提高了对动物的认知效率,还为进一步的研究和了解提供了有序的框架。这个例子突显了抽象思维在处理庞大而复杂的信息时的重要性,通过将信息层次化和分类,我们能够更好地理解和应对复杂的现实世界。
(二)系统架构中的重要性
“编程中最重要的三件事是:抽象,抽象,抽象”。抽象是计算机科学中许多工作的中心,它包括为系统定义正确的接口以及为系统实现设计合适的架构。 在计算机科学中,抽象是指高级的模型,是和低级的实体相对的。
例如,在面向对象编程中,“鸟”是抽象模型,具有羽毛、没有牙齿、会下蛋等共性特征,“大雁”、“鸭子”和“企鹅”是具象实体,它们继承了“鸟”的共同特征,同时具备个性差异,比如“大雁”会飞,“鸭子”和“企鹅”不会飞。
从系统实现角度看,经过这样的模型设计之后,“大雁”在代码实现上就无需从头开始对每一项属性和功能进行编程,而是在继承抽象类“鸟”的共性基础上,专注于“飞”等差异逻辑的实现。因此,在计算机科学中,抽象通常意味着化繁为简并将共性与差异分离,使得一大堆底层代码变得可移植和可复用,从而可以更加高效地实现和演进软件系统。
从系统使用角度看,通过抽象化的模型设计,“大雁”、“鸭子”和“企鹅”的功能被拆解提炼为“下蛋”、“飞”等极简的接口或者方法,使得使用方可以在不了解它们如何提供功能的情况下使用它们,极大地简化了复杂性。
通过上述案例我们可以认识到,抽象思维能够帮助我们极大地提升解决问题的效率,具体而言,它可以帮助我们:
- 化繁为简: 抽象思维通过将问题分解、分类、拆分,帮助将复杂的问题简化为更易于处理的部分。这个过程就好比在森林中迷失了方向,抽象思维就是通过识别并跟踪主要特征,从整体中剥离出关键元素,使得问题的复杂性降低,进而更容易找到解决方案。
- 由表及里: 抽象思维有助于我们看到问题的本质,而不仅仅是表面现象。在面对一个问题时,很多时候我们首先看到的是外部的表象,而抽象思维则能够帮助我们深入探究问题的核心原因和关键驱动因素。这种方法类似于医生对病人的诊断,不仅仅看症状,还要找到病因。
- 举一反三: 抽象思维帮助我们将具体问题升华为一般性的原则或模型。这就像是学习数学,通过理解一个问题的解法,我们可以推广到解决类似类型的问题。这种抽象过程使得我们能够以更高效的方式处理问题,而不是每次都从零开始思考。
综合来看,抽象能力是一种关键的底层思维能力,它并不仅仅局限于计算机科学和软件开发领域,而是贯穿于我们解决各种问题的过程中。通过抽象,我们能够更清晰地定义问题、更深入地理解问题的本质,从而更有效地找到解决方案。这种思维方式不仅在解决具体问题时有用,还有助于我们更全面地理解世界,提升对复杂现象的认知水平。
(三)软件开发中抽象的基本过程思考
抽象在软件开发中是一个基本而重要的过程,其核心目标是提取事物的共性,以便通过纵向和横向分层将复杂问题分解成可管理的小问题,实现通用能力的重复利用,从而降低系统构建的复杂度。
意识和手段
抽象过程首先需要一种正确的意识,即在问题分析中要超越表面,站在更高的层次来看待问题。这意味着不仅仅要看到问题的具体细节,还要理解问题的本质和共性,从而进行有效的抽象。
在软件开发中,抽象有两种基本方法,即自下而上和自顶而下。通过业务建模等手段,可以自下而上地从具体业务中提炼出模型和数据结构。而通过软件系统设计等手段,可以自顶而下地从整体出发,逐步定义系统的结构和模块划分。
抽象的方式
- 自下而上: 这是一种从局部到整体的抽象方式,即从小到大,通过业务建模等手段自底向上地归纳和演绎。这种方法关注局部细节,逐步构建出系统的整体模型、模块和服务。例如,在面向对象的开发中,从业务实体中提取出类和对象,逐步建立起系统的整体结构。
- 自顶向下: 这是一种从整体到局部的抽象方式,即从大到小,通过软件系统设计等手段自顶向下地拆解和切分。这种方法注重整体架构和系统的高层次设计,通过逐步拆解和细化,最终形成系统的模块、服务和组件。例如,在软件系统设计中,从整体业务需求出发,逐步分解成各个子系统和模块。
抽象层次的权衡
在软件系统设计中,抽象层次的选择至关重要。权衡抽象层次是指根据业务场景的需要,在抽象设计过程中选择合理的层次。过高的抽象层次可能导致过度泛化,而过低的抽象层次则可能导致失去通用性。例如,在接口设计中,选择参数类型时需要权衡通用性和类型约束力,以避免潜在的类型转换异常问题。
总体而言,抽象是软件开发中的基本思维和方法之一,通过合适的抽象,我们能够更有效地解决问题,提高系统的设计质量和可维护性。
二、业务中的应用实践
查看高超的文章《抽象思维及其在点评广告营销系统中的实践》(见下文链接),可以学习看下美团的应用实践
(一)业务背景和研发挑战
广告营销系统是大众点评平台的关键支撑,其主要业务目标旨在为平台创造可观的商业收入。通过在美团/点评App上提供广泛而多元的广告营销方案,系统致力于为境内外品牌客户打造全面有效的广告解决方案。这一业务模式的核心是在移动应用平台上为品牌客户提供一揽子的广告服务,其中包括但不限于品牌传播、获客引流和销量提升等多方面的关键业务。
在整体上,广告营销系统通过其在大众点评平台上的精准定位和服务,为品牌客户提供了一个强大而综合的广告推广平台。通过实现品牌建设、客户引流和销售增长等关键业务目标,系统为大众点评平台的商业收入创造打下了坚实的基础。业务整体的发展如下:
在业务稳定期,研发团队的工作方式发生了变化,从以往的需求驱动型逐渐过渡到技术驱动型。技术驱动要求研发同学具备高度主动性和独立思考能力,需要他们主动思考并定义当前影响业务发展的问题,并制定相应的技术规划来解决。在定义问题时,采用抽象思维对问题进行简化,由表及里有助于提高解决问题的效率。为支持业务实现目标,研发团队需要解决以下问题和挑战:
-
需求频率高且多变: 广告营销业务面向外部客户,需求不确定性大且节奏多变。如何在不增加研发资源的情况下,确保按期交付成为首要挑战。
-
客户需求方案多样: 面对来自各行各业的品牌客户,需求方案多样化。建设可复用的解决方案成为降低高投入成本的挑战。
-
系统规模快速增长: 随着业务发展,系统规模不断增大,对技术运营的要求也随之增加。如何控制系统复杂度,保障系统稳定运行成为底线挑战。
这些挑战要求研发团队在技术驱动下,更加注重主动思考问题,采用抽象思维简化复杂性,以提高解决问题的效率。
(二)营销系统目标架构
(三)实践解决方案
在解决研发挑战时,引入了马斯克所提倡的第一性原理,即回归事物最基本的条件,通过拆分为各要素进行解构分析,找到实现目标最优路径的方法。
对于前述的三个研发挑战,实质上都涉及到软件系统的复杂性,这种复杂性导致了低效率、低质量和高成本。软件复杂性主要由不确定性、无序性、规模和认知成本构成:
其中,认知成本和不确定性依赖于对业务问题的定义与解构;无序性则取决于解决方案的有效性,可以通过标准化和结构化来保持系统有序;规模是客观存在的,可以通过分而治之和提高解决方案的复用性来解决。
因此首先,从业务出发,尝试在业务中找到简化问题的可能性;接着,通过有效的业务建模进一步简化问题的复杂度;最后,选择合适的架构来表达业务模型。在业务发展过程中,我们需要循环上述流程,不断适应变化。这种方法有助于降低软件复杂性,提高系统的效率和质量。
问题域的顶层抽象
在构建理想的营销系统之前,我们首先需要深入了解营销业务的本质。通过从本质出发,我们能够更容易地找到解决问题的杠杆点。营销业务的最终目标是服务消费者,因此从消费者的角度出发,我们通常需要回答三个关键问题:“这里有什么?”(what)、“我为什么要参与?”(why)、“我怎么参与?”(how)。
这三个问题的答案直接对应了营销系统能力的三个核心要素,即展品、优惠和互动。这构成了我们对营销系统的顶层抽象。简要解释如下:
-
展品(What): 涉及了消费者关心的产品或服务,即营销活动中的展示物品。消费者需要清楚了解在这个营销平台上有哪些产品或服务可供选择。
-
优惠(Why): 针对“我为什么要参与”这个问题,优惠是一个重要的激励因素。消费者希望知道为什么参与这个营销活动会对他们有利,可能涉及到价格优惠、特别优惠或其他吸引人的福利。
-
互动(How): 涉及到参与的具体方式和交互过程。这包括消费者如何参与到营销活动中,如何获得优惠,以及他们与平台之间的互动方式。
通过理解这三个核心要素,我们可以更系统地设计和构建营销系统,确保它能够满足消费者的基本需求,提供有吸引力的产品或服务,激发他们的参与兴趣,并提供简便而愉快的互动体验。这样的系统能够更好地服务于业务的本质,提升用户参与度和满意度。
在完成对营销能力的顶层抽象之后,要解决的核心问题逐渐明了,系统的全景图也逐渐清晰。接着,就是从业务发展趋势出发,逆向思考技术侧现状与理想目标之间的差距,进而寻找应对策略,最后基于对营销能力的抽象,拆解出具体的关键任务:
-
展品子系统:收敛营销需求中展品领域的解决方案,以更方便地获取展品,更高效地处理展品,更灵活地展示展品。
-
互动子系统:构建支持可插拔、可编排、可配置的互动组件库,以降低互动需求的研发交付时长,并提升互动模块的可靠性。
-
优惠子系统:建设一站式电子奖券系统,通过配置化支持各类奖券的制作,并提供标准化的发券、用券能力,以及体系化的优惠权益安全防控能力。
此外,在技术运营方面,要以不发生严重级事故为目标,完善系统的稳定性保障措施,降低系统发生事故的概率,并提升团队人员应对风险的能力。
子问题的抽象与解决
共性统一解决、差异开放扩展的展品子系统
展品是抽象出的概念,实际对应展示营销中的营销标,也就是营销活动中展示的商户、外卖、团购、评价等。在过去的技术实现上,针对展品领域的需求做了部分代码级复用,但还需要经历完整的需求分析、方案设计、系统实现和测试上线过程。
为了降低展品领域的开发和维护成本,期望用一套系统解决展品领域的绝大部分需求。但是实际需求总是存在与设想形态偏离的情况,例如A活动期望通过九宫格的方式展示商品,而B活动希望用单排列表的方式展示。
因此,需要通过抽象建模,分离需求中的共性和差异部分, 针对共性部分可以建设面向流程、面向服务和面向功能的统一能力来解决,对于差异部分,比如数据结构的差异、展品字段的差异或者展示样式的差异,可以开放扩展点,以提升系统应对变化的能力。
确定了解决思路,接下来就是业务建模,也就是用合理的技术语言将业务问题精确地翻译成技术问题,然后再寻找解决问题的方法。
从具体案例出发,结合分层原则,将展品子系统分为如下图所示的三层
- 中间的一层定义了展品的身份,包括它是哪个业务线的,以及它是通过自建存储还是对接外部服务来实现数据管理的,为如何支持展品的统一管理打下基础;
- 最上面一层聚合了展品的共性部分,包括展示规则、排序规则和展示时间等,为提升展品系统的复用性奠定基础;
- 最下面一层是展品模型的具体定义,包括展品类型、展品属性等,并提供扩展能力。
从抽象模型出发,结合统一流程,进行领域拆分、功能细化,可以得出展品子系统的全景图:
- 首先,在流程的统一上,遵循求同存异的原则,实现展品处理流程的最大化统一。
- 其次,在领域服务的拆分上,以展品模型为基础,对标业务流程,遵循职责内聚的原则,将系统分为供给域、加工域和查询域,分别对应展品数据的接入、处理和输出能力。
- 最后,在展品系统功能的统一上,通过无需开发代码的配置化解决80%的共性,开放扩展点应对20%的差异。
基于模块化、模板化和函数化的互动子系统
互动营销主要强调的是用户和客户之间的互动,从而培养用户对客户品牌的认知和购买欲,常见的互动形式有做任务领奖励、社交互动、知识问答等。互动在技术上意味着有较多的写操作,相比只读场景的展示营销,有着更高的系统复杂度,因此也更容易出bug。过去,针对互动营销需求,在技术建设上主要是通过沉淀独立的组件,例如点赞、收藏、留资、抽奖等,来提高研发效率的,但是一个互动需求还是需要在互动逻辑编排上投入较多的开发、测试和维护成本。
这次优化的目标是,实现系统性的研发质效提升,互动需求的零开发支持率提升至90%以上,反映提测质量的千行代码bug率能够控制在0.5%以内。
为实现这个目标,采用抽象分治法。首先,对过去交付的需求案例进行总结分析,将互动营销玩法进行抽象分类,任务类互动玩法占比65%左右,社交类玩法占比30%,其他的一些定制小游戏等玩法占比5%。其中,任务类和社交类玩法的确定性较高,可以在组件化的基础上采用模块化、模板化等手段来进一步提升系统的复用程度,而对于变化较多的其他类玩法,可以通过函数化来降低定制需求的开发、部署和运维成本。这样一来,我们在面对互动营销需求时,可以在开发、测试和运维方面得到质的提升。此外,可以通过提升存量代码的单元测试覆盖率,减少代码变更的频率,来提升代码质量。
模块化是以业务逻辑为单元的抽象,它是对以代码单元为主的组件化的进一步抽象,使得每个模块都包含着执行预期功能的一个唯一方面(aspect)所必需的所有东西,例如,任务模块是基于任务组件、推送组件、签到组件等构建的,提供了创建任务、分发任务、展示任务列表和状态流转通知等一个任务产品模块应该具备的所有功能。
换言之,模块化可以用来分割,组织和打包软件,每个模块完成一个特定的、标准化的子功能,并且它的功能是可扩展的,将这些模块按某种方法组装起来成为一个整体,可以完成整个系统所要求的功能,某个模块在不被需要的时候也可以独立拆卸。因此,基于模块化构建的互动子系统在复用性、易测性(每个模块可以独立测试)和可靠性(每个模块可以独立部署,运行时互不影响)上可以得到进一步的提升。
模板化是基于范式的抽象方法,它的主要思想是,定义一个操作的一系列步骤,对于某些暂时不确定的步骤,就留给子类去实现,这样不同的子类就可以组成不同的步骤。因此,模板方法的核心在于定义一个“骨架”。在互动营销需求中,经常遇到这类需求:
“当用户关注了xx官方号后,们就给他发张优惠券”
这种需求经过抽象,可以提炼出一种范式,叫IFTTT,是“If This Then That”的缩写。简而言之,IFTTT就是基于条件触发的任务,是这类需求的模板“骨架”,即“若xx发生yy行为,就执行zz动作”。其中,每一个可以发生行为的场景叫做一个Channel,触发的条件叫Trigger,之后执行的任务叫Action,这一整套流程就叫Recipe。
基于IFTTT的基本理念,可以实现“由简单组成的复杂”,即由众多简单的IFTTT流程相互衔接,组成跨组件、跨模块的复杂流程。相比于面向过程的传统开发方式,基于范式的模板化开发模式可以减少简单重复的代码开发、缩减系统规模,从而极大地提升开发效率,降低运维成本。
在模块化、模板化的技术建设中不可避免还会遇到一些超出预期的需求。
针对这类需要定制化开发的需求,过去有两种方案:
- 一是“All In One”,也就是将这类需求的实现收敛在一个单体服务中,这样可以不用从0到1搭建服务,一些非功能性需求的代码也可以复用,开发效率较高,但是因为单体服务在运行期未隔离、服务体积也会不断增长,所以存在稳定性差和可维护性差的问题;
- 二是“微服务”架构,也就是为每个需求搭建一套独立的服务,这样可以解决稳定性的问题,但是存在开发成本高、机器资源利用率低的问题。
这两种方案各有利弊,如果将它们的优势叠加,就能完美地解决定制化开发需求的效率问题。当认识到问题的本质后,就比较容易找到解决方案,这里引入了函数化的解决方案,也就是业内新的一代开发模式FaaS(函数即服务,Function as a Service)。
基于FaaS(这里采用了我司的Nest平台),可以在开发期仅关心占比20%的业务逻辑,由框架解决占比80%的非功能性需求;而在运维期,业务开发可以实现秒级发布,也无需关注机器层面的容量评估、扩缩容、容灾、升级、下线等日常运维事务,可以节省大量的机器资源成本和技术运营人力成本,从而达到提效、提质和降本的目的。
产品功能标准化、安防体系化的优惠子系统
优惠是做好营销必不可少的元素,它可以激励用户更好地参与到营销活动中。
过去,在优惠需求领域遇到的主要问题包括两个:
- 一是交付效率低,因为优惠产品形式多样,而且经常需要与客户系统对接,不确定性较高;
- 二是安全风险高,因为优惠模块一旦出问题就意味着直接的经济损失。
针对这些问题,纵观优惠产品生命周期,从优惠券的制作、发放和核销这三个主要环节入手,分析相关的研发挑战和安全风险,进而提出实现标准化的优惠产品解决方案和体系化的风险管控体系的目标以及相应的设计思路。
为了建设平台化的优惠系统,提供标准化的产品功能,需要从用户视角抽象推导标准的奖券模型。这里采用分析归纳法,并用“5W1H”提问法来验证模型的完整性:“用户(who)为了获得某种优惠(why),在什么时间(when),来到什么地方(where),满足什么条件(how)的情况下通过核验兑付权益(what)?”,从而推导出奖券的基本六要素:
- 奖券权益:抽象权益维度,表示奖券所有者能够享受的权益。
- 兑付时段:抽象时间维度,表示奖券所有者可以兑付权益的有效时段。
- 适用商户:抽象空间维度,表示奖券所有者可以兑付权益的地方。
- 使用规则:抽象规则维度,表示使用权益需要满足的条件。
- 凭证标识:抽象标识维度,表示奖券的唯一标识,用于权益在使用时的确权。
- 核验模式:抽象核验方法维度,表示使用何种方式核销权益。
通过抽象提炼出奖券的基本要素后,接下来就是从平台视角泛化设计奖券的模型,为设计可扩展的优惠系统架构奠定基础。
首先,是对奖券模型进行分层,我们从“什么券?”、“怎么发?”和“怎么用?”三个问题出发,将奖券模型分为三层;其次,针对奖券的基本六要素,设计抽象接口,以支持扩展,例如兑付时段可以是动态时段,也可以是固定时段;最后,从平台视角出发,扩充系统功能,包括业务标识、管理模式、库存、发放规则等,以实现较为完整的优惠系统功能。
营销安全是优惠子系统面临的最主要的挑战,为了防止规模性的资损事件发生,需要构建体系化的安全保障方案。如图所示,从制定优惠营销安全应对原则出发,一方面是通过组织团队定期学习公司、行业的营销安全事故案例,从而提高安全意识;另一方面,针对业务流程中的制券、发券和用券核心环节,以及数据存储构建立体化的安全保障手段。从而构建在事前预备兜底方案,事中及时感知并处理异常,事后总结复盘不断改进的安全防御体系。
横纵向稳定性建设
展品子系统、互动子系统和优惠子系统可以独立存在,但在大多数需求场景中,它们需要通过组合、联动形成整体。因此,从营销系统整体出发需要在横向和纵向上进行综合性的稳定性建设,以保障营销活动稳定地运行。
首先,在横向稳定性建设上的关注点是活动的资损和客诉,这是直接反映技术交付质量的指标。为了控制好这两个指标,制定了“防备下游、怀疑上游、做好自己”的稳定性建设策略。但是,一年需要交付几百个营销活动,怎么平衡稳定性建设成本与效率呢?对过去的营销活动分析后发现,活动流量和风险分布是符合2/8原则的,80%的稳定性问题集中在20%的活动上。因此,计划建立活动评级机制,根据风险评估的活动定级S/A/B,进行稳定性保障资源的分配,从而最大化稳定性建设的收益与投入比。
在纵向稳定性建设上关注点是各个子系统、子功能的稳定性,例如抽奖组件是否是高可用、高可靠的。然而,和上面遇到了同样的挑战,营销系统的功能模块有上百个,如何平衡稳定性建设成本与效率呢?我们从功能模块的变化频率和风险等级两个维度,将所有营销功能组件分为四类,进而按系统模块的风险等级和易变性,拆分出系统模块的稳定性保障优先级,再针对性地做好系统在运行时的解耦和分层分级运维。
参考文章链接
抽象思维及其在点评广告营销系统中的实践
基本思维篇--抽象思维 - 知乎