收拾残局:如何让你的编码流程有条理 [Cleaning Up The Mess: How To Keep Your Coding Workflow Organized]

 

收拾残局:如何让你的编码流程有条理

原文:Cleaning Up The Mess: How To Keep Your Coding Workflow Organized

作者 Bryan Hoyt
翻译 Night Knight
原载 Smashing Magazine

啊欧,我们在标题里用了“有条理”这个词。该把这页面关了——可能很多人都会这么想。保持事情有条理虽然很无聊,但是个重要课题。也许给你设置一个环境会有趣些。来点in的,想像我们在为一家叫做“bEat”的时髦餐馆建一个服务于艺术社区的网站。这是个洋溢这艺术气氛的地方,砖墙上装饰着20世纪20年代的画作,舞台上现场演奏着爵士,餐桌旁围坐着富有的主顾。但是他们却没有网站,所以他们邀请你来当他们的救世主。作为一名天才设计师,你很有自信可以做出一个让他们钟爱的设计。可是他们有很多关于网站功能的奇妙想法,这让你不知道要怎样去组织你的网站所需要的所有文件。

他们需要发表每周博文和其他新内容,所以他们要能够自己编辑文章、上传图片。这是很正常的事。他们还想和Twitter连接,让他们的文章自动发布到Twitter。他们需要一个iPhoneAndroid平台的移动应用,因为他们的顾客希望将特色产品和菜单直接发到他们的智能手机上。顺其自然地,他们希望能够获得顾客们提交的评价,包括合适的图片和链接等。还要有许多很酷的交互式社交网络功能、好友系统、用户上传在线视频系统。“Facebook for restaurants”,他们这样形容它,好让你更容易理解。好了,目前为止,你可能会让他们去浪费另一个人的时间。但是你了解了他们的想法。

或许过去你曾经尝试过建立一个像这样的更复杂的、前沿网站,满怀热情地开始实施你的项目,但是以一个你无法继续维持的噩梦般的烂摊子收尾。如果新的特性很难被加入,你的客户就会失去兴趣,所以你开始彻夜努力跟踪bug,但是你连与之相关的文件都找不到。

在做了一个诸如此类的项目之后,就不难发现建立一个有序的网站项目的重要性了。

 

一般原理

 

Structure is the essence to the project.

结构是项目的本质。Chris Halderman配图

保持每件事简单明了。不要过分干预——一些站点和框架似乎有点自虐地去保证所有的东西都做到理论上的完美抽象。实际上,通常这是不可能做到的。

如果你开始创建几十个(或者上千个)小文件,每一个都只包含一个小小的类或者方法,那么你就是做过头了。如果你的文件名和目录名太过于抽象或者一般化,事情就可能开始变得有点傻了。比如说,如果用于检查网站管理员登录信息的代码被存放在了一个叫做WebsiteData/Items/GenericUser/AdminUser/Code/Auth.php的文件里,那么你就同时犯了上面两个错误。为什么不简单地在code/users.php文件里写一个check_login()函数呢?

不要把网站的不同方面混在一起。保持功能模块分离,保持不同语言分离。我最近帮助一个项目组解决了困难,那些可怜的被误导的程序员们把CSS、ASP VB Script、JavaScript、HTML和SQL语句混得一团糟,全都放进了一个单独的巨大的没有缩进的文件里。我没有夸张。说得够多了。

一个尺寸不能适应所有情况

Reflection prior to starting helps.

三思而后行。Andy Mangold配图

目录层次的深度和独立文件的数量会影响站点的大小。保证它安排恰当。

下面是一个网站近似大小和相应组织方式的列表。

  • 单页站点创建一个图片目录,一个独立的CSS文件,一个JavaScript文件,一个内容文件和一个独立的代码文件。不值得把模板和内容分开,除非你有特殊需求。
  • 5页站点一个图片目录,一个CSS文件,一个JavaScript文件,一个代码文件。考虑把内容文件放到一个单独的目录里。通常这里依然没有建立模板目录的必要。目前为止,确保你有一个页面的headerfooter(以及页面共有的所有其它元素)的模板。
  • 20页站点一个图片目录,一个用于存放上传文件和其他业务相关文件的目录(“assets”),一个用于存放内容文件的目录(或者至此你可能会用一个基于数据库的CMS系统)。到了这个阶段,你的JavaScript、代码和样式表可能已经变得足够复杂,可以考虑把他们放在分开的目录里。给目录起个显而易见的名字,比如css/javascript/code/。

确保所有的文件都存放到了相关的目录。你不能让一个走失的.js文件坐在像content/这样的 目录里,就因为那样方便。如果你的模板或代码不允许按你需要的方式来组织文件,就做一个快速的代码重构来让它支持。

避免将CSS、模板、布局和设计图或者JavaScript放进assets/(或者叫做uploads/resources/,要看你如何命名)。这些文件包含的是你的客户永远不需要考虑的有效代码,而assets/目录是用来放置和业务相关的文件和媒体的。把它作为工作流程中的一条金科玉律,并时刻遵守它。

  • 20 页网络应用 跟上面类似,不过到了这个等级你就绝对要把你所有的代码放到单独的目录里。确保它不在某个可能被Apache意外呈现的目录里,有时候一些小脚本会有些许错误。
  • 100页站点到了这个规模,你应该会用一个好的CMS系统来管理你的内容。用基于数据库的CMS或者基于文件系统的CMS都么有关系,但如果是后者,确保内容文件组织良好,并确保你能够定义每个页面的标题、描述等元数据,否者站点的SEO(译注:Search Engine Optimization,即搜索引擎优化)工作将会变得十分困难。 你可能也已经开始为站点划分不同的栏目。你有可能需要开始把样式表、JavaScript、设计图和模板按栏目分别提取到不同文件和目录中。确保这些目录互相匹配,并且和你网站的栏目匹配——或者是匹配其他的对特定网站有效的分类方式。至此,用一种Sass或者LESS这样的CSS语言是个不错的主意。
  • 2,500+页站点你绝对应该考虑雇佣针对于专们针对网站某一方面的人员,比如内容编辑、设计师、程序员和SEO专家。至此你也会想把内容存储到一个基于数据库的CMS里,如果之前不是的话。你将开始做经理,而让其他人干大部分的活儿。确保你有一个顺畅运作的合适的系统来让你能够检查他们的工作,并且在上线之前做好修改。
  • 100,000,000+页站点你是微软。你应该知道你现在在做什么。

大多数小网站很快会发展到超过20页,如果积极维护——到时你增加一些FAQ页面,一些深入探讨某些问题的小栏目,以及一两个作品——它增长很快。

说到这里,除非你确定这个项目是个一次性站点,比如一个关于某活动的资讯站,或者是为你妻子生日建立的网页,才考虑把你的小站按照上面说的(大约)20页站点来建设。为发展做好计划,但不要做曲棍增长曲线计划。

你的客户

和顾客沟通有助于理清事实。

和顾客沟通有助于理清事实。Andy Mangold配图

你应该为每个顾客建立一个目录,与你正在为他们做的项目文件无关。在这个目录里,为每个项目建立一个子目录。最初,只有一个叫做website/的目录,但是不久以后,你就会有其它的目录,比如叫做logo/、reports/、competitive analysis/之类的目录。把你的设计文件放进来也会有好处,或许放在design/或graphics/目录里。

不要让这个目录被Apache访问到。他会包含敏感信息。

根据你选用的框架,你可能会想要将代码放到这个目录里,让它们离开你的站点目录。你可以把它叫做code/,或者考虑到会有其他不同的代码而命名成website-code/。如果你的大部分其他项目都有相关的设计或业务,那么它们可能什么代码也没有,只有一些与原来不同的脚本,这些不需要单独的目录来存放。

除了顾客的工作目录,你可能需要一个完全独立的目录来存放不希望被顾客看到文档。你会发现自己需要频繁地与客户分享相关文旦个,很可能到某个时间点你会想要给他们访问属于他们的文件夹的权利(有些顾客会主动要求:“你能把所有我的文件都打包发给我吗?我只想确保我有所有东西的备份。”)。与其冒将“我痛恨这些家伙的十件事.doc”错发给他们的风险,不如把顾客的文件都放到他们的私人目录里。

为了方便回顾,下面以我们正在处理的结构为例:

 

YourBusiness/
  Accounts/
  Documents/
  Customers/
    bEat/
      Minutes/
      10 things I hate about these guys.doc
      Proposal.doc
    CustomerProjects/
      bEat/
        website/
            ... this is the bit we'll be discussing ....
        code/
            ... and this ...
        reports/
        graphics/

 

那么,这样的站点包括什么?

从现在起,我们讨论一下上面列出的code/website/目录。

图片

图片可以分为两类(绝大部分情况下都是):属于网站设计的图片和属于网站内容的图片。后者应该在你的assets/(或者叫做uploads/media/)目录里,或许包含在一个pictures/子目录。对于设计图,你几乎不需要去打破常规:把它们放到images/目录里。

如果你的设计有点儿复杂,你可能会有用于按钮、图标、导航、页面背景等等的图片。这种情况下,这个目录里很快就会有超过10页甚至20页的文件,所以考虑为它建立子目录。在顶层目录(译注:指images/)里有一般用途的图片也是可以的,不过子目录会有助于整理大量的小文件。给文件起个像form-warning-icon.png这样的感性而好记的名字。

样式表

对于大部分站点来说,你的样式表无需变得很大。对小站点来说,或者即使是稍大一些的站点,并没有不同的栏目(有着各自不同的设计),你通常只需要一个CSS文件。如果是这种情况,就叫它main.css或者style.css好了。

即使如此,许多人还是喜欢把它分解成多个文件。有很多不同的方法来完成这个工作。一种很流行的方式是一个用来布局的样式表,一个用来排印,还有一个用来指定颜色。这是个好主意,但是实际做起来却很困难——你可能会落得这样的下场:很多类被定义了3次(甚至以上),而跟踪bug将会是一场噩梦。

我认为把“布局”和“内容”样式分开是个更好的办法。“布局”包含了像导航栏、页眉页脚、边栏、盒状模型、片段的定义。“内容”包含了段落、标题、引用、列表、浮动图片、链接。如果你想要更进一步,为表单样式单独建立一个文件也是合理的。然而,随着网络日益具有交互性,表单和内容(没有别的意思)之间的界限很快就模糊了。

再次声明,请直截了当把这些文件命名为layout.css、content.css和forms.css。如果你给它们起些像presentation.css、model.css、page.css这样含糊不清的名字,你每次都要寻思该看哪个文件。

有时为那些有独特设计要求的页面建立独立的CSS文件是有用的。不过有时反而会带来更多麻烦,这要根据页面设计的复杂度来看。如果你发现你经常在编辑器的不同标签页(译注:不同的文件)之间切换,那么最好简化一下你的CSS文件了。同时认真考虑下使用Sass或者LESS让你的CSS更漂亮更干净。

如果你有多个CSS文件,那很好,不过在把它们放到服务器上之前,确保用自动化的工具将他们合并到了同一个文件中,否则你站点的下载速度会很糟糕。不要手动合并你完美地分解好的CSS。这是只要用一个土耳其行棋傀儡计算机就能轻松完成的作业。你可以借助MinifyPHP)或JuicerRuby)完成。

 

JavaScript

JavaScript

配图来源:dmitry-baranovskiy 来自Flickr

对很多站点来说,管理JavaScriptCSS文件有很多共同点。编写它们的目的很类似(并非完全相同),都是交由浏览器来解释、都和DOM交互(如果使用适当的话),而且它们还经常互相协作。JavaScript所为之添加功能的,和CSS修饰的经常是完全相同的一组元素。

你经常会有你的JavaScript库文件(jquery.jsmootools.js)、些许组件(比方说datepicker.jsdropdown.js)和一些站点独有的代码(例如my-image-slider.js)。把这些放在不同的文件里当然也没错,但是你会发现站点独有的JavaScript代码很少其实只要一个单独的文件来存放这部分代码。

把所有这些文件都放到一个叫做javascript/的目录里。假如你用了像jQuery这样的第三方库,你几乎不会创建出一个复杂到需要进一步分割这个目录的站点。

模板

模板只是一副骨架,需要用代码在其上勾画出躯体,并且用样式表配上绚丽的色彩。配图来源:dorena-wm 来自Flickr

模板不是内容,不是代码,也不是表现。模板可以包含所有这些东西,但如果使用正确,它应该是最明显的提示。把模板想象成骨架会对你有帮助。你的服务器端代码会用内容填充模板(来自数据库、错误提示、表单字段的内容等),然后浏览器会为它披上一件美丽的外衣,这样就得到了最终结果。

当然了,你的模板可能会包含可阅读的只言片语,用在按钮、下拉列表或者是别的什么上。这不是问题——这些文字和页面功能的关系更密切,而不不是内容。

把模板放到templates/目录。除了我上面提到的内容,模板就是一段服务器端代码(它们很敏感),所以不能被公开访问。

如果你的网站发送电子邮件,那么在这个目录里建一些子目录来存放纯文本和HTML邮件模板。如果你的站点不只是一个介绍性站点,你会需要很多模板,用在不同的页面和应用的界面上。要是你的站点有用于智能手机的版本,那么应该为它建立一个子目录。把这些目录恰当地组织起来。这里是一个好的样例:

templates/
    blog/
        sidebar.tpl
        post.tpl
        comment.tpl
    emails-plaintext/
        subscribe.tpl
        change-password.tpl
    emails-html/
        subscribe.tpl
        change-password.tpl
    social/
        twitter-feed.tpl
        facebook-sidebar.tpl
    mobile/
        base.tpl
        contact.tpl
        customer-profile.tpl
        friend.tpl
        homepage.tpl
        reviews.tpl
    base.tpl
    contact.tpl
    customer-profile.tpl
    friend.tpl
    homepage.tpl
    reviews.tpl

Assets

我不太喜欢这名字,不过其他候选项也好不到哪儿去。这是个用来存放所有音频、视频、文档、图片以及其他一切非文字性(或非HTML)的通常用于特定业务的对有人公开的站点内容。

这是一些备选的名字:uploads/、resources/、files/、media/。或者你可以把它分解成主目录下的多个目录,叫做pictures/、audio/ 等等——但是那很容易变得很混乱。无论如何,给不同类型的文件建立子目录更好些。

我个人倾向于用resources/这个名字,但是它有些抽象。并不是个好名字,不过比assets/要好(我们是什么人,会计师吗?)。不管怎么样,几乎是一个行业标准,要是我是个新手,我会用这个名字。所以在这篇文章里,就保持这个叫法吧。

如果这是个不需要考虑管理大量内容的小型商务站点,那么对这些文档的安全无需多虑。如果有需要,你应该把那些敏感的文档放到一个完全不相干的目录里。

如果你有一个有权限管理机制的大型站点,一定程度上你应该用一个文档管理系统。

做到这些,公开的文档会变得十分安全。你的客户应该能够自行上传文件到这个目录里并且通过CMS链接到它们。

如果并没有很多非网络文档,那么完全没必要进一步划分这个目录。但是如果你有很多这样的文件,那么建立photos/、pdfs/、videos/这样的子目录就很有意义。

数据库

这篇文章并不是关于数据库设计的,所以我们在这里不会说太多。但是保持你的数据库组织良好是非常重要的。任何情况下使用ORM(译注:Object-relational Mapping,即对象关系映射)——极少数的站点才会有一些特殊到ORM无法管理的数据需求。总之,事实上所有好的ORM都能够管理一切底层数据库可以管理的数据。

SQLite对于大多数站点来说都是一个很棒的选择,因为很容易配置,像一个简单的文件一样存在在你的文件系统里(却是一个全功能的关系型数据库),并且备份起来很简单(不需要花哨的导入/导出,除非你想要——只要用一个标准的文件备份解决方案;你显然已经有一个了,不是么?)。

给你的数据库起个和项目目录完全一样的名字。不要给你网站的不同方面建立不同的数据库,但是要给你开发的不同网站分别建立数据库。一如既往的保持简单,用简短的、完整的单词做名字,不要用各种前缀和后缀让名字变得很乱。

内容管理系统

这些宝贝们通常能够自行管理自己。但是一定要用一个组织合理编码完善的CMS。如果你用了一个基于文件系统的CMS,把所有内容放到一个子目录里,比如content/

管理模块

几乎所有人都会把管理文件放到admin/目录下。如果你有管理功能,也一样做。不要让管理模块有重复的代码、图片、JavaScript等。很明显,对于管理功能的特殊部分,你会有额外的代码之类。但是它应该和作为同一代码库的一部分,并且分解它以让站点的任何部分都能调用这些功能。

值得思考的是:你可能完全不需要管理功能。举例来说,如果你的客户需要上传和编辑图片,为什么不直给图片加一个“编辑”链接呢?文章、评论等的编辑也类似。当然,确保你有一个鲁棒性很强的授权和认证体制。

代码

哇!我该从哪儿开始说呢?软件开发完全是一个具有很强知识性的领域,而软件是我们已知的世界中最难保持条理的事物之一。我不会试图全面地描述所有方面。

无论如何,规则都一样:尽可能不把文件放在很深的目录结构里,用简短具象的名词给文件命名。在必要的时候使用子目录——不过对大部分网站来说你并不会有那么多的代码。所以放在顶层目录就好了。确保你对相同的东西使用了相同的名字——如果你的数据表叫做users,就不要把相关的文件叫做members.php。叫它members.php。

良好的代码分解是保持软件条理的最重要的方面,他涉及到代码的所有层面——从目录到变量名。这是区分合格程序员和缺乏经验的程序员的最重要因素。全面学习一下这一方面。

一些应该保存在他们各自的文件和目录中的东西:

  • 数据模型。如果个对象类型之间有着千丝万缕的逻辑关系,你可能需要为每个类建一个独立的文件。
  • View”(Django是这样称呼的)。也就是MVC中所说的“Controllers”。简单的说,“view”就是针对某一个特定URL的任何特定代码。
  • 通用类和函数。
  • 私人代码库。这甚至可能都不在你的项目或客户的目录里——你应该有一个系统性的自己的代码库集合,从而你不必管理同一个东西的多个副本。
  • 第三方代码库。

使用版本控制系统,比如SubVersion。想要学习版本控制,花点时间阅读guide to version control for web designers

这里经常会有和模板目录里对应的文件,虽然并不完全一一对应。但是只要有对应的,就用相同的名字。

将你的代码完全在可以公开访问的文件夹之外。你难道希望代码里不可避免会存在的代码漏洞被人们发现么?不要把HTMLCSS或者JavaScript混在你的服务器端代码里,反之亦然。

最终目录结构

当然,你应该考虑实际情况来决定怎么做对项目最好。下面绝非一个完整的例子,只是想让你理解我们讨论过的内容。

    bEat/
        website/
            images/
                boxes/ /* 对IE来说经常需要用到…… */
                    red-bottom-left.png
                    red-bottom-right.png
                    red-top-left.png
                    red-top-right.png
                navigation/
                    navigation-sprite.png
                    background.png
                logo.png
                page-background.png
                twirly-list-dot.png
            css/
                layout.css
                content.css
                print.css
                mobile.css
            javascript/
                jquery.js
                datepicker.js
                site.js
            assets/
                pictures/
                videos/
                pdfs/
            templates/
                blog/
                emails-plaintext/
                emails-html/
                social/
                mobile/
                *.tpl
            content/
        code/
            *.php
        reports/
        graphics/

这个项目的缩略形式:

    bEat/
        website/
            images/
            css/
            javascript/
            assets/
            templates/
            content/
        code/

无可否认,当你把它折叠起来之后看起来很基础。但是想要正确地扩充它是需要付出一定时间和努力的。你可以下载项目目录模板(.zip,一个框架PHP站点,有一个内容页面,基于H2O模板库。

或许你更喜欢下面这个形式。这样可以把一个项目的资源都放到一个目录里,代价是需要把所有的静态文件都放到更深一层目录里。如果你花很多时间来学CSSJavaScript,那可能对你来说不那么有用,但对你的项目和业务来说很重要。

    bEat/
        website/
            static/         /* 要是愿意你也可以叫它“public/” */
                images/
                css/
                javascript/
                assets/
                content/
            templates/
            code/

快速回顾

  • 保持整洁。不要为了寻求一个完美的目录层次而把大家逼疯,不过要避免为了图方便而把文件放错地方。
  • 用感性的文件名。能让你脑中立马反映出一幅(相关)图像的具象的单词是最好的。可能的话,就用单个单词给文件命名,但不要不惜一切代价地去做。
  • 当你需要用两个单词才能唯一区分一个文件的时候,经常(绝不总是这样)意味着你应该建一个子目录了。对于images/navigation-*.png,你最好替换成images/navigation/*.png。
  • 避免在文件名里使用多余的前缀和后缀。

当然 ,我们不是完美的,这里的建议决非唯一的(或是最好的)方式。如何管理你自己的站点文件?让我们在评论中讨论吧!


是一位来自新西兰“宁静的”基督城的Web开发和设计师。他领导了一支叫做Brush Technology的生机勃勃的web创业团队。除了工作,Bryan对音乐、艺术、文学和户外活动有着强烈爱好。 他的主页
In the context of the Linux kernel, the Virtual Memory Area (VMA) is a data structure that describes a range of virtual memory addresses that have a common set of attributes, such as permissions and caching behavior. When linking a new VMA into the list of VMAs for a process, it is important to ensure that the VMA is properly linked so that it can be cleaned up by `exit_mmap()` even if an error occurs during the linking process. Here is some sample code that demonstrates how to link a new VMA into the process's VMA list, even if an error occurs: ```c #include <linux/mm.h> int insert_vma(struct mm_struct *mm, struct vm_area_struct *vma) { int error; struct vm_area_struct *prev, *next; // Find the correct position to insert the new VMA prev = NULL; next = mm->mmap; while (next && next->vm_start < vma->vm_start) { prev = next; next = next->vm_next; } // Link the new VMA into the list vma->vm_next = next; if (prev) { prev->vm_next = vma; } else { mm->mmap = vma; } // Defer error checking until exit_mmap() error = 0; if (error) { // An error occurred, but link the VMA anyway vma->vm_flags |= VM_ACCOUNT; } return error; } ``` In this code, `insert_vma` inserts a new VMA `vma` into the process's VMA list. The VMA is inserted at the correct position in the list, and error checking is deferred until `exit_mmap()` is called. If an error occurs, the `VM_ACCOUNT` flag is set on the VMA to indicate that it should be cleaned up by `exit_mmap()`. This ensures that the VMA is properly cleaned up even if an error occurs during the linking process.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值