zoukankan      html  css  js  c++  java
  • Qomo项目中代码的一般性约定

     ================================================================================
    Qomolangma OpenProject v1.0


    类别    :Rich Web Client
    关键词  :JS OOP,JS Framwork, Rich Web Client,RIA,Web Component,
              DOM,DTHML,CSS,JavaScript,JScript

    项目发起:aimingoo (aim@263.net)
    项目团队:../../Qomo_team.txt
    ================================================================================


    一、变量声明的一般性方法
    ~~~~~~~~~~~~~~~~~~
    Qomo约定在全局空间进行变量声明时,应用var关键字来声明,而不应当省略(尽管语法上讲能这样做)。
    声明时的代码格式尽可能使用如下形式:
    ------------------
    var
      v1 = 1234;
      v2 = 'abcd';
    ------------------

    或为每行声明都保留var关键字,例如:
    ------------------
    var v1 = 1234;
    var v2 = 'abcd';
    ------------------

    Qomo约定在函数内部声明局部变量进,使用var关键字时可以用如下省写形式:
    ------------------
    var
      v1 = 1234,      // <-- 注意行未是逗号
      v2 = 'abcd';
    ------------------

    或为每行声明保留var关键字。

    Qomo反对在函数内部声明全局变量。

    二、Qomo中一些保留的命名
    ~~~~~~~~~~~~~~~~~~
    Qomo会将一些实现特殊的、具有“关键字”性质的功能声明为全局函数。它们通常具有特殊的名字,而且
    是以大写字符开始的(这看起来有点象构造器,但并不是)。这些函数名部分看起来象JavaScript的保留字,
    但由于javascript的命名是大小写区分的,且保留字都使用小写字符,因此这并不冲突。这些全局函数有:
    ------------------
      Class()        : 注册类
      Attribute()    : 快速属性声明
      Interface()    : 接口声明
      Aggregate()    : 接口聚合
      Abstract()     : 抽象方法
      NullFunction() : 空函数/空方法
    ------------------

    Qomo为构建系统框架,使用标准的JS原型继承的方式在全局范围内声明了一些类(构造器),用户代码应该
    避免覆盖这些名称。这些命名包括:
    ------------------
      Url()             : 分析一个Url地址
      Ajax()            : Ajax异步方式
      MuEvent()         : 多投事件
      CustomArguments() : 标识函数入口使用了定制参数
      BreakEventCast()  : 标识事件投送列表被中止
      JoPoint()         : 切面系统中的连接点
      JoPoints()        : 切面系统中的连接点列表
      Profilers()       : 创建系统分析对象
    ------------------

    作为习惯,Qomo保留了一些(少量的)全局的工具函数,例如:
    ------------------
      format()             : 指向String.format();
      RegisterInterface()  : 指向Interface.RegisterInterface()
      QueryInterface()     : 指向Interface.QueryInterface()

      isAlias()            : 检测一个命名空间是否是别名
      isNamespace()        : 检测一个变量是否是命名空间声明

      getAllFunctions()    : (用于调试与性能分析,) 列出一个代码块中调用过的函数与方法
      showProfiler()       : (用于调试与性能分析,) 调用$debug来显示性能分析报告
    ------------------

    除了上述三种情况,Qomo中将尽可能少的占用全局的命名,例如函数或变量。

    为此,Qomo为开发人员准备了一份资料文档,用于通告哪那些全局函数、类与命名空间被使用了,开发
    人员应尽可能避免出现相冲突的命名。

    三、Qomo中的一些命名约定
    ~~~~~~~~~~~~~~~~~~
    1. 系统的特殊声明
    ==============
    Qomo约定以$开始的变量为系统特殊的声明,它通常是关键的函数或可能在系统编译时被特殊处
    理的函数。这些函数主要包括:
    ------------------
      $import() : 导入文件或包
      $inline() : 内联代码块
      $assert() : 断言
      $debug()  : 调试输出

      $map()    : 创建命名与路径的映射
      $mapx()   : 展开命名空间
      $n2p()    : 命名空间到路径的转换
      $p2n()    : 路径到命名空间的转换

      $profilers : (对象)全局的性能分析器

      $Q() : 等同于$QomoConfig
      $QomoConfig() : 查询Qomo装载时或编译时的配置信息
      $QomoCoreFunction : 简单地返回一个函数用来替换Function对象的toString()方法,以保护代码
    ------------------

    此外,一些函数内的局部变量也使用$来表明它的特殊性。


    Qomo约定以"_"开始的函数具有使用的上下文环境限制。主要包括:
    ------------------
    // 以下函数仅能在类声明中使用
    //  - 注: Attribute()也仅能在类声明使用
      _cls : 取类引用
      _get : 类内部信息的getter
      _set : 类内部信息的setter
    ------------------

    此外,一些函数内的局部变量也使用_来表明它的特殊性,或与一个没有该前缀的同名函数存在关联。


    Qomo约定全大写的变量是系统保留的,或有特殊的含义的变量,该规则并不限于在函数内/外使
    用。例如:
    ------------------
      _RTLOBJECT : 在Qomo替换之前的Object()构造器
      _RTLERROR  : 在Qomo替换之前的Error()构造器
    ------------------

    2. 异常
    ==============
    Qomo约定以字符“E”开始并紧邻一个大写字母表明一个异常。异常可以用数组形式来表示,例如:
    ------------------
      ECallClassBadArguments = [8101, 'Arguments error  for Class().'];
      ERegClassNoname = [8102, 'With call Class(), lost class name .'];
      EAccessSafeArea = [8104, 'Try Access Safe area.'];
    ------------------

    3. 类与类类型注册
    ==============
    Qomo约定以大写字母开始的函数通常是类构造器,而以小写字母开始的函数是普通函数或方法。这
    一点是JavaScript惯用的代码风格。例如:
    ------------------
      // 类构造器
      function MyObject() {
        // ..
      }

      // 方法或函数
      function callSafeMethod() {
        // ..
      }
    ------------------

    Qomo约定应当以字符“T”开始,后面紧跟构造器函数名的格式对一个类进行类注册。Qomo的OOP系统和命
    名空间系统依赖于类注册。类注册使用Class()函数。例如:
    ------------------
      // 类构造器声明
      function MyObject() {
        // ...
      }

      // 类注册
      TMyObject = Class(Object, 'MyObject');
    ------------------

    4. 事件、事件句柄与事件类型
    ==============
    Qomo约定以On开始的属性为事件,而以do开始的函数通常用作事件句柄。例如:
    ------------------
      function doCall() {
        // ...
      }

      function MyObject() {
        this.OnCall = NullFunction;
      }

      var obj = new MyObject();
      obj.OnCall.add(doCall);
    ------------------


    Qomo约定事件可以用一个函数声明来描述事件的接口,但这个声明除了便于开发人员使用之外,并没有
    任何价值。一般情况下,该声明应该以字符“T”起始,紧接事件名,最后可以用Event结束。例如:
    ------------------
      TOnCall = function(item, index) { }
      TOnLoadEvent = function(filename, filenum) { }

      function MyObject() {
        this.OnCall = TOnCall;
        this.OnLoad = TOnLoadEvent;
      }
    ------------------

    对于上面的声明来说,OnCall与OnLoad后面是一个空函数(NullFunction)还是一个事件类型的声明并没有
    关系。上面这样做,只是便于开发人员理解:当事件发生时,事件句柄可以得到怎样的入口数据。

    由于“事件类型”只有声明和描述的价值,它事实上从来不会被执行。因此,可以在不同的文件中,或者
    相同文件的不同类、不同位置重复的声明相同名字的“事件类型”。这对程序执行不会有负面的影响。

    5. 接口
    ==============
    Qomo约定接口是以“I”字符开始来声明一个函数。接口的方法应声明为Abstract。例如:
    ------------------
      IInterface = function() {
        this.QueryInterface = Abstract;
      }
    ------------------

    6. 切面
    ==============
    Qomo约定应尽量以asp或asp_为前缀来声明切面。例如:
    ------------------
      var asp_OnTimer = new ObjectAspect(T2, 'OnTimer', 'Event', x0);
      var asp_getTopoString = new FunctionAspect(getTopoString, 'getTopoString', 'Function');
    ------------------

    7. 内联代码
    ==============
    使用$inline()可以将一个代码片断内联到当前位置执行。Qomo约定被联接的代码块应该是一个独立的
    文件,文件中可以包括注释,其代码体应该被包含在一个标签声明当中。这个标签声明只用于表现该
    代码块的特殊性,实际上没有执行价值。

    该标签声明应当以“_inline_”为前缀。例如:
    ------------------
    /**
     *
     * 内联代码可以按JS的语言规范任意包含注释
     *
     */
    _inline_object_regAllInterfaceForClass: {

        // register interfaces for Class's all instnaces
        if (arguments.length > 2) {
          Interface.RegisterInterface.apply(cls, [cls].concat(
            Array.prototype.slice.call(arguments, 2)
          ))
        }

    }
    ------------------


    8. 字符串、数组、正则等使用中的一般性规则
    ==============
    Qomo约定尽可能以单引号来声明字符串,而将双引号留给HTML中的属性来使用。

    Qomo约定以如果在全局使用正则表达式,应该以“_r_”为前缀声明,在函数局部使用正则表达式,应
    尽可能使用该规则。例如:
    ------------------
      _r_event = /^On.+/;
      _r_attribute = /^([gs]et)(.+)/;
    ------------------

    JavaScript中常用数组来表达一张表格,Qomo建议这种情况下的代码应该写成如下格式:
    ------------------
    var aTable = [
     [v1, v2, v3,                   v4],
     [v1, v2, v3,                   v4],
     [v1, v2, this_is_long_variant, v4],
     [v1, v2, v3,                   v4]   // <-- 注意最后一行没有","号
    ];
    ------------------

    尽可能用对齐的方式来避免表格修改时导致的出错。

    四、Qomo中的一些特殊使用法
    ~~~~~~~~~~~~~~~~~~
    1. 对象(Object)的特殊用法
    ==============
    Qomo直接替换了构造器Object(),因此使用new Object()的方式会构造出一个Qomo格式的对象实例。
    但用户代码中仍然可以通过直接量声明来得到一个“原生的”JavaScript对象。例如:
    ------------------
    var
      obj_1 = new Object();   // Qomo对象
      obj_2 = { };            // JavaScript原生的、直接量声明的对象
    ------------------

    二者的区别在于,obj_1因为是Qomo对象,因此必然具有如下方法和属性:
    ------------------
      obj_1.ClassInfo
      obj_1.get()
      obj_1.set()
      obj_1.inherited()
    ------------------

    而obj_2由于是原生的JavaScript对象,因此使用for .. in来列举时,不会看到任何“显式的”
    属性与方法。

    Qomo约定用户代码不应当修改直接量形式所得到的Object的原型(prototype)。由于这种对象没有任
    何“显式的”属性与方法,因此它可以用来做for ..  in做一些高速的列表处理。部分内核代码使用
    了这种特性。

    ——在firefox等mozilla引擎中,对替换后的Object()进行原型修改会污染(我并不确定这是否更加
    规范)原生的、直接量声明的对象。因此本项“特殊用法”应当谨慎使用。

    10. 匿名函数的特殊使用法
    ==============
    为了避免一段代码占用全局空间中的名称(命名污染),通常会使用匿名函数来执行一段代码。Qomo
    建议这种情况下使用void来触发该匿名函数的执行。——而不是使用一对括号来做相同的事。例如:
    ------------------
    // 推荐用法
    void function() {
      // 你的代码...
    }();


    // 不推荐用法
    (function() {
      // 你的代码...
    })();
    ------------------

    如果执行的结果会返回值,例如声明一个变量。则建议使用如下的结构:
    ------------------
    var myFunc = function() {
      // 一些私有变量的声明
      var ...


      // 你的函数
      var _myFunc = function() {
        //...
      }

      // 返回
      return _myFunc;
    }();
    ------------------

    如果不对上述的_myFunc做特殊处理(例如添加属性),那么上述的代码可以简化至:
    ------------------
    var myFunc = function() {
      // 一些私有变量的声明
      var ...


      // 返回你的函数
      return function() {
        //...
      }
    }();
    ------------------

  • 相关阅读:
    uni-app调用原生的文件系统管理器(可选取附件上传)
    uni-app图片压缩转base64位 利用递归来实现多张图片压缩
    解释器模式
    外观模型
    装饰模式
    组合模式
    原型模式
    简单工厂模式
    抽象工厂模式
    工厂方法模式
  • 原文地址:https://www.cnblogs.com/encounter/p/2188685.html
Copyright © 2011-2022 走看看