一种基于坑位模版的分页方案

一. 概述

1.1 业务诉求

想象一个向用户展示数据的下拉列表,数据的来源有多种方式。支持在每一页都按固定的数据源类型及顺序展示。

1.2 业务场景

  • up主的主页展示带货商品列表
    商品来源有多种:up主自选、官方推荐的、根据up主风格AI推荐
  • 用户推荐视频列表
    视频来源有多种:用户关注、用户画像推荐、播放排行榜

二、方案

每一页的每个位置的数据,有数据源类型和顺序的差异,将每个配置定义为一个坑位。即每一页有pageSize个坑位。

2.1 后台配置

在后台定义每页所有坑位的数据源类型,每页坑位配置的合集定义为坑位模版:

struct{
	1:i32: minPageSize //每页最小的数量
	2:list<string>: slotTypes //所有坑位的类型
}

每个坑位的类型

2.2 数据查询

  1. 坑位模版groupBy数据源类型,获取单页每种数据源的count
  2. 每一个数据源类型有一个分页查询接口,基于分页接口封装为游标(pageSize=坑位count)
  3. 按坑位模版的模型,分别从游标中获取元素充填:如果元素不够或元素被filter则后面的元素自动顶上,如果过滤后的所有数据源数量size<minPageSize,则继续取下一页,直到满足条件

注意其中的细节:

  1. 分页参数offset: 包含还有数据dataSource和pageNo信息,第一次传空后续用上一次返回的offset
  2. 单页的数据大小: [minPageSize, minPageSize+pageSize]
  3. 某坑位元素被过滤后,尽管下一页还有数据,但该位置仍被后续其他类型数据占用。

坑位模版查询

游标定义参考:

public class PageCursorList<T> {

	private int readCursor;

	@NonNull
	private final Function<Integer,List<T>> pageFetcher;

	private int pageNo = 1 ;

	private final int pageSize;

	protected List<T> list;

	public PageCursorList(int pageSize,Function<Integer,List<T>> pageFetcher){
		Preconditions.checkArgument(pageSize > 0,"pageSize must gt 0");
		this.pageSize = pageSize;
		this.pageFetcher = pageFetcher;
		//first page
		this.list = Optional.ofNullable(pageFetcher.apply(1)).orElse(Collections.emptyList());
	}

	public boolean hasNext() {
		boolean currentPageHasNext  = readCursor < list.size();
		if(currentPageHasNext || list.size() < pageSize){
			return currentPageHasNext;
		}
		nextPage();
		return readCursor < list.size();
	}

	public T getNext() {
		if (readCursor < list.size()) {
			return list.get(readCursor++);
		}
		return null;
	}

	private void nextPage(){
		pageNo++;
		this.list = Optional.ofNullable(pageFetcher.apply(pageNo)).orElse(Collections.emptyList());
		this.readCursor = 0;
	}
}

三、扩展

  1. 基于用户画像或标签,配置多套坑位模版,实现精准运营
  2. 配置多套坑位模版,实现AB

在用户查询时再套一层即可:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值