设计模式23模式介绍
一、什么是设计模式
设计模式(Design pattern) 是解决软件开发某些特定问题而提出的一些解决方案也可以理解成解决问题的一些思路。通过设计模式可以帮助我们增强代码的可重用性、可扩充性、 可维护性、灵活性好。我们使用设计模式最终的目的是实现代码的高内聚和低耦合。
二、设计模式的三大分类及关键点
1、创建型模式
对象实例化的模式,创建型模式用于解耦对象的实例化过程。
单例模式:某个类智能有一个实例,提供一个全局的访问点。
工厂模式:一个工厂类根据传入的参量决定创建出哪一种产品类的实例。
抽象工厂模式:创建相关或依赖对象的家族,而无需明确指定具体类。
建造者模式:封装一个复杂对象的创建过程,并可以按步骤构造。
原型模式:通过复制现有的实例来创建新的实例。
2、结构型模式
把类或对象结合在一起形成一个更大的结构。
装饰器模式:动态的给对象添加新的功能。
代理模式:为其它对象提供一个代理以便控制这个对象的访问。
桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。
适配器模式:将一个类的方法接口转换成客户希望的另一个接口。
组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构。
外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。
享元模式:通过共享技术来有效的支持大量细粒度的对象。
3、行为型模式
类和对象如何交互,及划分责任和算法。
策略模式:定义一系列算法,把他们封装起来,并且使它们可以相互替换。
模板模式:定义一个算法结构,而将一些步骤延迟到子类实现。
命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。
迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。
观察者模式:对象间的一对多的依赖关系。
仲裁者模式:用一个中介对象来封装一系列的对象交互。
备忘录模式:在不破坏封装的前提下,保持对象的内部状态。
解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。
状态模式:允许一个对象在其对象内部状态改变时改变它的行为。
责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。
访问者模式:不改变数据结构的前提下,增加作用于一组对象元素的新功能。
三、设计模式的几种原则
1、单一职责原则
对于一个类,只有一个引起该类变化的原因;该类的职责是唯一的,且这个职责是唯一引起其他类变化的原因。
2、接口隔离原则
客户端不应该依赖它不需要的接口,一个类对另一个类的依赖应该建立在最小的接口上。
3、依赖倒转原则
依赖倒转原则是程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。
4、里式代换原则
任何基类可以出现的地方,子类一定可以出现。里氏代换原则是继承复用的基石,只有当衍生类可以替换基类,软件单位的功能不受影响时,基类才能真正的被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
5、开闭原则
(1)对于扩展是开放的(Open for extension)。这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。也就是说,我们可以改变模块的功能。
(2)对于修改是关闭的(Closed for modification)。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。模块的二进制可执行版本,无论是可链接的库、DLL或者.EXE文件,都无需改动。
6、迪米特法则
迪米特法则又叫做最少知识原则,就是说一个对象应当对其它对象又尽可能少的了解,不和陌生人说话。
7、合成复用原则
合成复用原则要求在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。如果要使用继承关系,则必须严格遵循里氏替换原则。合成复用原则同里氏替换原则相辅相成的,两者都是开闭原则的具体实现规范。
四、设计模式关系
五、设计模式感想
一共有23种设计模式,可以说都是为了提高代码的可读性、可扩展性、可复用性、类的可替换性、组件化、可移植性等等特性。通过接口、抽象类、继承、实现、委托、抽象、面向接口编程、多态、重载、重写等方式使得代码的这些特性得以彰显,可以说只有深刻的理解了这些概念背后的哲学思想才能更好的理解设计模式。在设计模式中有很多思想,比如可以使用委托的不要使用继承、开闭原则,面向扩展开放,面向修改关闭,里式代换原则,父类一定能被子类代替并使用,反置则不然,面向接口编程,功能层次和实现层次分离(桥接模式)、高内聚低耦合等思想,这些思想都是宝贵的,正是因为这样的思想的存在才使得代码的更新换代的时候能够尽可能少的甚至不用修改之前的代码,直接加入新的内容。提高软件的开发周期,便于维护和升级,便于查找和纠错,易于扩展和使用。
同样的设计模式主要分为三大类,创建型、行为型、结构型。我们可以简单的这样分类,只不过这样的分类似乎并不准确,不能一语道出所有的本质,设计模式是相互关联的,有的设计模式内部其实是使用了别的设计模式作为支撑的,但是大体上这样的一种划分便于我们去记忆,仅此而已。
六、设计模式回顾
从迭代器开始,我们将类中数据结构的遍历和类的功能实现分离出来,本质上使用了工厂模式;
其次我们学习了适配器模式,它将不同的接口进行适配,从而便于版本的兼容性以及其他功能;
然后我们学习了模板方法,使用模板面向抽象编程,便于新的子类的实现和管理;
之后学习了工厂模式,其实借用了模板模式来创建产品,是一种非常重要用处很广的一种方法;
然后我们学习了单例模式,有懒汉式、饿汉式等,生成关于某个类全局唯一的对象,注意多线程的影响;
之后是原型模式,用来复制复杂的对象,使用了clone方法,然后是builder模式,用一个新的类对已有的抽象接口进行整合和编程,从而构建出我们想要的东西;
然后是抽象工厂模式,使用了工厂模式,组合模式等模式,面向抽象编程,将抽象零件组装成抽象产品,便于具体工厂的创建,提高了代码的组件化和复用性;
然后是桥接模式,将类的功能层次和实现层次分割开来,便于对应的扩展和使用;
然后是策略模式,可以整体的替换策略,使用也很广泛;然后是组合模式,保证了同根同源,通过委托添加自己构成递归,树形结构,将具有树形特点的对象组合起来;
然后是装饰器模式,和组合模式的结构类似,同样是递归结构,从而可以不断的装饰,增加新的功能,很好用;
接着是visitor访问者模式,通过在类外访问类中的数据结构从而得到想要的结果,便于程序的可扩展性和组件化;
接着是责任链模式,推卸责任,根据问题的大小来考虑自己释放处理,本质是链表,便于职责分明;
然后是外观模式,通过整合各个类之间的调用关系,组建成了统一的接口(API),便于外部类的调用;
接着是仲裁者模式,将很多类之间互相关联的关系交给仲裁者处理,省去了各个类之间的嵌套和调动,有利于高内聚和低耦合,思路清晰,便于扩展;
然后是观察者模式,通过互相委托从而能够在被观察的类发生改变的时候得到相应的改变的信息并且处理;
然后是备忘录模式,通过在某一时刻的状态保存下来,便于恢复,在游戏中使用的比较多;
然后是状态模式,将状态当做类,从而职责分明,解除了很多繁琐的if和else这些分支逻辑,便于扩展;
然后是享元模式,轻量级对象,通过共用不变对象来实现;
然后是代理模式,懒加载真正的服务器,加快访问速度,代理是帮助服务器代理的;
然后是命令模式,将命令当做类,通过保存一些列命令,从而能够随时执行这些命令,需要清除命令的本质就是一些操作和数据;
最后是解释器模式,利用编程原理的方法,来更高层次的封装代码,将自己开发的java代码当做编译系统,从而不用改变java代码只修改更高语言层次的代码就能实现不同的功能。
转 https://baijiahao.baidu.com/s?id=1761866681144060585&wfr=spider&for=pc
==========================================
责任链模式是一种将请求的处理者解耦的机制,使多个对象都有处理这个请求的机会。
备忘录模式是一种设计模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。
享元模式是一种结构型设计模式,它通过共享尽可能多的数据来最小化内存使用和计算开销。它适用于需要大量对象的情况,同时又要求对象能够轻量化。共享技术使得享元对象能够在不同环境中进行复用,而不会受到环境改变的限制。此外,享元模式还支持子系统通过共享外观模式来提供一致的界面,使得子系统更容易使用。
抽象工厂模式是一种创建型设计模式,它提供一个抽象的接口,用于创建相关或依赖对象的家族,而不需要指定具体类。通过抽象工厂模式,可以创建多个相关或相互依赖的对象,而不需要指定它们的具体类。这种模式可以简化代码的表达方式,提高代码的可维护性和可扩展性。
BRIDGE是一种结构型设计模式,它将一个大类或一系列紧密相关的类拆分为两个独立的层次结构。通过BRIDGE模式,可以将其抽象部分与它的实现部分分离,使它们可以独立地变化。这种模式可以有效地提高代码的可维护性和可扩展性。
类的适配器模式是一种设计模式,它通过创建一个新类的继承原有类的机制,实现不同类之间的互操作。这样可以避免由于兼容性问题而导致的错误和冲突,同时也可以使不同类的功能能够独立地发展和扩展。
观察者模式是一种设计模式,它允许对象之间的一对多依赖关系。这样,当一个对象改变状态时,其他依赖它的对象也会收到通知并自动更新。这种模式可以避免依赖关系的冲突,同时也可以提高系统的可扩展性。
访问者模式是一种设计模式,在不改变数据结构的前提下,增加作用于一组对象元素的新功能。它可以满足一些特殊需求,比如异步操作、动态绑定等。访问者模式通过封装一些操作来实现解耦,使得操作可以独立地进行,并且可以在不暴露数据结构的情况下进行修改。通过访问者模式,可以更好地利用系统中的数据结构,提高系统的灵活性和可维护性。
解释器模式是一种设计模式,它用来给定一个语言,定义它的文法,并建立一个解释器,这个解释器使用该表示来解释语言中的句子。通过定义不同的解释器,可以完成不同的功能,例如解释器模式可以用来处理多个对象的同一请求,也可以用来处理同一类型的特定问题。在解释器模式下,我们可以通过定义不同的语法来表示不同的句子,并且通过建立一个解释器来解释这些句子。这种设计模式可以帮助我们更好地理解和组织语言,提高代码的可读性和可维护性。
建造者模式是一种创建型设计模式,可以将复杂对象的构建过程和它的表示分离,使得同样的构建过程可以创建不同的表示。通过分离不同的表示,可以使得同一个设计在不同情况下具备不同的功能。
迭代器模式是一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。它通过迭代的方式,依次遍历每个元素,并将其作为下一个元素访问。这样可以避免暴露内部表示,保证程序的稳定性和一致性。迭代器模式在实现中可以使用不同的实现方式,但其基本原理和逻辑是一致的。
组合模式是一种结构型设计模式,它允许将对象组合成树形结构来表现整体-部分关系。组合模式使得客户端可以对单个对象和组合对象的使用具有一致性,同时也可以统一处理单个对象和组合对象的关系。
中介者模式是一种设计模式,它通过将多个对象组合成一个中介对象来封装对象的交互。中介者的作用是使各个对象不需要显式地相互作用,从而保持它们的耦合松散,并且可以独立地改变它们之间的交互。这种模式可以简化代码,提高代码的复用性和可维护性。
命令模式是将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。
单例模式是一种设计模式,它通过限制一个类只有一个实例,并提供对该实例的全局访问点,来确保类的安全性和唯一性。这样可以避免类的实例被多次创建,增加系统的并发性能,并且方便管理。例如,在创建一个类时,通过指定实例的静态属性来唯一标识该实例,避免了多个实例的冲突。此外,单例模式还提供了全局访问点,使得每个实例都可以被访问和操作。通过单例模式,可以保证系统的完整性和一致性。
外观模式是一种结构型设计模式,它为复杂的子系统提供简单的接口,使子系统更易于使用。外观模式为子系统提供了一个统一的界面,使得子系统更容易访问其他相关系统。通过外观模式,可以统一管理和操作子系统,提高系统的可维护性和可扩展性。
状态模式是一种允许对象在其内部状态发生改变时改变其行为的方式。通过这种方式,对象可以更好地理解和组织自己的行为。同时,状态模式也提供了一种机制,使得在发生改变时,不会自动重置对象的状态,而是根据条件自动调整。这种机制使得设计模式能够灵活应对不同情况下的变化,提高代码的可维护性和可扩展性。
策略模式是一种设计模式,它将算法封装起来,并允许不同算法之间互换。这样可以保证算法的独立性,避免出现其他问题的干扰。通过实现策略模式,开发人员可以灵活地选择不同的算法,并在不同的场景中选择合适的算法。策略模式的使用还可以提高代码的可读性和可维护性,减少错误的发生,提高系统的性能和可靠性。因此,策略模式是一种重要的设计模式,广泛应用于各个领域。
装饰器模式是一种动态地将责任附加到对象上的模式,它提供了灵活的替代继承方式。装饰器模式通过将子类的职责附加到父类的身上来实现,使得子类可以重写父类的代码,并在需要时进行扩展。这种模式下,子类的职责不会被父类明确地保留下来,而是被动态地分配给其他对象进行处理。装饰器模式在软件开发中非常有用,特别是在需要灵活处理继承关系的环境中。
代理模式是一种为其他对象提供代理以控制访问的机制。在代理模式下,代理对象可以在被代理对象执行操作前后进行一些预处理和后处理。通过代理模式,可以避免将敏感信息发送给攻击者,保护系统的安全。例如,在网络中,可以使用代理模式来处理来自其他站点的恶意攻击请求。此外,代理模式还可以提供一种机制,让攻击者无法直接访问被代理对象的资源。
==========================================