探究平台化设计的核心思想和Lattice的设计原则
一. 平台对业务敏捷支撑的挑战
早期阿里的交易中台遇到了一些挑战,这个在毗卢的博客中有提到,主要遇到了这些问题:新小业务都有一个成长规律,在早期业务模式验证阶段,需要的玩法比较简单,希望能频繁的发布快速试错。我们以电商领域为例,在成熟的电商体系下,有众多复杂、庞大的平台,如交易平台、商品平台、营销平台等。虽然这些平台对于天猫、淘宝各种业务模式、玩法都支撑得很好,但对于新小业务而言,这些模式、玩法在早期并不适用,他们希望平台能按照自己的要求做一些裁剪。
- 早期的交易平台的下单流程是硬编码方式写死的。整个流程,无论什么业务,都必须要与优惠系统、物流系统、卡券平台等系统对接。新业务开发时,必须要确保整个下单过程与这些服务的集成不会出现调用异常,一旦有异常出现,就需要与相关系统协调看如何屏蔽错误。
- 商品单价计算逻辑也没有很好在平台中得到解耦,也没有提供可扩展机制。汽车金融业务的商品单价是来源于支付宝的微贷系统。最终,该业务也只能以硬编码方式,在平台计算商品单价的地方,与其他业务的代码混在一起去编写相关计算逻辑。这部分代码因为可能会影响到其他业务,所以代码在发布上线前,必须经过严格的全网回归验证,以确保不会对其他业务产生影响以及资损。
- 汽车金融业务的发布节奏因此也必须跟随平台版本的节奏,只能耐心的等待每周一次的全网回归验证后,才能进行发布,无法按自己的意愿随时发布。
以上内容来自: https://www.ryu.xin
有赞交易遇到的瓶颈
早期的有赞交易也遇到类似的问题,17年以后公司迅速发展壮大,团队规模扩张了数倍,业务线也从单一的微商城电商交易扩展到多个垂直行业。然而,交易团队却面临了许多尴尬的情况:
首先是垂直行业的接入问题,由于交易团队的响应速度无法跟上业务团队的迭代速度,垂直行业被迫自行开发了一套针对自身业务的交易系统,导致公司技术资源浪费。这包括商业化服务订购、收银、批发等业务。
其次,交易团队新加入的成员发现交易核心开发非常困难,必须先完全理解整个系统,才敢尝试开发,这增加了学习成本。
另外,许多交易玩法无法组合,如果想要组合,就必须重新编码,将组合方案作为一个新方案进行开发,例如虚拟商品的拼团业务、酒店的分销业务等。这限制了产品运营同学创意想法的快速实现。
最后,一个小需求的上线可能会导致核心交易系统大面积故障,影响无法隔离。
二. 基于可复用模式的平台支持:加速业务发展
在现代企业架构中,企业级业务架构规划已经关注面向能力的规划,超越了面向功能与服务的规划。如何通过能力的识别和规划来最大化沉淀企业级可复用能力,以及如何将这些能力应用到更多的场景中,通过扩展、编排和组合等形式,是平台型企业架构需要解决的核心问题。为了应对业务的快速迭代、多场景和不确定性,企业需要在平台上构建可复用的“能力”,并为这些能力提供必要的扩展和可变机制,以便为不同前台提供灵活多变的业务服务,满足不同前台的差异化个性化需求。这些“能力”可根据粒度的不同,细分为“基础能力”、“能力组件”和“解决方案”三个层级。不同业务的差异性可以通过“能力的扩展点”设计和不同“业务身份”在扩展点上的“扩展实现”进行区分。
说明:基础能力、能力组件和解决方案概念来自ThoughtWork现代企业架构白皮书
下单的基础能力
在现代企业架构中,基础能力被认为是支撑业务运营的关键要素。例如,交易下单的一些基础能力包括快递可达性和同城可达性校验、下单扣减库存、支付扣减库存、子订单计价能力、收单能力等。这些基础能力的识别和规划对于企业级业务架构的规划至关重要。通过将这些基础能力沉淀成为企业级可复用的能力,企业可以在多个场景中应用这些能力,从而最大化效益。
为了更好地应对业务的快速迭代、多场景和不确定性,企业需要在平台上构建可复用的能力,并提供必要的扩展和可变机制,以此为不同的前台提供灵活多变的业务服务,满足不同前台差异化个性化的需求。这些能力可以分为三个层级:基础能力、能力组件和解决方案。基础能力是企业架构中最基本的能力,而能力组件则是由多个基础能力组成的较高层级的能力。最高层级的能力则是解决方案,它是一组能力组件的集合,可以满足特定的业务需求。
在不同业务之间的差异性,则可以通过能力的“扩展点”设计和不同“业务身份”在扩展点上的“扩展实现”进行区分。通过这种方式,企业可以针对不同业务的需求,快速扩展和定制能力,从而满足不同的前台业务需求。
三. Lattice能力的定义
能力模型(Ability)
针对买家下单过程中需要计算运费和创建物流订单的场景,在电商交易中,我们可以为不同的业务场景设计各种物流方案。例如,在国内不同城市之间的物流配送中,可以针对不同地区的快递可达性和同城可达性进行校验,以便为买家提供最佳的配送服务。在下单后,我们可以利用基础能力,如下单扣减库存和支付扣减库存,来保证订单的准确性和库存的实时管理。
除此之外,我们还可以考虑如何在不同的业务场景下,通过扩展和组合不同的能力来提供更灵活和个性化的服务。例如,为了应对高峰期的订单量激增,我们可以通过组合子订单计价能力和收单能力,来提高交易系统的处理能力。同时,我们也可以通过基础能力的不断扩展,如增加新的快递配送服务、更加灵活的计费方式等,来满足不同业务的差异性和个性化需求。
在实现可复用的能力方面,我们需要考虑基础能力、能力组件和解决方案这三个层级的划分,并为不同业务场景设定扩展点和扩展实现,以实现更加灵活和个性化的服务。通过这样的方式,我们可以最大化地沉淀企业级可复用的能力,并为业务的快速迭代、多场景和不确定性提供支持。
- 传统通过快递进行配送的物流方式(例子中,我们定义 NormalLogisticsAbility)
- 基于线下门店自提方式进行履约的物流方式。 这种方式,货品发到门店,但交易订单产生后不会有实际物流,用户需要人肉到线下门店去提货。比如,买轮胎,轮胎不是寄到家里,而是自己开车去4S店去安装已购买好的轮胎。 (例子中,我们定义 OfflineLogisticsAbility)
- 虚拟物品发货方式:比如卡密等商品。。
无论这些物流方式外在的差异有多大,但他们总有一些共性的功能是可以抽象成统一的接口。比如,无论何种运输方式,他都需要计算运费价格、需要在物流订单上保存物流信息等。平台> 则以面向接口的方式,去调用这些抽象好的接口,最终可实现平台内核稳定,同时也能支持未来新的运输方式的扩展。
@Ability(name = "OrderLine's Price Ability")
public class OrderLinePriceAbility extends BaseLatticeAbility<OrderLinePriceExt> {
public OrderLinePriceAbility(OrderLine bizObject) {
super(bizObject);
}
public Long getCustomUnitPrice(OrderLine orderLine) {
return Optional.ofNullable(reduceExecute(p -> p.getCustomUnitPrice(orderLine),
Reducers.firstOf(Objects::nonNull)))
.orElse(orderLine.getUnitPrice());
}
@Override
public BlankOrderLinePriceExt getDefaultRealization() {
return new BlankOrderLinePriceExt();
}}
能力SPI扩展(Extension)
能力是指某种实体或个体在特定环境下展示出的可行动的潜能,而这些行动是可以被扩展的。就像人的手,它天生具备抓握、捏取等能力,但是通过加装手套或者增加外挂,比如手指尖的抓握延伸器等,就能够进一步扩展手的功能,让人具备更多的操作能力。类似地,在电子商务的场景中,为了满足不同的需求,我们需要根据不同的物流方案来计算运费和创建物流订单,这些行为的实现也是可以通过扩展不同的能力来完成的。
总的来说,能力不仅仅是一个固定的概念,而是可以通过不同形式的扩展和组合来实现更多的行为,从而适应不同场景和需求的。
定义一个“自定义子订单商品单价”的扩展点,允许业务能够去实现该扩展点,返回商品的自定义单价
public interface OrderLinePriceExt extends IBusinessExt {
String EXT_ORDER_LINE_CUSTOM_UNIT_PRICE = "OrderLinePriceExt.EXT_ORDER_LINE_CUSTOM_UNIT_PRICE";
@Extension(
code = EXT_ORDER_LINE_CUSTOM_UNIT_PRICE,
name = "Custom the Item's unit price of OrderLine",
reduceType = ReduceType.FIRST
)
Long getCustomUnitPrice(OrderLine orderLine);
}
业务(Business)
"关于垂直业务"可以用"行业"来替代。这是因为每个行业都有自己的一套规则和标准,而不同的行业之间存在明显的差异。虽然有时候会有跨界合作,但是对于某些行业的规则和术语,只有在这个行业内部的人才能真正理解。这就好比在不同的山间穿梭,每个山谷的景色都不尽相同,需要有足够的经验才能明白其中的奥秘。
在编程中,我们使用 @Business 注解来定义业务,例如业务A,编码为 "business.a"。这有助于我们更好地区分不同的业务,并为每个业务定义其独特的规则和逻辑。
@Business(code = "business.a", name = "Business A")
public class BusinessA extends BusinessTemplate {
}
然后,针对业务A,定义它的商品自定义单价为 2000 (单位分)。
@Realization(codes = "business.a")
public class BusinessAExt extends BlankOrderLinePriceExt {
@Override
public Long getCustomUnitPrice(OrderLine orderLine) {
return 2000L;
}
}
产品(Product)
产品是一个服务,有完整功能、能对外输出并能形成业务场景,快速支撑业务场景的功能集合体。定义团购场景 “GroupBuyProduct” 产品
@Product(code = GroupBuyProduct.GROUP_BUY_PRODUCT_CODE, name = "Group Buy Trade Product")
public class GroupBuyProduct extends ProductTemplate {
public static final String GROUP_BUY_PRODUCT_CODE = "lattice.productGroupBuyProduct";
@Override
public boolean isEffect(ScenarioRequest request) {
if (request instanceof BuyScenarioRequest) {
boolean effect = StringUtils.equals("groupBuy", ((BuyScenarioRequest) request).getSource());
System.out.println("GroupBuyProduct effect status:" + effect);
return effect;
}
return false;
}
}
一旦我们识别和构建了平台的基础能力和能力组件,就可以让不同的业务根据其特定需求来复用这些能力并快速进行定制。这可以通过配置和开发基础能力下的扩展点来实现,以下是示例:
(图片来自ThoughtWork)