谈及中台,大都雾里看花,抱有一份敬畏之心,恐误导众人。但愿通过本人的思考与一起思考实际的敌人们一些启发,让中台建设失去它应有的收益,总结出更多的成功经验。

最近接触到一些公司说在做中台,交换之后大都是应该应用什么样的技术,如何解决数据一致性问题等。其中公司倒退工夫有长有短,有十几二十年的传统企业,也有三四个月才起步的守业团队。交换下来心中不免有些担心,不太分明所谓中台是谋求一种技术实现还是一个风行噱头。

通过较长时间的思考、学习和实际,我发现理解得越多越不敢讲本人做的称之为中台。它是一种企业级业务构架设计方法论,如何做好还得从企业的愿景收回剖析企业倒退指标,正当利用资源对系统架构进行持续性的演进

每个企业的愿景和指标都不一样,对信息化诉求不一样,所构建出的中台零碎天然也不一样,然而对企业经营有无效的晋升是显尔易见的,所以设定好可量化的指标尤为重要。

背景

本文通过一个简略的例子来讲述如何进行中台化落地,企业理论过程远比这简单得多。这是一家新批发企业,通过数字化转型取得新的业务增长点。“数字钱包”是公司的一个重点产品,我的项目特点是和其它业务绝对独立且前端性能多样化,经磋商解决引入中台化的思维来布局这个我的项目。

一、 策略剖析

架构设计就是为将来而设计的,首先要分明这个产品的愿景是什么,做这个事是目标是什么,要达成什么指标等。
策略剖析是至上而下的,经验公司的倒退历史,理解公司当初的倒退情况,分明公司将来的倒退方向。此过程须要公司领导及各业务负责人参加沟通,达成一致意见。

1. 业务愿景剖析

  • 减少企业经营效益:通过钱包预付款性能,减少资金积淀,加强资金利用效率,同时升高顾客的促销老本
  • 加强顾客粘性:减少顾客复购机会,加强顾客用户体验

2. 业务模式分析

此产品次要用于公司各种类型资金交易的解决方案。目前包含:

  • 会员钱包性能:与会员零碎买通,与会员零碎强绑定,实现会员专属虚构账户性能
  • 生产卡性能:次要用于线下实体卡业务,会员和非会员均可应用

    • 记名:用于会员
    • 不记名:用于赠送、福利卡
    • 亲属,用于家庭共用卡
  • 积分性能:用于购物返利,流动处分等

3. 业务场景剖析

次要为线上线下联合,不同的终端不一样的应用场景

  • 线上微信、APP实现可信赖的疾速领取服务
  • 线下门店、单干商户实现凭明码平安生产服务

4. 业务功能分析

不同的业务模式和业务场景有不一样的业务性能,这里须要去切分和隔离

  • 会员钱包:充值、生产等
  • 生产卡:充值、生产、明码、转账、挂失、开卡、销户等
  • 积分:赠送、生产、兑换等

5. 零碎建设指标

  • 为满足销售工作的达成须要疾速响应前端各业务场景的需要变动
  • 零碎须要易于复制业务模式的翻新尝试

二、 战术设计

战术设计就是依据战略目标制订具体的作战步骤。

  • 作战步骤须要紧贴公司策略步骤制订,依据当下的理论的资源状况进行正当的配置
  • 战略目标较为严惩,且较为耗时耗力,须要先抉择一个较为容易实现的指标,获得阶段性的成绩
  • 设定指标后还须要设计一个可量化的指标,得以评估中台化革新的收益,是否带来正向后果

本我的项目所处在钱包性能急将上线解决业务性能闭环的阶段,须要疾速出成绩故在后续系统结构不做大的扭转的状况下,思考到线下操作都是由公司员工实现,施行危险绝对可控,故先实现线下根底版本。

因为第一阶段性能较简略,架构关键点在于如何放弃零碎的灵便扩展性,故后期的架构设计是重点,而后的性能实现就能牵强附会了。
可量化指标是实现新老性能的迁徙,实现多端操作的整合。

三、 战术落地

1. 逻辑构造剖析

(1)畛域驱动设计

依据策略愿景的诉求,零碎设计上要求放弃灵活性,易于性能扩大和业务状态疾速复制性。
咱们采纳DDD(畛域驱动设计)思维来剖析业务:

  • 将零碎中的钱包账户交易流水划分为两个畛域实体,造成聚合
  • 应用命令模式驱动业务操作,以交易流水实体为聚合根驱动钱包账户实体的变动
  • 应用畛域事件来联动零碎内与零碎外相干性能

此阶段能够以事件风暴的模式,与领域专家一起应用通用语言来展开讨论,以达到业务、技术意识一致性

(2)形象能力

零碎须要放弃满足的复用能力,能够不便疾速的迭代出新的业务性能、业务规定和业务场景。故须要辨认出这其中的业务共性和可变性,通过多种程序设计模式放弃零碎的灵活性

这个我的项目的业务共性就是所有的业务操作都是能够以交易流水为驱动,引发一个业务变动
可变性就是不同的业务变动,如金额减少、金额缩小、账户锁定、明码变动等
可变的内容形象为业务行为业务规定,不可变的就是交易解决交易实现交易事件公布

(3)零碎扩展性


这里次要指零碎间的扩展性。须要定义好互相通信的协定和规范,通过定义好的流程将数字钱包零碎与其它零碎交融成一个整体。

2. 逻辑结构设计

上图为零碎架构的外围逻辑,次要有3大部分组成

(1)WalletService 外围交易服务接口

所有交易操作的执行器

public interface WalletService {    void done();}
DefaultService 默认的抽象类,次要实现CheckPolicyBehavior接口的主线流程调用

事实类调用:

public class ConsumeService extends DefaultService {    public ConsumeService(Wallet wallet, BigDecimal tradeAmount) {        super(TradeRecord.builder().wallet(wallet).tradeAmount(tradeAmount).build());    }}

(2)Behavior 交易行为接口

public interface Behavior {    void doAction();    InOutFlag getInOutFlag();}public class CreditBehavior extends DefaultBehavior {    private final BigDecimal tradeAmount;    public CreditBehavior(Wallet wallet, BigDecimal tradeAmount) {        super(wallet);        this.tradeAmount = tradeAmount;    }    @Override    public void doAction() {        super.doAction();        wallet.setBalance(wallet.getBalance().add(tradeAmount));    }    @Override    public InOutFlag getInOutFlag() {        return InOutFlag.IN;    }}

依据设计方案将所有钱包账户操作都定义为行为,此处实现的是具体的账户操作逻辑,实现类继承至抽象类进行简略的关闭。
getInOutFlag()是对行为产生的资金进出后果的配置

(3)CheckPolicy 交易规则接口

public interface CheckPolicy {    void check();}public class NoOverdraftAllowed implements CheckPolicy {    private final Wallet wallet;    private final BigDecimal tradeAmount;    public NoOverdraftAllowed(Wallet wallet, BigDecimal tradeAmount) {        this.wallet = wallet;        this.tradeAmount = tradeAmount;    }    @Override    public void check() {        if (wallet.getBalance().compareTo(tradeAmount) < 0){            throw new BizException("余额有余");        }    }}

实现类用于判断相干操作是否存在余额有余(透支)状况,如果有则中止执行

3. 设计模式的使用

(1) 模板模式

public abstract class DefaultService implements WalletService {    protected abstract static class TradeConfig {        public abstract TradeType tradeType();        public abstract Behavior behavior();        public abstract List<CheckPolicy> checkPolicies();    }    protected abstract TradeConfig tradeConfig();    @Override    public void done() {        check();        tradeConfig().behavior().doAction();        tradeRecord.setBalance(tradeRecord.getWallet().getBalance());        tradeRecord.setTradeStatus(TradeStatus.SUCCEED);    }}public class LockService extends DefaultService {    public LockService(Wallet wallet) {        super(TradeRecord.builder().wallet(wallet).build());    }    @Override    protected TradeConfig tradeConfig() {        return new TradeConfig() {            @Override            public TradeType tradeType() {                return TradeType.LOCK;            }            @Override            public Behavior behavior() {                return new LockBehavior(getWallet());            }            @Override            public List<CheckPolicy> checkPolicies() {                return CheckPolicyBuilder.builder()                        .add(new NoAvailableStatusAllowed(getWallet()))                        .build();            }        };    }}

在主交易流程中,将共有的流程放在done()中执行,将可变的局部形象成配置模板供事实类事实

模板模式的长处:

  • 扩展性好,对不变的代码进行封装,对可变的进行扩大;
  • 可维护性好,因为将公共代码进行了提取,应用的时候间接调用即可;
  • 事实类在无限的空间扩大,不影响主流程的实现;

(2) 策略模式

public class RechargeRollbackService extends DefaultService {    private final TradeRecord sourceTrade;    public RechargeRollbackService(TradeRecord sourceTrade) {        // ...    }    @Override    protected DefaultService.TradeConfig tradeConfig() {        return new TradeConfig() {            @Override            public TradeType tradeType() {                return TradeType.RECHARGE_ROLLBACK;            }            @Override            public Behavior behavior() {                return new DebitBehavior(getWallet(), getTradeAmount());            }            @Override            public List<CheckPolicy> checkPolicies() {                return CheckPolicyBuilder.builder()                        .add(new NoRechargeTypeAllowed(sourceTrade))                        .add(new NoTimeoutAllowed(sourceTrade))                        .add(new NoOverdraftAllowed(getWallet(), getTradeAmount()))                        .add(new NoAvailableStatusAllowed(getWallet()))                        .build();            }        };    }}

在交易行为和交易规则的设计中应用了策略模式,可依据不同业务操作设计不同的策略

策略模式的长处

  • 扩展性好,能够在不批改对象构造的状况下,为新的算法进行增加新的类进行实现;
  • 灵活性好,能够对算法进行自在切换;
  • 构造清晰,代码可读性高;

(3) 组合模式

public abstract class DefaultTowPCService extends DefaultService implements TwoPCWalletService {    public DefaultTowPCService(TradeRecord tradeRecord) {        super(tradeRecord);    }    @Override    public void process() {        check();        getTradeRecord().setTradeStatus(TradeStatus.PROCESSING);    }}public class RechargeService extends DefaultTowPCService {    public RechargeService(Wallet wallet, BigDecimal tradeAmount){        super(TradeRecord.builder().wallet(wallet).tradeAmount(tradeAmount).build());    }}

TwoPCWalletServiceDefaultTowPCService 用于在原有接口根底上扩大的二阶段提交性能,此处为了放弃DefaultService性能的单一性,并没有在原有类上进行性能扩大,而是应用组合模式进行性能扩大
此事实类就事实了WalletServiceTwoPCWalletService两个接口

策略模式的长处

  • 扩展性好,能够在不批改对象构造的状况下,为新的性能减少新的事实;
  • 变动性小,不须要事实的类,不批改代码

四、 零碎架构演进

1. 构造阐明

  • wallet-common为外部各层的共用实体对象
  • wallet-domain为形象的业务根底逻辑与规定,个别不具体间接业务场景反对。须要与wallet-service联合实现实现的业务逻辑。在团队开发层面,这一个档次的独立能够无效管制根底规定的代码稳定性
  • wallet-repository专一数据对象的长久化,与业务逻辑进行隔离
  • wallet-service为合乎业务场景的业务性能实现,次要依附wallet-domainwallet-repository的互相组合来实现
  • wallet-client用于对外的前端接口层
  • wallet-provider用于对外部微服务的接口层

2. 第一阶段 繁多构造模式

这一阶段,业务模式繁多,业务性能繁多,业务量较少,开发人员也较少,将所有模块打包运行在一个jvm中

3. 第二阶段 多业务构造模式

这一阶段,随着业务模式和业务量的减少,模式间的业务性能也不雷同或有互斥性,繁多构造已不能满足,故将根底模块关闭为SDK,每种业务模式独自一套零碎独立保护

4. 第三阶段 业务中台化

随着业务模式、业务量、业务性能需要继续减少。因为各业务线独立经营,导致SDK版本不统一,减少了保护老本。多团队保护架构导致性能反复且实现过程参差不齐,带来肯定保护老本且零碎间无奈实现复用,同时每条业务线独立经营也带来用人老本的减少。

这一阶段的指标是将大部分的共用性能下沉造成标准化逻辑,对立保护版本,缩小人力老本,故架构演进采纳中台化的思维

  • 业务能力(wallet-domain):将业务高度形象造成一个一个根底能力
  • 业务域(wallet-service):将业务能力依据业务场景进行组合编排造成功能域
  • 长久层(wallet-repository):依据不同的状况,将数据长久化到中台或前台
  • 前台触点(wallet-client):依据不同的场景定制不必的前台API

五、综述

本文通过一个较简略的例子讲述中台架构演进的过程,理论场景远比此简单。但最重要的不是最终的零碎架构,而是对系统演进的思考和施行过程,因为中台的状态也是随工夫一直变动的。

六、源代码

文中代码因为篇幅起因有肯定省略并不是残缺逻辑,如有趣味请Fork源代码
https://gitee.com/hypier/barry-wallet

七、请关注我的公众号