前面的一篇文章,我介绍了Jla框架的代码单元的规范,为什么需要有这样的规范?最主要的目的还是将能够将代码和功能进行有条理的拆分,让每个代码单元仅仅关注自身的逻辑,这样就可以提高代码的重用性。
可是要真的实现让每个代码单元能够心无旁骛的开始自身逻辑的实现,仅仅有一个框架规范还远远不够,我们必须对一些大部分代码单元都会关心的问题提供一个合理的解决方案,保证代码单元不再为这些事情而操心,其中最重要的两个解决方案是资源管理和配置管理,关于配置的管理,我会在下一篇文章之中讲到,本文将首先讲到资源管理。
在本框架之中,每个程序是以JavaScript为主体的,但是单靠JavaScript,肯定不能实现那些丰富多彩的应用,对图片、CSS或者其他资源的调用是很平常的内容,也就是说,一个程序单元(或者说一个类)除了有一个Js文件以外,还有可能有一系列的图片、CSS片段文件甚至音乐视频等多方面的内容,这些(统称为资源文件)和脚本文件合在一起,才组合成为一个程序单元,如果要考虑代码的重用和独立性的问题,这些资源文件也应该考虑进去。
对于资源的调用,我设计了这样的一个解决方案:
1.开发的时候,假设资源文件和类文件一样,都是分目录存放的, 例如对于命名空间Com.Test.ClassA,类文件的路径为:
workspace/src/Com/Test/ClassA.js
假设类ClassA调用了一个图片test.png,则应该放在:
workspace/resource/Com/Test/ClassA/test.png
这样,每个类都有自己的资源目录,将自己的多个资源放在目录下即可,也不用担心和其他的文件名冲突的问题
2.假如类ClassA之中想要调用自己的资源,当然不能直接写路径(如果直接写路径,基本上不能保证代码部署后或者移动之后还能执行),建议ClassA在定义的时候require Js.Resource类,然后调用该类的静态方法getUrl,例如:
1 Jla.require(["Js.Resource","namespace.ClassB"],2,function(Resource,ClassB)
3 // code of ClassD start
4 function App()
5 {
6 var img = document.createElement( " img " );
7 img.src = Resource.getUrl(App, " test.png " );
8 }
9 App.prototype.onClick = function ()
10 {
11 Jla.require([ " namespace.ClassC " ], 1 , function (ClassC)
12 {
13 // 调用ClassC.完成点击之后执行的操作
14 })
15 }
16 // code of ClassD End
17 Jla.set( " namespace.ClassD " ,App);
18 })
在代码最终部署的时候,资源的访问路径和组织形式可能和开发的模式有所不同,这种情况下,只需要在发布的时候通过更改Resource类的配置或者重写getUrl的方法,就可以让每个代码单元正常访问到自己的资源,各个代码单元不需要做任何更改。另外,可以根据代码单元的require关系,完全不需要的代码单元,其对应资源也不用发布到部署环境之中。
以上就是针对资源的解决方案,该解决方案将代码单元和资源之间的关系简单化,带来很多方便。
下面说说带来的一个问题,就是Sprite,因为按照现有的框架,我希望能将不同的代码单元的资源分目录存放,可是现在很多网站上,将多个图片(很有可能是毫无关联)的图片组合到一张图片上,这样,似乎就很难对代码进行有效的拆分,针对这个问题,我提出如下的解决方案:
首先,我认为,Sprite不应该是开发时就需要考虑的内容,而是部署时需要考虑的内容,因此,我不建议各个代码单元在开发的时候就使用合并起来的图片,这样会大幅度的减少代码重用性,最好在开发的时候,图片还是一个个的分离的图片,每个代码单元调用自己的资源图片,哪怕代码单元内部,也不建议使用Sprite技术,因为我说过:Sprite不应该是开发时就需要考虑的内容,而是部署时需要考虑的内容。
现在假设各个程序单元开发的时候都没有考虑过Sprite的问题,怎么实现Sprite呢?我想通过这样一个类似于重写的技术:
1.假设每个代码单元,在显示图片的时候,都使用一个类Js.Html.Image,这个类提供了create(用来根据URL创建一个图片实例),setSrc(用来更改一个图片实例的src),setBackground(用来设置背景图)三个方法,这三个方法包含了所有图片的基本使用
2.Js.Html.Image还提供了一个addSprite方法,用于通知Image类,哪些图片被整合到了另一张图片的什么地方,例如:
2 {rect:[ 0 , 256 , 300 , 44 ],path:Resource.getUrl( " Test.Class1 " , " test.png " )},
3 {rect:[ 0 , 212 , 300 , 44 ],path:Resource.getUrl( " Test.Class2 " , " test.png " )},
4 ],{size:{x: 300 ,y: 300 }})
这样,Image类记录下这个信息,在创建Test.Class1的test.png图片的时候,最终实际上会去img/image.png的某一块上去获取图片显示,这样就实现了图片的Sprite方案。
这样做,我觉得比一般的Sprite方案有更多优点:
1.和开发过程基本无关,使开发过程不受影响,要知道网上讨论Sprite技术的时候,一致表明缺点是使开发和维护复杂化
2.假如Sprite图片做了调整,只需要改上面的配置即可,不需要到处调整。
3.将完全无关的功能组合在一起也完全不是什么问题
这样就实现了这种模式下的Sprite技术,本来应该将这个关键的Image对象源码展示一下的,但是这个还没有完善,而且,本系列文章主要是介绍新框架的思路,源码并不是特别重要,而且,一般写一个出来也不会太复杂吧。