样例说明

通过本样例,您可以了解:

  1. 一个面向场景的水平业务(产品)是如何定义的
  2. 扩展点有多个实现时的冲突决策机制
  3. 一个业务会话的构建过程

环境准备

您需要:

  1. 用于运行程序的IDE(集成开发环境),比如IntelliJ IDEA 或其类似工具;
  2. Java™ Development Kit (JDK),需要JDK 8及以上版本
  3. 已经完成 Quickstart Guide 样例

版本依赖

<dependency>
      <groupId>org.hiforce.lattice</groupId>
      <artifactId>lattice-model</artifactId>
      <version>1.0.5</version>
</dependency>
<dependency>
      <groupId>org.hiforce.lattice</groupId>
      <artifactId>lattice-runtime</artifactId>
      <version>1.0.5</version>
</dependency>

Step 1:定义团购场景 “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;
    }
}

产品定义需要用 @Product 注解标识,同时需要继承 ProductTemplate 抽象类,并实现 isEffect 方法。团购产品的生效条件:

  1. 当前的场景是 “买家下单场景” ,即 ScenarioRequest 是 BuyScenarioRequest
  2. 如果渠道来源是 "groupBy" ,当前产品则生效

Step 2:团购产品实现 “自定义商品单价”扩展点

Quickstart Guide 中,平台定义了一个 “自定义商品单价” 的扩展点。 在这里,我们让团购产品去实现这个扩展点,并假定在团购平台上,商品单价打7折。如下:

@Realization(codes = GroupBuyProduct.GROUP_BUY_PRODUCT_CODE)
public class GroupBuyProductExt extends BlankOrderLinePriceExt {
    @Override
    public Long getCustomUnitPrice(OrderLine orderLine) {
        return orderLine.getUnitPrice() * 700 / 1000; //only for sample.
    }
}

注:这里的价格计算只是用于DEMO,实际的价格计算不能用类型强制转换

Step 3:构造 “买家下单场景” 的请求

public class BuyScenarioRequest implements ScenarioRequest {

    @Getter
    private final OrderLine orderLine;

    @Getter
    @Setter
    private String source;

    public BuyScenarioRequest(OrderLine orderLine) {
        this.orderLine = orderLine;
    }

    @Override
    public OrderLine getBizObject() {
        return orderLine;
    }
}

Step 4:构造一次面向“买家下单场景”的业务调用过程

 public static void doBusiness(String source) {
        OrderLine orderLine = new OrderLine();
        orderLine.setUnitPrice(1000L);
        orderLine.setBizCode("business.b");
        try {
            Long unitPrice = new BizSessionScope<Long, OrderLine>(orderLine) {
                @Override
                protected Long execute() throws LatticeRuntimeException {
                    //bla.bla.bla
                    OrderLinePriceAbility ability = new OrderLinePriceAbility(orderLine);
                    return ability.getCustomUnitPrice(orderLine);
                }

                @Override
                public BuyScenarioRequest buildScenarioRequest(OrderLine bizObject) {
                    BuyScenarioRequest request = new BuyScenarioRequest(bizObject);
                    request.setSource(source);
                    //add some other info.
                    return request;
                }
            }.invoke();
            System.out.println("[Business B] overlay product unit price: " + unitPrice);
        } catch (LatticeRuntimeException ex) {
            System.out.println(ex.getErrorMessage().getText());
        }catch (Throwable ex) {
            ex.printStackTrace();
        }
    }

一次业务调用过程,我们用 BizSessionScope 进行包装。 原因在于:

  1. 一个业务可以叠加非常多的产品;你可以想象,在电商生态中有一个AppStore,每个业务都可以从AppStore中选择并安装产品;
  2. 一次业务调用,并不是业务安装的产品都会生效,比如本例中的“团购产品”,只有在下单渠道是“groupBy”时才会生效;
  3. 一次业务调用中,我们需要过滤出本次会话实际生效的产品,并将生效的产品与业务叠加后,再进行扩展点调用以及多份扩展点实现的Reduce

所以,BizSessionScope 会再被首次构造上,进行业务配置处理、生效的产品过滤、本次会话范围缓存初始化以及业务上下文初始化。

Step 5:样例演示

我们演示两次业务调用过程:

  1. 第一次业务的渠道来源是 null,商品价格就是商品单价 1000L
  2. 第二次业务的渠道来源是 groupBy,团购平台要求商品单价必须打 7 折,产品的定制逻辑优先(这个一般是业务和平台产品签约时约定的)
public class LatticeOverlayProductSample {

    public static void main(String[] args) {
        Lattice.getInstance().setSimpleMode(true);
        Lattice.getInstance().start();

        System.out.println("---------------------------------------");
        doBusiness(null);
        System.out.println("---------------------------------------");
        doBusiness("groupBuy");
        System.out.println("---------------------------------------");
    }
    ......
}

运行结果如下:

---------------------------------------
GroupBuyProduct effect status:false
[Business B] overlay product unit price: 1000
---------------------------------------
GroupBuyProduct effect status:true
[Business B] overlay product unit price: 700
---------------------------------------

我们可以看出,在团购产品生效时,自定义商品单价扩展点,返回的是 “团购产品” 的定制实现,即商品打了7折。

本样例代码URL:https://github.com/hiforce/lattice-sample/tree/main/lattice-overlay-product

关于 “产品” 的概念出处,大家可以进一步阅读:TMF2.0 – 关键概念 – 业务