1、为什么使用?设计模式,可以使代码更简洁、更优美、更效率、扩展性型更强。
2、设计模式的原则:开闭原则(对拓展开放,对修改关闭)(抽象化是关键)
--单一职责原则:类的职责应该单一(不存在多种原因导致类的变更),否则类应该被拆分。
--里氏替换原则:任何基类可以出现的地方,子类一定可以出现。(LSP)(该规范中子类尽可能不要重写或重载基类的方法)(面向对象设计的基本原则之一)(开闭原则的补充)(抽象化的具体实现)
--依赖反转原则:依赖于抽象,不依赖于具体。(编程是需要依赖具体的类时,不与该类交互,而转向与该类的上层接口交互)(面向接口)(开闭原则的基础)
--接口隔离原则:每个接口,对于实现该接口的类,不存在冗余的方法,否则需拆分接口。(使用多个隔离接口,要优于一个集合接口)
--最少知道原则:类对于自己依赖的类知道的越少越好。(迪米特法则)(无论依赖的类的逻辑多么复杂,子类只需要通过逻辑被封装的暴露的方法去使用即可)(该原则保证依赖的类改变是,对继承他的类影响最小)(只与直接朋友通信)(朋友关系:类之间存在耦合[依赖,关联,聚合,组合])(直接朋友:作为成员变量,方法参数,方法返回值的类)(陌生类不要出现在局部变量中)
--合成复用原则:合成/聚合优于继承。
3、模式应用场景
----结构模式
--适配器模式(Adapter):已有接口和定义接口不匹配。(类的适配器模式和对象的适配器模式)
实现描述:
类适配(原始类A有一方法funcA,接口faceA需要实现funcA、funcB,实现一个适配类B继承与A实现接口faceA)(解决接口内方法个数和原始类方法不匹配)
对象适配(将类适配中A和B的关系从继承,改变为B持有A的实例对象)(解决原始类方法和已有接口方法的命名不匹配和个数不匹配)
接口适配(桩问题)
对于接口,引申出两个概念:标识接口(没有声明任何方法的接口)和桩(实现了接口,但是实现方法体为空的类)。
标识接口:用来标识某个类符合一定的规范。(对于有人制定规则的前提下,这种标识非常有用,如何不遵守这种规范,任意去实现自己的代码,将会给程序带来致命的错误)
桩:在一个接口里声明的一组方法,有的时候某些方法可能被忽略执行,或者返回值没有任何意义,可以定义一个桩,让具体的实现延迟到具体的子类。(没理解透)
--装饰模式(Decorator):扩展一个类功能。(动态的添加功能)
实现描述:原始类A定义有方法funcA,定义接口faceA有方法funcA,定义装饰类B持有A的实例对象、实现接口faceA。(旨在对原始类的扩展)
--代理模式(Proxy):代替原对象进行一系列操作。(对象的访问控制)(隐藏一个对象的具体信息)
实现描述:原始类A定义有方法funcA,定义接口faceA有方法funcA,定义装饰类B持有A的实例对象、实现接口faceA,客户程序通过接口faceA去调用A的funcA。(旨在封装原始类的复杂接口)
--外观模式(Facade):各组件类解耦,形成一个外观提供服务。(计算机类和各个组件类,为了防止各个组件之间的耦合,用计算机类持有各个组件的实例,避免了组件之间的关联)
实现描述:原始类A、B、C,定义外观类D持有A、B、C的实例对象。(旨在对A、B、C关系的解耦)
--桥接模式(Bridge):抽象化和实例化的解耦。
实现描述:定义接口faceA含funcA,定义桥接类A持有接口faceA的一个对象并实现funcA,funcA会根据一定的逻辑调用faceA的funcA,使实现接口faceA的各个类具体的逻辑实现和 接口的调用逻辑分离,客户程序调用A的方法funcA就可以调用相应的处理逻辑。
--组合模式(Composite):客户程序和复杂元素的内部结构解耦。(树节点和树)(部分整体模式)(像操作简单元素一样操作复杂元素)
实现描述:将复杂的组织结构以树的形式实现,简化对复杂数据结构的操作(汗)(没理解透)
--享元模式(Flyweight):已存在对象的共享。(共享池)(连接池)(没理解透)
实现描述:管理类持有实例对象的列表并管理这个列表,对外以工厂的模式提供对象。
-------简单工厂模式(扩)
--简单创建:一个工厂类负责对实现的同一接口的一些类进行实例的创建。(传递相关类型名字符串来区分创建的类)
--个性化创建:在简单的基础上,工厂类对每个类实现一个创建方法。(个性化)(多个方法)
--静态个性化创建:在个性化创建的基础上,工厂类的方法设置为类的静态方法(static)。(多个静态方法)
----创建模式
--工厂方法模式(Factory Method):解决简单工厂模式在扩展的时候必须修改工厂类、违背开闭原则。(简单工厂模式类的创建依赖于工厂类)(扩展性好)(支持新增产品)
实现描述:定义一个工厂类接口,对每一个产品类创建一个工厂类。
--抽象工厂模式(Abstract Factory):对产品簇的扩展支持(不支持新增产品,可新增产品簇)
实现模式:定义一个工厂类接口,多个产品抽象接口。(产品簇)
--单例模式(Singleton):提供唯一对象(创建对象过多时)(减压)(对象只能唯一)
实现模式:内部类生成private static 对象,通过public static方法对外提供(内部类实现)
--建造者模式(Builder):创建一个复杂对象,使创建流程和发杂对象各部分的具体创建过程分离。
实现模式:定义一个建造者接口Builder,一个导演类Director持有建造者Builder接口,通过该接口调用具体建造者ConcreteBuilder类中的方法,从而构造出复杂的Product对象。
--原型模式(Prototype):对象的克隆。(本地方法,比new更效率)(简化对象的创建)(浅拷贝:数组、引用对象)(深拷贝:原始类型和包装类型、String)(越过类的构造函数权限进行克隆)(与单例模式冲突)
实现模式:重写Object类的clone方法。(Cloneable接口,数组、引用对象需要单独实现克隆)
----关系模式
-父类与子类
--策略模式(Strategy):让可互换算法的具体变化不影响到调用的客户端程序。(决定权在客户端程序)(由客户决定具体调用的算法)(客户程序不需要知道算法的具体变化和所需要的数据)
实现模式:一个抽象的算法接口,一个可有可无的提供辅助函数的抽象类,一群实现接口、继承抽象类的算法类,一个需要相关算法的客户端程序。
--模板方法模式(Template Method):算法公用部分放到父类,不同部分延迟到子类实现。(父类引用调子类方法)(没理解透)
实现模式:一个提供主方法的抽象类,一群继承抽象类的算法类,一个需要通过抽象类的引用调用具体方法的客户端程序。
-类之间
--观察者模式(Observer):两类接口存在依赖。(一方影响另一方)(一方监控另一方)
实现模式:一接口A依赖于另一个接口B,接口A的实现的变化影响B的实现(一个抽象类和他的子类),接口B的实现需要去监控A的动态并做出反应。
--迭代器模式(Iterator):聚合的遍历。
实现模式:聚合接口和迭代器接口,迭代器接口的实现持有聚合接口的引用,从而操作集体的聚合类型。
--责任链模式(Chain Of Responsibility):多个对象互相引用。(对用户程序隐藏具体调用的对象)
实现模式:一个类B继承于抽象类A、实现了接口funA,A持有funA的引用、可以去引用B的实例对象,客户程序通过B的实例对象调用相应操作。
--命令模式(Command):命令者和受令者的解耦。
实现模式:命令接口F,实现接口的命令类C,C持有最终完成命令的类R的引用,调用类I持有命令接口的引用。
-类的状态
--备忘录模式(Memento):备份对象状态,以便恢复。
实现模式:一个原始类A可以创建备忘录类B,存储类C持有B的实例用来存储备忘录。
--状态模式(State):状态不同,行为不同。
实现模式:原始类A持有状态类B的实例,A根据B的属性值去调用B的相应的具体方法。
-BY中间类
--访问者模式(Visitor):解决和元素类关系不大且频繁变动的操作的改变问题(来访问我吧)(扩展性:接收不同的访问者,操作的扩展)(符合单一职责)(外界调用元素接口引用)
实现模式:一个元素接口,一个访问者接口,元素接口接收访问者接口从而让其进行一些相关操作。
--中介者模式(Mediator):工作有关的工作者类之间的解耦。
实现模式:一个中介者接口,实现接口的中介者类,该类持有N个工作者类对象,并协调他们进行工作,抽象工作者类持有与之对应的中介者接口引用。(外界调用中介者接口引用)
--解释器模式(Interpreter):解释相关表达式。(扩展性好)(影响效率、性能,维护性复杂)(不建议轻易使用)(单一问题频度很大,可以考虑)
实现模式:表达式接口(非终结符表达式类和终结符表达式类),一个上下文环境Context类。(没理解透)