设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。
可以看出,23种设计模式也不是凭空捏造出来的,而是经过了反复的推敲修改以及诸多的项目实战总结而出的代码设计经验。因此,能作为一种模式(pattern),设计模式不再是代码的罗列,而是扎实的逻辑结构,每一种设计模式都拥有成熟的思想。
设计模式的发展
既然是“模式”,那么容易得出设计模式可以应用于各种各样的编程语言中,而且所得出的表现都应该是一样的。对于一些像是C#、Java、C++这样的比较明确的面向对象的语言,一种设计模式在各语言之间的转换都是比较容易的,只是语法不同而已。但是,JavaScript作为一种弱类型的切十分灵活的语言,甚至没有明确的class这个关键字,随着Node和HTML5以及web2.0的兴起才开始受到比较多的重视,设计模式对她来讲就和变得和别的语言不同。
但是,很多东西Javascript都有,只是没有作为正式的部分。而设计模式又是一种编程的思想,思想是相同的,一旦你掌握了这种思想,代码就可以相通,利用一些javascript的特性来实现各种设计模式应该也不是一件特别难的事情。
设计原则
面向对象程序设计有几个原则:开闭原则、里氏转换原则、依赖倒转原则、接口隔离原则、合成/聚合复用原则、最小知识原则。开闭原则具有理想主义的色彩,它是面向对象设计的终极目标。设计模式正是通过实现这些原则来达到代码复用、增强可维护性的目的。
这些原则并不是固定的,任何人都可以提出更好的原则
开闭原则(Open Closed Principle,OCP)
此原则是由Bertrand Meyer提出的。原文是:“Software entities should be open for extension,but closed for modification”。
模块应对扩展开放,而对修改关闭。模块应尽量在不修改原来的代码的情况下进行扩展。
举个例子,假设现在有一个已经开发完成的规模不小的软件系统,有人提需求说我要再加一个功能,那么这时候去修改源代码显然是不明智的,不仅违反了开闭原则,而且那么多的代码,工作量肯定也很大。为了要实现这个需求,可以在原来的软件系统中扩展出来一个功能,只需要编写调试这个新功能模块的代码,这就是开放扩展,关闭修改。
里氏代换原则(Liskov Substitution Principle,LSP)
里氏代换原则是由Barbara Liskov提出的。可以描述为:子类继承于父类,可以单独调用,如果调用的是父类的话,那么换成子类也完全可以运行。从开闭原则可以看出,设计模式一个重要的部分是抽象化,里氏代换原则从另一个角度描述了抽象(父类)和具体(子类)之间的关系。举例,猫科动物可以完成捕猎这个动作,而老虎也可以完成捕猎,在这个例子中,猫科动物就是父类,老虎是继承于猫科动物、从猫科动物这个类扩展出来的子类。
可以说:里氏代换原则是继承复用的一个基础。
依赖倒转原则(Dependency Inversion Principle,DIP)
若引用的对象有底层类型,那么就直接引用底层类型。高层模块不应该依赖于底层模块
换句话说,在程序里面调用的时候调用子类 ,子类依赖于父类,而父类不要依赖于子类。也就是说,细节依赖于抽象,可是抽象不应该依赖于细节。
依赖倒转原则要求程序设计时应该考虑如何针对抽象编程。
以计算机系统为例,依赖倒转原则要求要针对接口编程,而不是针对实现编程。无论键盘鼠标、CPU、内存等等这些硬件都是针对接口设计的,而如果要针对实现来设计,硬盘就要对应到某个特定(品牌/类型)的主板,那么换硬盘时就需要把主板也换掉。
接口隔离原则(Interface Segregation Principle,ISP)
每一个接口都是一个角色,客户端不应该依赖于它不需要的接口。
也就是:一个类对另一个类的依赖应该建立在最小的接口上。
意思是这样的:应该把每一个接口都细化,针对类去设计接口。如果一个接口里含有太多的方法,而对很多类来说里面的很多方法都是用不到的,那么另外的类在实现这个接口时就要实现很多对它来说没用的方法,浪费人力物力。对一个类来说,实现很多它都能用得上的专用接口总比让它实现一个臃肿而又有很多它用不上的方法要划得来。
采用接口隔离原则对接口进行约束时,要注意以下几点:
接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性是不挣的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。
为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。
运用接口隔离原则,一定要适度,接口设计的过大或过小都不好。
合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)
了解这个原则应首先了解一下组合和聚合。
组合(合成)和聚合都是对象关系的一种。聚合表示整体与部分的关系,表示“含有”,整体由部分组合而成,部分可以脱离整体作为一个独立的个体存在。组合(合成)则是一种更强的聚合,部分组成整体,而且不可分割,部分不能脱离整体而单独存在。在组合(合成)关系中,部分和整体的生命周期一样,组合的新的对象完全支配其组成部分,包括他们的创建和销毁。
复用原则的设计原则是:要尽量使用合成/聚合,尽量不要使用继承
最小知识原则(Principle of Least Knowledge,PLK,也叫迪米特法则)
一句话,一个对象应对其他对象有尽可能少的了解。
基本模式
创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)、访问者模式。
———————————————————
有不对的地方欢迎指出~~~
【本文由“大智慧聪明者”发布,2017年3月28日】