设计模式是众多软件开发人员经过相当长的一段时间的试验和错误的总结
目的是使程序 可维护, 可扩展, 可复用, 灵活性好
六大原则
开闭原则(Open Close Principle)
对扩展开放,对修改关闭。
在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。
简言之,是为了使程序的扩展性好,易于维护和升级。使用接口和抽象类
里式替换原则(Liskov Substitution Principle)
任何基类可以出现的地方,子类一定可以出现。
LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。
里氏代换原则是对开闭原则的补充。
实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范
依赖倒置原则(Dependence Inversion Principle)
这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。
接口隔离原则(Interface Segregation Principle)
使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度
迪特米法则(Demeter Principle)
一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立
合成复用原则(Composite Reuse Principle)
尽量使用合成/聚合的方式,而不是使用继承
常用23种设计模式
创建型
用于创建对象
工厂模式(Factory Pattern)
工厂方法适用于创建单个产品
工厂负责创建接口使用者需要的对象,但是接口使用者不需要关心具体的对象类型,只需要关心已知的返回对象类型和接口即可
定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行
允许我们在不改变现有代码基础上添加新的产品类型,并且可以将具体产品的实现与调用方分离开来
优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。
2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖
简单工厂模式和普通工厂模式的差别比较小,可以合在一起讲,它们的区别是简单工厂模式里,工厂直接负责产品的生产,而到普通工厂模式里,工厂是个抽象类,具体的生产行为交给了具体的工厂。到了抽象工厂模式里,工厂生产的对象不止一个,而是多个
抽象工厂模式(Abstract Factory Pattern)
抽象工厂适用于创建多个产品
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
抽象工厂可以理解为是一系列工厂方法的集合。抽象工厂的子类,实现每一个工厂方法
使用工厂方法模式时,往往仅需选用所需的工厂方法即可,而使用抽象工厂模式时,则需要创建所有抽象产品对象
单例模式(Singleton Pattern)
确保一个类只有一个实例,并提供了一个全局访问点来访问该实例
建造者模式(Builder Pattern)
组合的变化由不同基础部件组合导致
使用多个简单的对象一步一步构建成一个复杂的对象
将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示
建造者模式更加关注与零件装配的顺序
原型模式(Prototype Pattern)
用于创建重复的对象,同时又能保证性能
实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式
注意深拷贝和浅拷贝
结构性
适配器模式(Adapter Pattern)
使原有接口适配新接口
将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
适配器继承或依赖已有的对象,实现想要的目标接口
适配器模式:客户需要使用现有的类,而此类的接口不符合客户的需要;想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类;通过接口转换,将一个类插入另一个类系中
桥接模式(Bridge Pattern)
将抽象与实现分离,使它们可以独立地变化,该模式通过将一个对象的抽象部分与它的实现部分分离,使它们可以独立地改变。它通过组合的方式,而不是继承的方式,将抽象和实现的部分连接起来
适用于一个类存在两个独立变化的维度,且这两个维度都需要进行扩展
个人理解: 一个抽象类中调用另一个抽象类, 实现解耦
过滤器模式(Filter、Criteria Pattern)
组合模式(Composite Pattern)
用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次
将对象组合成树形结构以表示”部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性
树枝和叶子实现统一接口,树枝内部组合该接口
树枝内部组合该接口,并且含有内部属性 List,里面放 Component
装饰器模式(Decorator Pattern)
允许向一个现有的对象添加新的功能,同时又不改变其结构
在保持类方法签名完整性的前提下,提供了额外的功能
外观模式(Facade Pattern)
隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口
降低访问复杂系统的内部子系统时的复杂度,简化客户端之间的接口
创建一个新类, 为客户端提供具体的部件组合后的接口
两个类的关系是单项的, 一方通过外观与另一方发生关系, 而另一方则不能
享元模式(Flyweight Pattern)
已创建的对象直接返回
用于减少创建对象的数量,以减少内存占用和提高性能
在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建
用 HashMap(Hashtable) 存储这些对象
代理模式(Proxy Pattern)
一个类代表另一个类的功能, 为其他对象提供一种代理以控制对这个对象的访问, 继承同一接口, 对客户端来说并无区别
代理模式:当无法或不想直接访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口
1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。
行为型
责任链模式(Chain of Responsibility Pattern)
为请求创建了一个接收者对象的链
通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推
避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止
职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了
命令模式(Command Pattern)
请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令
解开了请求调用者和请求接收者之间的耦合关系
将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化
比如需要对行为进行记录、撤销或重做、事务等处理时使用
当需要先将一个函数登记上,然后再以后调用此函数时,就需要使用命令模式,其实这就是回调函数