手机站前端架构(一)

@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!

Made with Slides.com