设计原则与js编程技巧

依赖倒置原则
  • 高层模块不应该依赖低层模块,两者都应该依赖抽象

  • 抽象不应该依赖细节

  • 细节应该依赖抽象

也可以说高层模块,低层模块,细节都应该依赖抽象

每一个逻辑的实现都是由颗粒原子逻辑组成的,颗粒原子逻辑就是低层模块,而颗粒原子逻辑组成的模块就是高层模块。在java语言中,抽象就是接口或抽象类,两都都是不能直接被实例化的,细节就是实现类,实现接口或继承抽象类而产生的类就是细节,两者都可以直接被实例化。

依赖倒置原则在java语言中,表现是:

  • 模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的。

  • 接口或抽象类不依赖实现类

  • 实现类依赖接口或抽象类

更加精简的定义就是“面向接口编程”—OOD(Object-Oriented Design,面向对象设计)的精髓之一。

单一职责原则

一个对象(方法)只做一件事情,应该仅有一个引起它变化的原因。SRP原则在很多设计模式中都有着广泛的运用,例如代理模式、迭代器模式、单例模式和装饰者模式。
SRP 原则的优点是降低了单个类或者对象的复杂度,按照职责把对象分解成更小的粒度,这有助于代码的复用,也有利于进行单元测试。当一个职责需要变更的时候,不会影响到其他的职责。

但 SRP 原则也有一些缺点,最明显的是会增加编写代码的复杂度。当我们按照职责把对象分解成更小的粒度之后,实际上也增大了这些对象之间相互联系的难度。

最少知识原则

最少知识原则要求我们在设计程序时,应当尽量减少对象之间的交互。如果两个对象之间不必彼此直接通信,那么这两个对象就不要发生直接的相互联系。常见的做法是引入一个第三者对象,来承担这些对象之间的通信作用。如果一些对象需要向另一些对象发起请求,可以通过第三者对象来转发这些请求。在设计模式中体现得最多的地方是中介者模式和外观模式

把变量的可见性限制在一个尽可能小的范围内,这个变量对其他不相关模块的影响就越小,变量被改写和发生冲突的机会也越小。这也是广义的最少知识原则的一种体现。

开放-封闭原则

软件实体(类、模块、函数)等应该是可以扩展的,但是不可修改。开放封闭原则是一个看起来比较虚幻的原则,并没有实际的模板教导我们怎样亦步亦趋地实现它。但我们还是能找到一些让程序尽量遵守开放封闭原则的规律,最明显的就是找出程序中将要发生变化的地方,然后把变化封装起来。通过封装变化的方式,可以把系统中稳定不变的部分和容易变化的部分隔离开来。在系统的演变过程中,我们只需要替换那些容易变化的部分,如果这些部分是已经被封装好的,那么替换起来也相对容易。而变化部分之外的就是稳定的部分。在系统的演变过程中,稳定的部分是不需要改的。

分离变化的方式 1. 放置挂钩 2. 使用回调函数
设计模式中的开放 - 封闭原则:. 发布订阅模式, 模板方法模式,策略模式,代理模式,职责链模式

接口和面向接口编程

当我们谈到接口的时候,通常会涉及以下几种含义,下面先简单介绍。

  • 我们经常说一个库或者模块对外提供了某某 API接口。通过主动暴露的接口来通信,可以隐藏软件系统内部的工作细节。这也是我们最熟悉的第一种接口含义。

  • 第二种接口是一些语言提供的关键字,比如 Java的 interface 。 interface 关键字可以产生一个完全抽象的类。这个完全抽象的类用来表示一种契约,专门负责建立类与类之间的联系。

  • 第三种接口即是我们谈论的“面向接口编程”中的接口,接口的含义在这里体现得更为抽象。用《设计模式》中的话说就是:接口是对象能响应的请求的集合。

JAVA抽象类和 interface 的作用主要都是以下两点。
 通过向上转型来隐藏对象的真正类型,以表现对象的多态性。
 约定类与类之间的一些契约行为。

js代码重构
  • 提炼函数
    如果在函数中有一段代码可以被独立出来,那我们最好把这些代码放进另外一个独立的函数中。这是一种很常见的优化工作,这样做的好处主要有以下几点。
     避免出现超大函数。
     独立出来的函数有助于代码复用。
     独立出来的函数更容易被覆写。
     独立出来的函数如果拥有一个良好的命名,它本身就起到了注释的作用。
  • 合并重复的条件片段
    如果一个函数体内有一些条件分支语句,而这些条件分支语句内部散布了一些重复的代码,那么就有必要进行合并去重工作。把条件分支语句提炼成函数在程序设计中,复杂的条件分支语句是导致程序难以阅读和理解的重要原因,而且容易导致一个庞大的函数。
  • 合理使用循环
    在函数体内,如果有些代码实际上负责的是一些重复性的工作,那么合理利用循环不仅可以完成同样的功能,还可以使代码量更少。下面有一段创建 XHR 对象的代码,为了简化示例,我们只考虑版本 9以下的 IE浏览器,代码如下:
var createXHR = function () {
    var xhr;
    try {
        xhr = new ActiveXObject('MSXML2.XMLHttp.6.0');
    } catch (e) {
        try {
            xhr = new ActiveXObject('MSXML2.XMLHttp.3.0');
        } catch (e) {
            xhr = new ActiveXObject('MSXML2.XMLHttp');
        }
    }
    return xhr;
};
var xhr = createXHR();

下面我们灵活地运用循环,可以得到跟上面代码一样的效果:

var createXHR = function () {
    var versions = ['MSXML2.XMLHttp.6.0ddd', 'MSXML2.XMLHttp.3.0', 'MSXML2.XMLHttp'];
    for (var i = 0, version; version = versions[i++];) {
        try {
            return new ActiveXObject(version);
        } catch (e) {
        }
    }
};
var xhr = createXHR();
  • 提前让函数退出代替嵌套条件分支
var del = function (obj) {
   var ret;
   if (!obj.isReadOnly) { // 不为只读的才能被删除
       if (obj.isFolder) { // 如果是文件夹
           ret = deleteFolder(obj);
       } else if (obj.isFile) { // 如果是文件
           ret = deleteFile(obj);
       }
   }
   return ret;
};

可优化为

var del = function (obj) {
    if (obj.isReadOnly) { // 反转 if 表达式
        return;
    }
    if (obj.isFolder) {
        return deleteFolder(obj);
    }
    if (obj.isFile) {
        return deleteFile(obj);
    }
};
  • 传递对象参数代替过长的参数列表
  • 尽量减少参数数量
  • 少用三目运算符
    如下可读性没if-else好
if (!aup || !bup) {
    return a === doc ? -1 :
        b === doc ? 1 :
            aup ? -1 :
                bup ? 1 :
                    sortInput ?
                        (indexOf.call(sortInput, a) - indexOf.call(sortInput, b)) :
                        0;
}
  • 合理使用链式调用
    使用链式调用的方式并不会造成太多阅读上的困难,也确实能省下一些字符和中间变量,但节省下来的字符数量同样是微不足道的。链式调用带来的坏处就是在调试的时候非常不方便,如果我们知道一条链中有错误出现,必须得先把这条链拆开才能加上一些调试 log或者增加断点,这样才能定位错误出现的地方。
    如果该链条的结构相对稳定,后期不易发生修改,那么使用链式调用无可厚非。但如果该链条很容易发生变化,导致调试和维护困难,那么还是建议使用普通调用的式:

  • 分解大型类
    可以将对象中的行为单独设为一个行为类
    并增加行为对象为属性即可

  • 用 return 退出多重循环

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值