百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 运营笔记 > 正文

怎么评价淘宝 UED 的 Midway Framework 前后端分离?

ann3311 2025-07-02 17:46 4 浏览 0 评论

早上看到贺老出马,也忍不住写了一篇来谈一下苏宁这样的公司对这方面的考虑。

近两年来,我一直在思考如何改进前端体系的开发模式,这里面最基础的一点就是前后端的分离。谈到前后端分离,也有一个误区,认为仅仅是以浏览器作分界,把这两部分的代码分离出来。但其实是,做这件事情的本意,是要解决开发模式的问题,也就是要分离前后端开发人员的职责。

针对不同类型的Web产品,这个分离方式是有所不同的。对于Web应用,因为它跟服务端的交互基本就是AJAX或者WebSocket接口,所以这个分离是天然的,整个前端基本都是静态HTML模板,JavaScript模块,以及CSS和相关静态资源,但是对于网购产品这样的形态,它的做法就不一样。

## 展示占主要部分的产品

网购产品的展示需求很重要,图片等资源载入非常多,但相对的操作却很少,基本只有搜索商品,加购物车,结算这样的环节。传统这样的产品,多半是这么个工作流程:

交互出高保真图,前端去切图,生成静态HTML加展示效果,然后,注意,他不是自己接着往下做,而是交给另外一群开发人员,把它转换成服务端模板,比如freemarker或者velocity之类,或者是smarty,为什么要这么做呢?因为这类产品讲究一个首屏优化,是首屏而不是首页,这就意味着对于首屏来说,经过的环节应当尽可能少,比如说,就不能先载入客户端模板,再AJAX一个数据,然后去渲染一下。这么做的性能肯定是不如服务端把HTML生成好,然后一次请求加载的。

这个过程肯定是有一些问题的,比如说,如果开发人员B在套模板的过程中,发现原先的静态HTML部分有问题,应该怎么办?大家知道,一个对HTML和CSS都很熟悉,同时又可以写业务逻辑的前端开发人员是很稀缺的,所以,多数情况下,这两边的技能是不同的,如果是简单的页面问题,这个开发人员可能自己也就解决了,如果他解决不了,怎么办?

如果B自己不改,把他已经搞成服务端模板的代码返回给前端人员A,A也没法下手,因为已经是服务端模板,A手里没有环境,改了之后不知道对不对,不能预览。那么,B把问题告诉A,A修改他的原始版本,然后再拿给B又怎样呢?这时候B又麻烦了,他要对比两次修改的部分,把自己前一阵的修改合并进去。

所以,不管怎么搞,这里面都很折腾。

Midway这个产品,他想要解决什么问题呢?既然说前端人员没法预览模板的原因是,后端在使用服务端模板,那么,我能不能找一种两边都可用的模板,你能在服务端渲染,我也能在客户端预览?服务端跟浏览器端同时都能运行的语言是什么?只有JavaScript。

所以,大家就往nodejs里面去发掘了,一个普通的JavaScript模板库,它在浏览器端也可以渲染,在nodejs端也可以输出成HTML,这时候,那些原来负责整合模板和逻辑的人员改用nodejs,是不是就解决这问题了?

想象一下这个场景多么美好:前端来决定某个模板是服务端渲染还是客户端渲染,当首屏的时候,就在nodejs里面生成HTML,不是首屏的时候,就AJAX过来在浏览器端渲染展示。

从技术方案上看,这么做很好了,工程上又带来另外一些问题,那就是对熟练JavaScript开发人员的需求量大增。对阿里这样的公司来说,前端有大几百人,别的公司只能仰望,所以他当然可以放手一搞,但对我们苏宁这样,前端人数不大的,就麻烦了。如果我们也引入这样的方案,就面临把很大一部分Java开发人员转化成JavaScript开发人员这么一个问题,这个事情短期内肯定是无法解决的,所以反过来会增加前端这边的压力。所以暂时还用不了阿里这样的方案,只能努力先提高人员水平再看情况。

服务端引入nodejs还有别的优势,比如说请求合并等等,这个也可以用其他方式变通解决,比如加一个专门的跟现有后端同构的Web服务器,在那边干这些事。

## 展示和业务逻辑较均衡的产品

对于另外一些场景,也有类似的问题,比如支付产品,展示相对没那么重,但是又算不上Web应用,它面临另外一种情况的前后端分离。这种场景下,前端的出静态HTML和DOM操作类的JavaScript,业务开发人员负责写后端,还有另外一部分业务逻辑的JS。

这里的问题是什么呢?是jQuery式代码造成的协作问题。比如说:

$(".okBtn").click(function {
  $.ajax(url, data)
    .success(function(result) {
      $("someArea").html(_.template("tpl", result));
    });
});

因为前端人员的稀缺,所以他不可能帮你把业务逻辑写出来,所以说,这里面$.ajax往里的部分,要业务人员自己写。然后,数据得到之后,又要去处理界面部分。

很多场景下,处理界面远不是这么搞个模板放上去就完事的,所以业务开发人员感到很烦闷,为了这么一点小问题,反复去找前端的人来搞,很麻烦,自己搞又特别花时间,所以都很苦闷。

这同样是一种前后端的分离,只是这个分界线不在浏览器,而在于:是否写业务逻辑。对付这种场景,解决办法就是加强JavaScript代码的规划。现在流行那么多在前端做MV*的框架,不考虑Angular这类太重量级的,来看看Backbone这样的,它到底解决了什么问题?

很多人说,Backbone虽然小,但根本不解决问题。这句话有一定道理,但前提条件是你自己的JavaScript代码分层已经做得很好了。如果做得不好,它就可以协助你解决分层的问题。

刚才那段代码,它的问题在哪里呢,在于职责不清晰。一个函数只能做一件事,这是共识,但由于回调等方式,所以不经意就破坏了函数的单一性、完整性。我们试试来拆开它。

对于一个后端开发人员来说,他为什么常常害怕写前端代码?是因为JavaScript语言吗?其实不是,我们用来写业务逻辑的时候,只会使用JavaScript一个很小的子集,对于这个子集来说,它并不存在多大的学习困难,最麻烦的地方在于DOM、BOM等东西,对于一个后端开发人员来说,如果要求他在掌握服务端代码编写的同时,还要去学这些,那真是有些不容易,所以,我们来给他省点事。

现在我们的出发点是,把这段代码拆给两个不同的人写,一个人操作DOM,另外一个人只写逻辑,绝对不操作DOM。前面这个代码拆给前端维护,后面这个拆给业务开发人员。

最老圡的方式:

a.js

$(".okBtn").click(function {
    b1(data);
});

function a1(result) {
    $("someArea").html(_.template("tpl", result));
}

b.js

function b1(data) {
    $.ajax(url, data)
        .success(a1);
}

现在大家是不是相安无事了?

如果这么做的话,AB双方要做很多约定,也就是说,这个过程仍然是一个螺旋链。比如说,A先写点击事件的绑定,然后想起来这里要调用一个请求,就去找B写b1方法。B在写b1的时候,又想到他要调用一个界面展示方法a1,然后又来找A写,来回也挺折腾。

况且,有这么一天,A在另外一个地方也想调用b1了,但是由于b1的回调已经写死了,比较蠢的办法就是在a1里面再判断,这是什么东西点击造成的,然后分别调用不同的回调。如果情况复杂,那这个代码写出来真是没法看。

如下:

a.js

var type = 0;
$(".okBtn").click(function {
    type = 1;
    b1(data);
});

$(".okBtn1").click(function {
    type = 2;
    b1(data);
});

function a1(result) {
    if (type1) {
        $("someArea").html(_.template("tpl", result));
    }
    else if (type2) {
        // ...
    }
    type = 0;
}

稍微好一些的办法是,在b1中,直接返回这个请求的promise,这样可以由调用方决定到底该干什么。

$(".okBtn").click(function {
    b1(data).success(function(result) {
        $("someArea").html(_.template("tpl", result));
    });
});

$(".okBtn1").click(function {
    b1(data).success(function(result) {
        // ...
    });
});

b.js

function b1(data) {
    return  $.ajax(url, data);
}

如果要对返回数据作统一处理,也可以很容易地在b1中,用promise重新封装了返回出来,只不过这样在a.js里面,直接调用的就不是success,而是then了。

注意到这样的代码还有问题,比如说大量的全局函数,不模块化,容易冲突。此外,没有一个地方可以缓存一些共享数据,比如说这么一个场景:

界面上两个块M和N,其中,M初始载入并加载数据,N在初始的时候不载入,而是在某个按钮点击的时候载入,而M和N中各有一个列表,数据来源于同一个服务端请求。

现在就有个问题,当N载入的时候,它的数据怎么来?比较老土的方式,肯定是载入N的时候,同时也再去请求一下数据,然后渲染到N上。

从一个角度看,如果说不重新请求,N的这个数据应当从哪里来?从另外一个角度看,如果重新请求了,发现数据跟之前的产生了变更,是否要同步给M,怎么同步给它?

我们看看类似Backbone这样的框架,它能提供怎样的机制呢?或者如果我们不用它,怎么自己把这个分层封装得更好一些?

首先,是建立一个数据模型,在它上面添加数据的缓存:

define("model", , function {
    var Model = {
        data: null,
        queryData : function(param, fromCache) {
            var defer = q.defer;

            if (fromCache || this.data) {
                defer.resolve(this.data);
            }
            else {
                var self = this;
                this.ajax(url, param).success(function(result){
                    self.data = result;
                    defer.resolve(result);
                });
            }

            return defer.promise;
        }
    };

    return Model;
});

这么一来,我们在模型上作了数据的缓存,如果调用的时候加fromCache参数,就从缓存读取,否则就请求新的。为了在两种情况下,调用方接口能保持一致,把整个函数封装成promise,以便接着调用。这里的模型定义成单例了,假定是全局唯一的,可以根据需要调整成可实例化的。

这个时候,视图层就要封装DOM和事件的关联关系:

define("view", ["model"], function(Model) {
    function View(element) {
        this.element = element;

        this.element.selector(".okBtn").click(function {
            var self = this;
            var fromCache = true;
            Model.queryData({}, false).then(function(result) {
                self.renderData(result);
            });
        });
    }

    View.prototype = {
        renderData: function(data) {
            this.element.selector("someArea").html(_.template("tpl", result));
        }
    };
});

这个时候,多个视图实例的情况下,数据也能够较好地利用。

这样,前端写这个View,后端写Model,可以作这么个分工。

这个只是很简陋的方式,在复杂场景下还有很多不足,在这里先不展开了。更复杂的场景也就是类似Web应用那种方式,稍后专门写一篇来展开。

## 小结

我们再来回顾前后端分离所要解决的问题,是分离前端和业务开发人员的职责,这个方案怎么定,是应当随着团队状况来确定的。比如阿里前端厉害,人多势众,他的前端就要往后推,去占领中间层。我们苏宁这样的公司,前端比较薄弱,只能在很多场景下,让出中间层,否则战线铺太广只能处处被动。

同一个中途岛,在不同的形势下,占还是不占,是很考验前端架构师的一个问题。

对阿里的这种实践,我们会持续围观,寻找并创造合适的出手时机。

— 完 —

相关推荐

港风女明星惊喜入淘,618新增百位明星淘宝开播

潮新闻客户端记者祝瑶今年天猫618,直播江湖风云再起,新增百位明星入驻淘宝开播。其中有钟丽缇、洪欣、陈松伶、陈法蓉等港剧黄金时代的女神级人物,她们通过淘宝直播全托管模式,轻装上阵投身直播带货行业。...

明星开的淘宝的店 你知道几个?(明星开的淘宝的店 你知道几个吗)

layciga:张艺兴(暂停运营了)dangerouspeople:薛之谦断头台的生活方式:尚九熙张予曦stylenotes:张予曦小飞象Orfila:吴昕织羽集:徐娇TIANCBRAND:陈赫D...

欧阳娜娜入职淘宝:近1周淘宝直播间粉丝过百万的明星飙升24倍

3月22日,一张欧阳娜娜的淘宝工牌在网上引发轰动。看度记者了解到,欧阳娜娜确实以淘宝新势力造型合伙人的身份“入职”了淘宝,担任2020年淘宝新势力代言人。她与淘宝还将有一系列更深入的合作,其中也包括时...

李小璐淘宝店日销10万,为何明星从“带货”转“卖货”?

天下网商记者王诗琪沉寂已久的李小璐再度回到大众视野,竟摇身一变成网红,带着自己设计的服装品牌,开起了淘宝店。9月26日晚正式营业,到28日下午4点,李小璐的淘宝店铺卖出了1100多件衣服,按均价...

官宣!100位明星来淘宝直播:明星影响力找到最好舞台

追星有多苦,只有粉丝知道:要是演唱会门票难抢、社交媒体上“爱豆”又长期不“营业”,到底该去哪里跟明星互动?现在淘宝直播给了个好去处:100位明星来淘宝直播了!在淘宝就能跟明星在直播间里亲密互动,还可以...

刘涛淘宝直播首秀交易额破亿,明星带货赚钱之余也有“失业”风险

5月14日,刘涛淘宝直播带货首秀,4小时交易总额突破1.48亿元,观看人次超过2100万;5月16日,陈赫抖音直播带货首秀,4小时5000万人次观看,销售额8269.13万元;5月17日,汪涵淘宝直播...

欧阳娜娜入职淘宝,明星排队来淘宝直播

3月22日,一张欧阳娜娜的淘宝工牌在网上引发轰动。记者了解到,欧阳娜娜确实以淘宝新势力造型合伙人的身份“入职”了淘宝,担任2020年淘宝新势力代言人。她与淘宝还将有一系列更深入的合作,其中也包括时下火...

李小璐复出开淘宝店,日销10万元,还有哪些明星“下海”了?

天下网商记者王诗琪沉寂已久的李小璐再度回到大众视野,竟摇身一变成网红,带着自己设计的服装品牌,开起了淘宝店。9月26日晚正式营业,到28日下午4点,李小璐的淘宝店铺卖出了1100多件衣服,按均价...

淘宝直播明星带货榜出炉!林依轮成全网明星主播TOP1

明星直播带货热度不减,真刀真枪的PK下谁才是带货最厉害的那个?6月29日,淘宝直播联合淘榜单发布了今年天猫618的明星直播带货榜。排名第一的是曾凭借《爱情鸟》走红的林依轮,他更是首次跻身所有淘宝主播的...

300余明星上天猫618!半个娱乐圈都在淘宝直播

新京报讯吴亦凡、宋威龙、李易峰、许光汉、华晨宇、刘涛、毛不易、欧阳娜娜、赵丽颖、郑爽、华晨宇、鹿晗、古力娜扎、迪丽热巴、Angelababy、吴倩、张云龙……他们全要上天猫618。5月27日,天猫6...

朋友手上买路易威登nanospeedy是假货!鉴定师:教你两招鉴定技巧

今天鉴定了一只路易威登【nanospeedy】当这个包包出现在眼前的时候,我就在想这只包会不会是假货?【nanospeedy】被评为最难买的路易威登热门款式之一,今天就来讲讲超难买到的LV迷你枕头包!...

我那件花了1800元购买的“名牌”衣服送人了

不知多少女人像我一样,听信微商所谓的“尾单”,买进高仿的大牌服饰,还以为真的可以出入专柜无压力。对于一个拿死工资的上班族来说,买正品的大牌衣服和包包有点太奢侈。顶多护肤品用兰蔻,香水用迪奥,已经很享受...

淘宝买菜,你敢用吗?(淘宝买菜的东西是真的吗)

...

1099元买手表 卖家:天梭“新款设计LOGO 亲”

11月1号,宁波的杨先生在网上买了一块手表,商品信息写的是瑞士天梭正品手表,可收到后他怀疑是假货。...

淘宝的戴森吹风机能买吗?假货踩坑记

先说一句啊,戴森的吹风机虽然宣传得比较好,但是我自己是绝对不会用的,之前只是琢磨放在浴室里面一个给洗澡的傻白甜们做个样子而已。自己还是老老实实的用松下nanoe毕竟自己的头发自己知道需求。11月27日...

取消回复欢迎 发表评论: