模块化还是跨平台?
大家好,很高兴又见面了,我是能说会道,技术一流的一灯小雨。今天来聊个轻松有趣的话题吧。。。
因为职业关系,本人也常关注一些技术大婶(神)的个人网站或论坛,也会就一些话题和跟自己没有半毛钱关系的水友展开针锋相对的讨论。不过很多话题的讨论毫无意义,多半都无疾而终,根本没有得出好的结果。我发现一个有趣的现象,很多水友你和他讨论来讨论去,突然发现这几天来他就没影了,没人接茬了,我猜想可能是他最近上班论坛逛论坛逛得有点多了,把工作进度落下了,老板对他很不满意,让他加班去了。这个话题自然也就只能就此搁置,我也只落得一个大大的没趣。两星期后,他在论坛发言了(可能是项目完成了或者实现了阶段性目标,他又能逛论坛了),我也不想理他了。
这段代码发生了什么?
最近在某大神的个人微博下有看到一个水友的提问。提问方式是非常经典却又简单粗暴的菜鸟式提问:代码xxxxx,问:这段代码发生了什么?结果当然是可想而知的,没有人回复这条提问。我把该提问粘贴如下,供你参考:
var validate = function(){}
{
validate = function(){
//此处省略
}
}
//问:这是一段react源码,这样写有什么好处?
很自然的,我也不想回复这个提问,主要原因是我也没觉得这样写有什么好处,没什么好说的,期待有大神来回复。不过我注意到提问者的头像是一朵巨大的牡丹花,非常的漂亮,我脑子的某根神经动了一些,于是回复道:我觉得这个问题非常好,可以深入挖掘很多东西。我料想对方如果反应迟缓,老半天才回复,那么这事也就完了,我还不如去打盘王者荣耀。不过对面的回复却很快。这样一来二去讨论半天,一切都如我所愿。微信也加了,性别也确认了,年龄也确认了。是妹子,年轻的妹子!那么关于这段代码,你有什么想法呢?欢迎给我留言吧!
模块化?
初看上面的代码,确实让人摸不着头脑。再仔细一看,就会发现,这个问题实际上问的是最外面的大括号为什么要这么用?我们看到大括号中既没有let,也没有const,仅仅是做了一个赋值操作。这在词法层面,没有任何逻辑意义,同样在运行时也没有形成局部作用域。这完全是没有任何意义啊!我说错了,它的意义在于大括号提供了代码缩进功能。不过,这样回复人家显然不太好吧,这样就没话聊咯,所以我的回答是:嗯,这个意义重大,非常值得深入研究。然后,嘚吧嘚。。。嘚吧嘚。。。经过一番讨论,我发现,这个大括号确实并非毫无意义,比如它对于模块化和分组开发的意义。我们可以试想一个这样的场景:在开发中,由你负责代码整体架构的把控。应用需要一系列的增删改查操作,而你希望将这一部分功能交给手下人去完成。你如何定义接口呢?
你如何确定这些接口的实际完成程度呢?那么我们对上面的代码稍加改造,可以提供一个可供参考的方案。我们先新建一个文件sql.js,代码如下:
var insert = function(){console.log('coding...');}
{
insert = function(){
//todo
}
}
var del = function(id){console.log('coding...');}
{
//此处写具体实现
}
var update = function(entity){console.log('coding...');}
{
//此处写具体实现
}
var query = function(name){console.log('coding...');}
{
//此处写具体实现
}
exports.insert = insert;
exports.del = del;
exports.update = update;
exports.query = query;
在实际开发中,你可以写好这样一个文件模板。然后提交到svn或git上,并通知相关人员下载文件填写具体实现的代码。我们可以看到,这个文件对于具体实现人员来说非常的友好。当相关人员下载了该文件一看,基本上一目了然,不需要和你再沟通什么了,要实现的接口清清楚楚,函数的参数列表也有默认值可控参考。这样不是很好吗?同样的,我们的调用方再调用以上的代码时也是由诸多好处的。我们实现一下调用,这里再新建文件index.js,代码如下:
var demo = require('./demo')
demo.insert();
demo.del();
demo.update();
demo.query();
运行结果我们看到:凡是还没有重新实现的接口,我们调用时会再控制台打印‘coding...’,而重新实现过的接口会走新的实现逻辑。这样做的好处在于,在实际开发中,我只需要查看相关接口的调用结果就能判断接口的完成进度,而不是到接口的具体实现文件中去查看。换句话说,我不看sql.js的内容,就知道那个家伙有没有把sql.js写完,而且知道你哪些接口已经写好,哪些接口还没写。另外一个好处是:调用方不会因为实现方还没有实现某些接口而导致异常。这样不是很好吗?好了,关于模块化,就说这些,您认同我的这个方案吗?或者您是否有更好的想法呢?给我留言吧。
跨平台?
上文中提到的模块化方案并没有回答我们一开始提出的问题:最外层的大括号是做什么用的?难道真的只是为了缩进吗?我们可以看到在代码管理上,sql.js的代码结构是非常棒的。这个文件由接口设计者和接口实现者共同完成,或者还会由更多人一起配合编写,但是代码结构层次非常清晰,设计者和实现者的代码一目了然,没有相互混杂。那么除此之外,还有什么呢?我们是不是可以拿这个该死的大括号做点什么呢?在这里,我提供一个跨平台思路,供大家餐考。我们试想这样一个场景:因为某种特殊原因,我们的增删改查接口不得不触及到一些和平台相关的系统调用,这样我们就不得不针对不同的平台编写不同的具体实现。我们在此先添加一个与平台相关的配置文件config.js,代码如下:
exports.config = {
platform:'linux'//iOS,windows,anroid
};
这时候,就能用到前面的大括号了,我们对sql.js进行下面的改造:
var config = require('./config').config;
var insert = function(){console.log('coding...');}
if(config.platform === 'linux')
{
insert = function(){
console.log('linux');
}
}
else if(config.platform === 'ios')
{
insert = function(){
console.log('ios');
}
}
else if(config.platform === 'windows')
{
insert = function(){
console.log('windows');
}
}
else if(config.platform ==='android')
{
insert = function(){
console.log('android');
}
}
var del = function(){console.log('coding...');}
{
}
var update = function(){console.log('coding...');}
{
}
var query = function(){console.log('coding...');}
{
}
exports.insert = insert;
exports.del = del;
exports.update = update;
exports.query = query;
首先我们引入了config.js文件,利用config中的平台设置对不同的平台进行具体的实现。好高兴,终于把那个大括号利用上了。这样不是很好吗?你觉得呢?那么,我们在次进行改造。代码如下:
var config = require('./config').config;
var insert = function(){console.log('coding...');}
var del = function(){console.log('coding...');}
var update = function(){console.log('coding...');}
var query = function(){console.log('coding...');}
if(config.platform === 'linux')
{
insert = function(){
console.log('linux');
}
del = function(){};
update = function(){};
query = function(){};
}
else if(config.platform === 'ios')
{
insert = function(){
console.log('ios');
}
del = function(){};
update = function(){};
query = function(){};
}
else if(config.platform === 'windows')
{
insert = function(){
console.log('windows');
}
del = function(){};
update = function(){};
query = function(){};
}
else if(config.platform ==='android')
{
insert = function(){
console.log('android');
}
del = function(){};
update = function(){};
query = function(){};
}
exports.insert = insert;
exports.del = del;
exports.update = update;
exports.query = query;
文件头部为接口定义,中部为根据不同平台的具体实现,尾部为接口导出。这样我们的代码就能根据config中的平台设置而调用相应的具体实现。不过,我琢磨来琢磨去,感觉还是在具体实现外面加个大括号看着舒服,如下面这样:
var config = require('./config').config;
var insert = function(){console.log('coding...');}
var del = function(){console.log('coding...');}
var update = function(){console.log('coding...');}
var query = function(){console.log('coding...');}
{
if(config.platform === 'linux')
{
insert = function(){
console.log('linux');
}
del = function(){};
update = function(){};
query = function(){};
}
else if(config.platform === 'ios')
{
insert = function(){
console.log('ios');
}
del = function(){};
update = function(){};
query = function(){};
}
else if(config.platform === 'windows')
{
insert = function(){
console.log('windows');
}
del = function(){};
update = function(){};
query = function(){};
}
else if(config.platform ==='android')
{
insert = function(){
console.log('android');
}
del = function(){};
update = function(){};
query = function(){};
}
}
exports.insert = insert;
exports.del = del;
exports.update = update;
exports.query = query;
代码一多,我认为缩进还是很重要的,这样比较方便阅读,更容易理顺代码的整体结构。你觉得呢?以上就是我关于上文提到的大括号问题所想到的一些扩展,希望能对你由所帮助或者引发你的一些思考,如果你有什么好的想法或者建议不妨给我留言,一起学习,一起进步。哦,还有,再提一下前面说的妹子吧!我加了她微信后就去她朋友圈看了,她的朋友圈内容基本都是晒娃,我挺失望的。我有问她为什么有娃了还做开发?她回答说:“我只会做这个呀!”
好了,就到这里吧,那么下一篇文章见吧!