
一. 平台对业务敏捷支撑的挑战
早期的交易平台的下单流程是硬编码方式写死的。整个流程,无论什么业务,都必须要与优惠系统、物流系统、卡券平台等系统对接。新业务开发时,必须要确保整个下单过程与这些服务的集成不会出现调用异常,一旦有异常出现,就需要与相关系统协调看如何屏蔽错误。
- 商品单价计算逻辑也没有很好在平台中得到解耦,也没有提供可扩展机制。汽车金融业务的商品单价是来源于支付宝的微贷系统。最终,该业务也只能以硬编码方式,在平台计算商品单价的地方,与其他业务的代码混在一起去编写相关计算逻辑。这部分代码因为可能会影响到其他业务,所以代码在发布上线前,必须经过严格的全网回归验证,以确保不会对其他业务产生影响以及资损。
- 汽车金融业务的发布节奏因此也必须跟随平台版本的节奏,只能耐心的等待每周一次的全网回归验证后,才能进行发布,无法按自己的意愿随时发布。
以上内容来自: 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(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