设计模式的 简述
前置了解
面向过程编程(Procedure Oriented Programming)
-
是一种
以过程为中心
的编程思想。 -
是以什么正在发生的过程为主要目标进行编程。
-
就是
分析出解决问题所需要的步骤
,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。 -
典型的语言:Pascal、C、PHP。
面向对象编程(Object Oriented Programming)
-
以对象为核心
,该方法认为程序由一系列对象组成。 -
类是对现实世界的抽象,包括表示静态属性的数据和对数据的操作,对象是类的实例化。
-
对象间通过消息传递相互通信,来模拟现实世界中不同实体间的联系。
-
在面向对象的程序设计中,对象是组成程序的基本模块。
-
就是
分析出解决问题所需要的对象
,然后用函数把这些对象及其方法一个一个实现,使用的时候一个一个依次调用类对象的方法即可。 -
典型的语言:C++、Java、PHP。
特点
-
封装性
-
隐藏对象内部的复杂性,只对外公开简单的接口
。 -
便于外界调用,从而提高系统的可扩展性、可维护性。
-
对内部数据提供了不同级别的保护,以防止程序中无关的部分意外地改变或错误的使用了对象的私有部分。
-
通俗地说,把该隐藏的隐藏起来,该公开的公开出来。
-
-
继承性
-
子类继承父类的所有方法和属性
。 -
子类不能调用父类的隐藏属性和方法,是受到封装性的影响,使得子类不能直接调用父类中的私有结构而已,还是继承到的。
-
子类继承父类以后,还可以声明自己特有的属性或方法,实现了功能的拓展。
-
-
多态性
-
一个类实例的相同方法在不同情形有不同表现形式
。 -
即:对于一个基类方法,不同的子类会有不同的实现。
-
但是,具有不同内部结构的子类对象可以共享相同的基类提供的外部接口。
-
面向接口编程(Interface Oriented Programming)
-
以接口为核心,将方法的声明和实现分开
,关注各个对象之间的协作关系。 -
将各个对象之间的协作关系做为系统设计的关键。
-
系统设计中
倾向于将所有的定义与实现分离
。
六大原则(合成复用原则 应该不是六大原则之一)
开闭原则(Open Close Principle)
-
对扩展开放,对修改关闭
。 -
在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。
-
就是要增加程序的扩展性,便于维护和升级方法。
-
我们需要使用
接口
来声明方法、使用抽象类
来声明类属性。然后子类去扩展类属性、去修改接口方法。 -
就是用抽象构建架构,用继承、实现来扩展功能。
优点:
-
代码的可复用性高。
-
代码的可维护性高。
-
代码的单元测试时,只需要添加新的方法测试,原有的测试方法不需要更改。
里氏代换原则(Liskov Substitution Principle)
-
里氏替换原则是
实现开闭原则的重要方式之一
。 -
子类可以扩展父类的功能,但不能改变原有父类的功能。(就是多态)
-
父类能够被子类无缝替代,就是子类对继承自父类的方法未作任何修改。
-
即:在子类中尽量不要重写父类的方法,而是使用重载的方式。
-
就是说明在编程中,如何正确地使用继承。
优点:
-
增强程序的健壮性
-
代码的可复用性高。
-
代码的可维护性高。
依赖倒转原则(Dependence Inversion Principle)
-
中心思想:面向接口编程。
-
上层模块不应该依赖下层模块,两者应依赖其抽象;
-
抽象不应该依赖细节,细节应该依赖抽象。
优点:
-
通过基类来制定统一的规范,具体地实现就交给其实现类来完成。
-
抽象稳定。
接口隔离原则(Interface Segregation Principle)
-
要
为各个类建立他们需要的专用接口
,而不要试图去建立一个很庞大地接口供所有依赖它的类去调用。 -
将复杂的接口,根据业务拆分成多个简单接口。
优点:
-
将臃肿庞大的接口分解为多个粒度小的接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性。
-
接口隔离提高了系统的内聚性,减少了对外交互,降低了系统的耦合性。
-
使用多个专门的接口还能够体现对象的层次,因为可以通过接口的继承,实现对总接口的定义。
-
能减少项目中的代码冗余。
迪米特法则、最少知道原则(Demeter Principle)
-
最少知道原则,尽量降低类与类之间的耦合
,提高模块的相对独立性。 -
一个对象应该对其他对象保持最少地了解。
-
对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的 public 方法,不对外泄露任何信息。
-
即:只与直接的朋友通信。(我们称出现在成员变量,方法参数,方法返回值中的类为直接的朋友,而出现在局部变量中的类不是直接的朋友。)
优点:
-
降低了类与类之间的耦合,提高了模块的相对独立性。
-
提高了类的可复用率和系统的扩展性。
单一原则(Single Responsibility Principle)
-
单一职责原则规定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分。
-
一个类或者一个方法应只负责一项职责
。
优点:
-
类的复杂度低。
-
类的可读性高。
-
系统的可维护性高。
-
系统变更引起的风险低。
合成复用原则(Composite Reuse Principle)
-
尽量在编写类的时候
使用合成、聚合的方式
,而不是使用继承的方式。 -
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
-
是针对接口编程,而不是针对实现编程。
优点:
-
类与类之间的耦合度低。
-
类的可重用率高。
23 种设计模式
只是23种比较常见的设计模式
,还有很多其他的设计模式。
创建型模式
-
这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。
-
这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。
工厂模式(Factory Pattern)
-
是用工厂方法代替 new 操作的一种模式。
-
又叫做静态工厂方法,定义一个用于创建对象的接口,让子类决定实例化哪一个类。
-
工厂模式使得一个类的实例化延迟到子类。
-
就是,将一个类对象的创建方法隐藏起来,再使用工厂方法来获取该类的实例。
抽象工厂模式(Abstract Factory Pattern)
-
提供一个创建系列相关或相互依赖对象的接口,而无需指定他们具体的类。
-
是工厂模式的升级版。
原型模式(Prototype Pattern)
-
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
-
通过复制现有实例来创建新的实例,无需知道相应类的信息。
-
需要创建一个指定的对象时,刚好有一个这样的对象,但是又不能直接使用,就会深拷贝一个一样的新对象来使用。
浅复制:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。
深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建一份。
单例模式(Singleton Pattern)
-
保证一个类只有一个实例,并提供一个访问它的全局访问点。
-
懒加载
:用到该单例对象的时候再创建。 -
预加载
:在程序开始运行时,就将该单例对象加载到内存了。
建造者模式(Builder Pattern)
-
将一个复杂对象的构建与他的表示分离,使得同样的过程可以创建不同的表示。
-
封装一个复杂对象构造过程,并允许按步骤构造。
结构型模式
-
这些设计模式关注类和对象的组合。
-
继承的概念被用来组合接口和定义组合对象获得新功能的方式。
适配器模式(Adapter Pattern)
-
将一个类的接口转换成客户希望的另外一个接口。
-
该模式使得原本接口不兼容而不能一起工作的类可以一起工作。
-
主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。
桥接模式(Bridge Pattern)
- 将抽象部分与他的实现分离,使得他们都可以独立的变化。
组合模式(Composite Pattern)
-
将对象组合成树形结构以表示“整体-部分”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
-
是一种将对象组合成树状的层次结构的模式。
装饰器模式(Decorator Pattern)
-
动态的给一个对象添加一些额外的职责。
-
即:动态的将新功能附加到对象上。
外观模式(Facade Pattern)
-
为子系统种的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得子系统更加容易使用。
-
隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口,具体要调用系统的那个方法不需要客户关心。
享元模式(Flyweight Pattern)
-
运用共享技术有效地支持大量细粒度的对象。
-
即:通过共享的方式高效的支持大量细粒度的对象。
代理模式(Proxy Pattern)
- 给某些对象提供一个代理对象,并由代理对象控制对原有的对象的引用。
行为型模式
- 这些设计模式特别关注对象之间的通信。
职责链模式(Chain of Responsibility Pattern)
-
使多个对象都有机会处理请求,从而避免请求的发送者与接受者之间的耦合关系。
-
将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
命令模式(Command Pattern)
-
将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通。
-
从而可以使你可用不同的请求对客户进行参数化;可以对请求排队或记录请求日志,以及支持可撤销的操作。
解释器模式(Interpreter Pattern)
- 给定一个语言,定义他的文法的一种表示,并定义个解释器,这个解释器使用该表示来解释语句种的句子。
迭代器模式(Iterator Pattern)
- 提供一种方法顺序访问一个聚合对象种的各个元素,而又不许暴露该对象的内部表示。
中介者模式(Mediator Pattern)
-
中介者使得各对象不需要显示得相互交互,从而使其耦合松散,而且可以独立的改变他们之间的交互。
-
定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。
-
中介者模式又叫调停模式,它是迪米特法则的典型应用。
备忘录模式(Memento Pattern)
-
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象外保存这个状态。
-
这样以后就可以将该对象恢复到原先保存的状态。
观察者模式(Observer Pattern)
- 定义对象间一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并被自动更新。
状态模式(State Pattern)
-
创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。
-
允许一个对象在其内部状态改变时改变它的行为,让对象看起来似乎修改了它的类。
-
一个拥有状态的 context 对象,在不同的状态下,其行为会发生改变。
策略模式(Strategy Pattern)
-
定义一系列算法,把他们一个个封装起来,并且使他们可以相互替换。
-
本模式使得算法可以独立于使用它的客户而变化。
模板方法模式(Template method Pattern)
- 定义一个操作算法骨架,而将一些步骤延迟到子类种,模板方法使得子类可以不改变一个子算法的结构,而重定义该算法的某些特定步骤。
访问者模式(Visitor Pattern)
-
表示一个作用于某对象结构种的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
-
将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,
为数据结构中的每个元素提供多种访问方式。 -
它将对数据的操作与数据结构进行分离。
JavaEE 的设计模式
MVC 模式(Model View Controller Pattern)
-
把软件系统分为三个基本部分:模型(Model)、视图(View)、控制器(Controller)。
-
Model:主要表示一个存取数据的对象或 Java POJO,用于存储数据以及对数据的访问和修改。
-
View:用于数据展示,与用户进行交互,表示数据的可视化界面。
-
Controller:主要用于控制程序的流程,对请求做出响应,
使视图与模型分离开,控制数据流向模型对象,并在数据变化时更新视图。
业务代表模式(Business Delegate Pattern)
-
表示将表示层和业务层解耦。
-
是用来减少通信或对表示层代码中的业务层代码的远程查询功能。
组合实体模式(Composite Entity Pattern)
-
用在 EJB(企业 Java Beans) 持久化机制中。
-
一个组合实体是一个 EJB 实体 bean,代表了对象的图解。
-
当更新一个组合实体时,内部依赖对象 beans 会自动更新,因为它们是由 EJB 实体 bean 管理的。
数据访问对象模式(Data Access Object Pattern)
-
用来抽象和封装一个对象来对数据源进行访问、存储和更改。
-
这样可以方便对数据的管理,以及避免数据间的重复、覆盖等问题出现。
前端控制器模式(Front Controller Pattern)
-
提供一个集中的请求处理机制,所有的请求都将由一个统一的处理程序处理。
-
该处理程序可以做认证、授权、记录日志、或者跟踪请求 等功能,然后把对应请求传给相应的处理程序即可。
拦截过滤器模式(Intercepting Filter Pattern)
-
用于对应用程序的请求、或响应做一些预处理、或后处理。
-
定义过滤器,并在把请求传给实际目标应用程序之前应用在请求上。
-
过滤器可以做认证、授权、记录日志、或者跟踪请求 等功能,然后把请求传给相应的处理程序。
服务定位器模式(Service Locator Pattern)
-
为某服务提供一个全局访问入口来避免使用者与该服务具体实现类之间产生耦合。
-
缓存该服务对象,当再次请求相同的服务时,服务定位器会在它的缓存中查找。
传输对象模式(Transfer Object Pattern)
- 从客户端向服务器一次性传递带有多个属性的数据。
Spring 使用到的设计模式
简单工厂模式
- 定义了一个创建对象的类,由这个类来封装实例化对象的行为。