当前位置: 首页 > news >正文

重构之美-跨越Web标准,触碰语义网[分离:通用也许是个美丽陷阱]

这段时间超级繁忙,文章断了一个多月了,不好意思。

当程序员完全放弃对结构的编写与确定,高呼万岁,解脱了。真的,我发现我经过的程序员没有一个不是超爱Web标准,能不爱吗?我告诉他们再也不用写html,不用写css,不用写js,最多最烦人最招惹领导的界面问题都与你们无关。(我说句悄悄话:不要看现在每个公司后端“程序员”一堆一堆,我敢说对于其中不少人,像我这样把html/css/js部分从他们手中一抽走,基本就废了他们,他们剩下没多少可做的工作了。唉,别说他们,后来我把自个儿也废了,因为我速度太快了,后面慢聊……)

我是要说什么来着?哦,我要说得是程序员万岁了,但压力并不会凭空的消失,而是转移了,本来由大量程序员分担的工作便集中压到往往人单力薄的前端,前端的一系列问题就出来了,那就是设计、结构、样式、行为之间以及其自身的分离。这个分离相当困难,因为这几个东西太缠绵了,千丝万缕的纠缠。实际上,至今我仍在努力梳理,所以我只能在我的能力范围、认知范围和实践范围内说说看。

我曾在卡当顶着大量工作成为前端瓶颈,我后来一直在反思:为什么?怎么会这样?web标准错了吗?我开始抛开无法回避的客观因素,从主观上自身上去找答案。web标准,我还是信任的。

我当时的工作有哪些?管理和前后协调上的工作就不说了,说说前端技术上。首先我要做设计,因为那时能设计的人都不懂Web标准甚至不懂table,我自然否定他们的设计,因为传统的表格拼图设计思路会给制作带来麻烦,尤其是当时崭新的结构化思路非常需要设计的支持;其次我要做结构,这没啥说的,在结构上的理解与运用没人比我强;最后我还得做样式,由于我从那时开始就追求自创的独立于根的写法,而且狂热的恋上这种我认为最精简最漂亮能最大限度摆脱布局思路的结构,而这需要无比的耐心和深厚的css功底作为支撑,否则难以去除冗余结构也难以还原设计稿……

这样,为了避开层层的障碍做得更好,自己理想中的完美,我不自觉的把所有工作都集到了我一个人身上,使其他人很难介入进来,只能走在边缘。随着产品越来越复杂,恶性循环下我就陷得越来越深,不但我得陷在开发中,还得陷在维护中,出了什么bug,不管何时我必须在场,否则无法解决,我手机为QA开着,随时响应他们的召唤。在后来的反思中,我认为陷进去的原因之一就是:通用

可能这一说,是会被开发砍脑袋的。因为“编写一次,畅通无阻”,是开发至上追求,大家都讨厌重复劳动,讨厌苦力活,觉得这些都没有价值,不值得做,通用了,就能节省自己的时间,他人的时间。程序编写我不熟悉,我这里单说前端,更具体的是特指css。

css的诞生就是为了统一控制,最初我们就知道使用css来统一全站字体、字体色彩、行距等表现性的东西。多方便啊,维护的时候改一个地方,全站都变了。使用css后给人的第一个感觉就是通用。后来web标准来了,css的控制能力和范围在前端得到了几近无限的放大。我们发现通过css不仅仅可以控制颜色,还能控制布局。那么能使颜色通用,思路自然而然的无缝转嫁:统一控制布局。这是在我脑子里曾长久主导的设计思路和设计方向。我追求着通用,在卡当做到了当时个人能力下的极致甚至写过类似如此变态的css:
xxx div{float:left;}——一个css中。
xxx div div{float:none}——另一个css中。
xxx div div div{float:right;}。——再一个css中。
可能光看这部分代码你会觉得很狗屁,呵呵。也许你会说:“不是通用的错,是你做得不好。”完全是这样的吗?

2006年9月,正好两年前,在我围着通用上扑下扑,鸡飞狗跳的折腾过程中,CTO郑文军和我有一次交流,在多次的常规交流中唯这次让我记忆犹新。当时我炫耀着目前的前端多么多么的畅通,要变什么改一个小地方全变,要个性化什么通过css的优先级处理覆盖掉通用定义就行了,当然实际上我是焦头烂额的,忽悠领导呗是吧……文军看了看说:“嗯,不错嘛。”我正为忽悠成功而暗自开心。他话锋一转:“但是我觉得你不应该做得这么通用,有些地方即便能通用你也不应该让它通用,你要允许冗余的存在,允许看起来很讨厌的东西残留在系统中。”这可把我反忽悠了,可以说我把通用处理得不够好,但是能够通用为什么不通用,冗余的存在意味着无意义的重复劳动,无谓的多余时间消耗。我能节省我的时间,为什么不呢?是吧,Why not! 一抹袖子,办公室里,One、Two、Three, Fight!……

最后他说:“我们先把技术搁下好不好,不谈技术。换个角度来看,现在要做一件事情,比如我们一个新版本要上,包含很多内容很多模块很多面要处理,上线时间是3天后,铁板钉钉是不允许变的,钱不是问题,但时间晚一秒都不行。而我们现在的人力是肯定做不到的,就比如你前端,你要多少人我都给你,但是3天后必须完成,你可以吗?你做得越通用,对新人而言学习成本越高,无法迅速的开始。……”

我当时立刻就有一种醍湖灌顶的感觉,我解决问题处理问题的思路确实局限在了技术这个范围,没有跳出来,不够宏观。所谓的节省精力和时间局限在了一个小范围,甚至只是自己,而实际上我心知肚明的清楚,我自己也并没有省心反而更加烦心。

也许程序上的通用是有很大价值的,因为功能的需求变动和扩展通常不会很大和频繁,但是在过于直观的界面设计上,变动是频繁的。很简单嘛,boss通常看不到也看不懂程序,但是界面谁不会看呢?也能很方便的发表意见,甚至路过你身边冒一句:“把这个挪到这边,把那个挪到这里,这个图片不要了,那个角弯一下。”冒完泡后,大摇大摆的带着指点江山的成就感离开,也不会觉得有什么麻烦。只剩下你对着屏幕的反光,大眼瞪小眼,还得提防他啥时候再次路过,然后把之前说的话反着说一次。

这样的变动,对于界面设计来说虽然烦,但是这种烦不是因为实施,在PS/FW里拖来拖去的实施并不麻烦,抵触主要源于心烦(老子觉得这样好看,老子专业,凭什么改?)但是对于之后的css设计,实施就是灾难了。css不是银弹,特别是在处理布局上。我们设想也实施过各种各样的css文件:处理字体的,处理颜色的,处理模块的,处理布局的……这样的细分就是在分离,目的是通用。程序之所以相对而言能够去通用,我觉得因为功能之间能够通过定接口基本做到分开。一个优秀的程序员和一个差劲的程序员,无论谁上谁下,只通过接口握手,不会因为不同的编码习惯、风格、优雅度而相互影响。但是css不行,它没有接口,不管你细分了多少模块,最终css面对的是一份混在一起的,整合的html。这种情况下,如果由不同的人来完成不同模块,再组合起来,css间就会冲突,因为布局总是相关的,有时这种冲突会非常激烈。当然我们可以通过优先级去解决,这就是覆盖操作,分离程度越高,覆盖操作越多,而分离层次越多,当你面对一个新页面的时候,你越迷惑:到底以前在这个标签上定义了哪些样式我需要去清除或覆盖。我曾经在这上面陷得很深,我自己都记不得我需要处理哪些我曾定义过的东西,翻箱倒柜的寻找……

问题还不仅仅出在开发过程中,维护时也是。分离后,通用后,引一发而动全身是其优势,同时也是其劣势!随着项目的壮大,页面越来越多,而人员变更,使得后续的css设计五花八门,这个时候,分离出来的通用样式就越来越难以更改,因为你不知道引这一发,全身会怎样的抖动,也许左手很正常,而右手在抽羊癫疯。也许全身很正常,但某一处血管已经断了(因为样式问题而导致功能失效不是低概率),于是你不敢轻举妄动,恶性循环后,通用的这些css慢慢就成为沉重的历史包袱压着后续开发。如何查找?就像在超长代码中去寻找一个未关闭的标签或忘写的“;”一样困难,而且你还得首先确诊问题的根本是有个未关闭的标签或“;”。曾经我们上线一个版本后出现严重bug,前后所有相关人力在追查了整整两天后才发现,是程序员套结构时一个未关闭的标签导致。虽然只是一个小问题,习惯问题,却引发了高度重视,甚至大家产生对web标准的怀疑,因为风险太大。(唉,你们不知道我当时的苦啊,有一次我发现程序员居然一个页面少关闭了近10个标签……这还是我写他套……)

我要说的是,从那次交流后,我就开始很慎重的对待样式的通用和分离。尽可能少的分离,尽可能少的通用定义,除了兼容尽可能少的进行覆盖,尽可能的回避!important,目的是为了使自己,使他人在面对新页面时不要背着难以卸掉的、沉重的历史包袱。我们知道对待一个页面写样式最快最爽的办法就是面对一个完全无样式的页面,不仅如此,干净的页面对界面设计的宽容度也是最大的。前端是什么,UI和UE,是用户界面和用户体验,界面源于设计,体验源于交互。css不是主角,它是配角,在设计和交互间是穿针引线的作用,css需要做的是尽可能的不限制。而css的高通用、高分离,我认为就是喧宾夺主,对设计和交互构成了限制。

从2007年开始,我写CSS就基本上为一个public.css+"page".css,页面链接"page".css,而"page".css中对public进行import,并且尽可能少的定义public,把控制权尽可能多的交给"page".css。"page".css得到了更多的控制权就意味着"page"的界面设计得到了来自css更少的限制。目的就是让css之间的牵连更少,而操作更自由。自由当然需要代价,那就是各个page的css会存在冗余,会在开发时产生重复劳动,但我觉得对于css来说,最重要的还是自由。少了分离少了通用,无论人员变更还是水平高低,都能迅速的参与到项目中来,而不是先啃一套css规范,如果公司一换,屁用没有,又得重新啃新的规范。我float用得比你的position还好,我为啥要遵循你的position规范呢?我想很多人都不会乐意去修改别人的css,因为很难理清别人的思路,padding-top只是padding-top吗?它很可能是页面的布局重点。我相信每个人在接手他人工作的时候最乐意的就是按自己的方式来,哪怕全新开始也会很快。那么好,你现在把他的"page".css内容删了重写,页面干干净净,自己搞吧,如果赶时间,极端点,你甚至不用了解和导入public.css。而你写的"page".css并不会被其他页面引用,写得再烂,也不会破坏整体。或许会有人拿面目全非的改版说事,别异想天开只动css,通常来说,面目全非的改版改的是需求,需求一大变,css?直接del吧。不要一说起css的灵活就把轻松改版挂在口中,你做到过吗?css的灵活是体现在开发、维护的过程中各个细微之处,在大量的细节问题处理上节约时间并推进进度,而不是面对整体。如果非要把css拔升到全局控制的高度,会是灾难。再重申一次:css不是银弹。

最后一个必须提的,是组件化。如果说我的左手是反对,右手是支持,从2004年开始,面对组件化操作css的做法,我左手就没放下来过,很简单:组件化操作css是更高的通用和更高的分离。前段时间我们在讨论片段化的时候我也是反对将css纳入其中,哪怕最终能自动合并而不必担心文件数的问题。因为,需要给予千变万化、动荡不安的前端更多的宽容和自由。还有一个原因,我会在下篇中讲到。

分离的第二步:减少分离,降低通用,解放css。


本文转自爆牙齿博客园博客,原文链接:http://www.cnblogs.com/yuntian/archive/2008/09/23/1269800.html,如需转载请自行联系原作者

相关文章:

  • shell脚本(1)
  • 笔记-Kotlin学习
  • 【Unity Shader】五、Shader纹理映射,及纹理的缩放和偏移
  • img 样式单和属性
  • 统计学基于SPSS贾俊平 授课笔记 发布作业 spss19cn 软件下载地址及破解包spss19_10039 下载地址...
  • zabbix监控模板大全
  • 2017杭州云栖大会—移动云专场【赠票】
  • seaJS源码
  • apache 日志轮询三种方法
  • Django REST框架-基于类的视图
  • 玩转算法面试:(三)LeetCode数组类问题
  • TensorFlow 之 高层封装slim,tflearn,keras
  • NetScaler的部署实验之七NetScaler Gateway的配置以及StoreFront集成NetScaler Gateway的配置更改...
  • myEclipse 中看jar源代码
  • bootstrap创建登录注册页面
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • Apache Spark Streaming 使用实例
  • create-react-app项目添加less配置
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • KMP算法及优化
  • Leetcode 27 Remove Element
  • Python - 闭包Closure
  • React as a UI Runtime(五、列表)
  • Spring Boot MyBatis配置多种数据库
  • Spring Cloud Feign的两种使用姿势
  • SQLServer之创建显式事务
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 前端技术周刊 2019-02-11 Serverless
  • 运行时添加log4j2的appender
  • - 转 Ext2.0 form使用实例
  • ​iOS实时查看App运行日志
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • !!java web学习笔记(一到五)
  • #微信小程序(布局、渲染层基础知识)
  • (10)STL算法之搜索(二) 二分查找
  • (Ruby)Ubuntu12.04安装Rails环境
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (待修改)PyG安装步骤
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (理论篇)httpmoudle和httphandler一览
  • (六)vue-router+UI组件库
  • (五)Python 垃圾回收机制
  • (转)IOS中获取各种文件的目录路径的方法
  • (转)程序员技术练级攻略
  • (转)重识new
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .CSS-hover 的解释
  • .NET Core 项目指定SDK版本
  • .net core使用ef 6
  • .net refrector
  • .NET文档生成工具ADB使用图文教程