手机站前端架构(一)
@CSS魔法
2016. 03. 01.
URL、Controller、模板
- “架构” 是什么?
- URL
- Controller
- 模板
(45~60 分钟)
“架构” 是什么?
架构的目的是什么?
为什么要有架构?
- 控制复杂度
- 保障代码质量
- 提高开发效率
架构的三大目标:
清理、抽象、分离
规范、工具
新技术、工具
总之:让业务工程师更爽!
- 业务工程师
关注点:
- 功能如期上线
- 功能的正确性、稳定性
- ……
- 系统的健康度
- 人的健康度
- 架构工程师
- 思考 / 分析 / 调研
- 造工具 / 写文档
- 改造 / 迁移 / 修正旧代码
架构组的日常工作(以我为例):
20%
30%
50%
这还不是最憋屈的……

下面没有了……

“架构” 是什么?
架构 = 苦逼
URL
浏
览
器
Routing
Controller
模板
(View)
HTML
URL
数据
一次常规的页面请求:
手机站 (WAP 站) 的 URL 策略:
m.shanghai.baixing.com/...
www.baixing.com/m/...
m.baixing.com/...
shanghai.baixing.com/m/...
桌面站 (Web 站) 的 URL:
shanghai.baixing.com/...
www.baixing.com/...
shanghai.m.baixing.com/...
推荐
事实
WAP 页面 URL 规范:
URL 路径的第一级
必须是 /m/
为什么?
- 老 WAP 版
(真正的 “WAP” 版) - 触屏版
(“HTML5 版”)
WAP 站的双版本策略:
- 功能机、旧版智能机
- ≤ 5% 用户
- 主流智能机
- ≥ 95% 用户
WAP 站双版本如何共存?
- 不同设备请求同一 URL,可能返回不同内容
- 根据设备的 UA 信息来划分
后端的 “浏览器分级策略”
前提:系统要知道这是一个 WAP 页面!
URL 必须符合前面提到的规则!

- 历史遗留
- 特殊情况 (?)
但还是有些例外:
代发、充值成功……
市场活动、……
例外还是少一些吧!
Controller
浏
览
器
Routing
Controller
模板
(View)
HTML
URL
数据
htdocs/
└── controller/
├── Fabu_Controller.php
├── Fabu_WAP_Controller.php
├── Helpcenter_Controller.php
├── Helpcenter_WAP_Controller.php
└── ...
现有 Controller 文件:
-
同一功能同时提供
两个平台版本的 Controller - 当移动设备访问 Web URL 时,
应自动跳转到对应的 WAP URL
与 WAP 相关的 Controller 规范:
URL 不同,自然可以 route 到不同的 Controller!
很多页面没有做到!可能是因为麻烦吧……
模板
浏
览
器
Routing
Controller
模板
(View)
HTML
URL
数据
WAP 的双版本是如何实现的:
双模板
htdocs/
└── view/
└── wap/
├── home.jedi
├── home.mobile.jedi
├── listing.jedi
├── listing.mobile.jedi
└── ...
双模板是如何同时工作的?
ResponseData::createDefault($req)
->params($p)
->template('template-name');
Controller 并没有指定两个模板!
模板的查找机制:
- 根据 UA 得到平台代码(variant)
- 到模板目录下查找
- 主文件名:
先以'template-name'
+'.'
+ variant 查找;
再以'template-name'
查找 - 扩展名依次尝试
'jedi'
、'jades'
、'jade'
htdocs/
└── view/
└── wap/
├── home.jedi
├── home.mobile.jedi
└── ...
ResponseData::createDefault($req)
->params($p)
->template('wap/home');
触屏版
老 WAP 版
'mobile'
'mobile.wap'
home.mobile.jedi
home.jedi
- 一致性
- 老设备可能会访问新功能的 URL
既然老 WAP 版已经不维护了,为什么还要为它准备模板?
foo.mobile.jedi
需要有一个foo.jedi
- 为什么不共用
foo.jedi
?
“宁可无,不可错”
- 简单!
- 文件少不一定简单
模板的抽象方式 (Jedi):
Skeleton
继承
页面模板 B
页面模板 A
继承
模板的抽象方式 (Jedi 1.x):
Skeleton
多级继承
页面模板 B
子模板
包含
“中间层” 模板
多级继承
页面模板 A
多级继承
:import
skeleton.jedi
skeleton.mobile.jedi
skeleton-na.jedi
WAP 在用的 Skeleton:
老 WAP 版专用
触屏版专用
老 WAP 版
“空白页” 专用
WAP 模板规范:
- 放到固定的目录
- 用 Jedi
- 为每个页面准备两个模板
- 使用合适的 Skeleton
htdocs/view/wap/
foo.jedi
foo.mobile.jedi
现有代码中存在例外吗?
例外还是少一些吧!
很多……
如何作死?
番外篇
- 这个页面的双版本功能会失效
- 旧手机会看到错乱的页面
(或新手机会看到老版页面)
WAP 页面 URL 路径的第一级没有 /m/
?
死法一
- 不会死(只要处理好平台识别、跳转等)
- 不一致
Web 和 WAP 共用 Controller?
死法二
文件少不一定简单;但不一致肯定是复杂的。
- 移动设备看到的是为 PC 准备的页面
- 性能差(加载 & 运行)
Web Controller 不把移动设备的访问重定向到 WAP 页面?
死法三
- 不一致
- 在重构中可能被遗漏,引发 bug
没有把 WAP 模板放到固定的目录?
死法四
- 不一致
- 双份 Skeleton,双份的维护成本
WAP 模板用 Jade 来写?
死法五
WAP 页面只用一个 foo.jedi
模板文件?
死法六
- 不一致
- 旧手机会看到错乱的页面
“宁可无,不可错”
WAP 页面只用一个 foo.mobile.jedi
模板文件?
死法七
- 不一致
- 线上直接报错!
写 WAP 页面不基于 Skeleton,直接写?
死法八
- 不一致
- 在重构中可能被遗漏,引发 bug
文档
(稍后补充)
Q & A
Thank You!
手机站前端架构(一)
By zpbx
手机站前端架构(一)
前端架构工作的内容;URL、Controller、模板相关设计
- 473