设计模式详解

  设计模式(Design pattern)是一套被反复使用、经过分类编目的、代码设计经验的总结。使用设计模式使得代码具有更好的代码重用性、可读性、可扩展性、可靠性,使得程序呈现高内聚-低耦合的特性。
  设计模式在软件中哪里?面向对象(oo)=>功能模块[设计模式+算法(数据结构)]=>框架[使用到多种设计模式]=>架构 [服务器集群]

六大设计原则

单一职责原则:类的设计尽量做到只有一个原因可以引起它的改变
里氏替换原则:只要父类出现的地方子类就可以出现,且替换成子类也不会出现任何错误或者异常
依赖倒置原则:包含三层含义:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。面向接口编程,而不是面向实现编程。在Java语言中,抽象就是指接口或抽象类,两者都是不能直接被实例化的;细节就是实现类,实现接口或继承抽象类而产生的类就是细节,其特点就是可以直接被实例化,也就是可以加上一个关键字new产生一个对象。依赖倒置原则在Java语言中的表现就是:

  • 模块间的依赖是通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的
  • 接口或抽象类不依赖于实现类
  • 实现类依赖接口或抽象类。

面向接口编程,而不是面向过程编程。
接口隔离原则:不要建立臃肿庞大的接口。即接口尽量细化,同时接口中的方法尽量少
迪米特法则: 一个对象应该对其他对象有最少的了解,也就是说一个类要对自己需要耦合或者调用的类知道的最少
开闭原则ocp: 一个软件实体,比如类,模块,函数应该对扩展开放,对修改关闭
合成复用原则:尽量使用合成/聚合的方式,而不是使用继承
在这里插入图片描述
依赖:继承、实现、关联(聚合、组合)

各分类中模式的关键点

【1】单例模式
  单例模式就是确保某一个类只有一个实例,并且提供一个全局访问点。单例模式具备典型的3个特点:1、只有一个实例;2、自我实例化;3、提供全局访问点。
  单例模式的主要优点就是节约系统资源、提高了系统效率,同时也能够严格控制客户对它的访问。也许就是因为系统中只有一个实例,这样就导致了单例类的职责过重,违背了“单一职责原则”,同时也没有抽象类,所以扩展起来有一定的困难。

【2】简单工厂模式
  定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)。

【3】工厂方法模式
  定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。
  工厂方法模式非常符合“开闭原则”,当需要增加一个新的产品时,只需要增加一个具体的产品类和与之对应的具体工厂即可,无须修改原有系统。同时在工厂方法模式中用户只需要知道生产产品的具体工厂即可,无须关系产品的创建过程,甚至连具体的产品类名称都不需要知道。

【4】抽象工厂模式
  定义了一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类。抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。
  从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。将工厂抽象成两层, AbsFactory(抽象工厂) 和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。 这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。

【5】原型模式
  原型模式就是用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。它主要应用与那些创建新对象的成本过大时。它的主要优点就是简化了新对象的创建过程,提高了效率,同时原型模式提供了简化的创建结构,即:对象.clone()。
  浅拷贝 VS 浅拷贝

【6】建造者模式
  建造者模式主要是将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。建造者模式将复杂产品的构建过程封装分解在不同的方法中,使得创建过程非常清晰,同时它隔离了复杂产品对象的创建和使用,使得相同的创建过程能够创建不同的产品。

【7】适配器模式
  适配器模式将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)。主要分为三类:类适配器模式、对象适配器模式、接口适配器模式。

【8】桥接模式
  桥接模式(Bridge模式)是指:将实现与抽象放在两个不同的类层次中,使两个层次可以独立改变。基于类的最小设计原则,通过使用封装、聚合及继承等行为让不同的类承担不同的职责。它的主要特点是把抽象(Abstraction)与行为实现(Implementation)分离开来,从而可以保持各部分的独立性以及应对他们的功能扩展。

【9】装饰模式
  装饰者模式,动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更加有弹性的替代方案。

【10】组合模式
  组合模式,它创建了对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的层次关系。组合模式使得用户对单个对象和组合对象的访问具有一致性, 即:组合能让客户以一致的方式处理个别对象以及组合对象。

【11】外观模式
  外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关心这个子系统的内部细节。

【12】亨元模式
  享元模式运用共享技术有效地支持大量细粒度的对象。常用于系统底层开发,解决系统的性能问题。像数据库连接池,里面都是创建好的连接对象,在这些连接对象中有我们需要的则直接拿来用,避免重新创建, 如果没有我们需要的,则创建一个。
  享元模式能够解决重复对象的内存浪费的问题,当系统中有大量相似对象,需要缓冲池时。 不需总是创建新对象,可以从缓冲池里拿。这样可以降低系统内存,同时提高效率。
  享元模式经典的应用场景就是池技术了, String常量池、数据库连接池、缓冲池等等都是享元模式的应用,享元模式是池技术的重要实现方式。

【13】代理模式   为一个对象提供一个替身,以控制对这个对象的访问。 即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。被代理的对象可以是远程对象、 创建开销大的对象或需要安全控制的对象代理模式有不同的形式, 主要有三种 静态代理动态代理 (JDK代理、接口代理)Cglib代理 (可以在内存动态的创建对象,而不需要实现接口, 他是属于动态代理的范畴)
  静态代理在使用时,需要定义接口或者父类,被代理对象(即目标对象)与代理对象一起实现相同的接口或者是继承相同父类。优点:在不修改目标对象的功能前提下, 能通过代理对象对目标功能扩展。缺点:因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类一旦接口增加方法,目标对象与代理对象都要维护。
  动态代理,代理对象不需要实现接口, 但是目标对象要实现接口, 否则不能用动态代理。代理对象的生成, 是利用JDK的API,动态的在内存中构建代理对象。动态代理也叫做: JDK代理、 接口代理。JDK中生成代理对象的API:代理类所在包:java.lang.reflect.Proxy;JDK实现代理只需要使用newProxyInstance方法,但是该方法需要接收三个参数:static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )。
  静态代理和JDK代理模式都要求目标对象是实现一个接口,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候可使用Cglib代理,它是在内存中构建一个子类对象从而实现对目标对象功能扩展, 有些书也将Cglib代理归属到动态代理。Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口。它广泛的被许多AOP的框架使用,例如Spring AOP, 实现方法拦截。Cglib包的底层是通过使用字节码处理框架ASM来转换字节码并生成新的类。在AOP编程中如何选择代理模式:

  1. 目标对象需要实现接口, 用JDK代理
  2. 目标对象不需要实现接口, 用Cglib代理

【14】模板模式
  在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。模板方法模式 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤。

【15】命令模式
  命令模式将请求封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。同时命令模式支持可撤销的操作。命令模式可以将请求的发送者和接收者之间实现完全的解耦,发送者和接收者之间没有直接的联系,发送者只需要知道如何发送请求命令即可,其余的可以一概不管,甚至命令是否成功都无需关心。

【16】访问者模式
  封装一些作用于某种数据结构的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。主要将数据结构与数据操作分离,解决数据结构和操作耦合性问题访问者模式的基本工作原理是: 在被访问的类里面加一个对外提供接待访问者的接口。访问者模式主要应用场景是: 需要对一个对象结构中的对象进行很多不同操作(这些操作彼此没有关联),同时需要避免让这些操作"污染"这些对象的类,可以选用访问者模式解决。

【17】迭代器模式
  如果我们的集合元素是用不同的方式实现的, 有数组,还有java的集合类或者还有其他方式,当客户端要遍历这些集合元素的时候就要使用多种遍历方式,而且还会暴露元素的内部结构,可以考虑使用迭代器模式解决。迭代器模式提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示,即: 不暴露其内部的结构。

【18】观察者模式
  对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer, Subject通知Observer变化。

【19】中介者模式
  用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

【20】备忘录模式
  备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。备忘录模式有着相同的含义,备忘录对象主要用来记录一个对象的某种状态,或者某些数据,当要做回退时,可以从备忘录对象里获取原来的数据进行恢复操作。

【21】解释器模式
  解释器模式是指给定一个语言(表达式), 定义它的文法的一种表示,并定义一个解释器, 使用该解释器来解释语言中的句子(表达式)。

【22】状态模式
  状态模式主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题。状态和行为是一一对应的,状态之间可以相互转换。当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了
其类。

【23】策略模式
  策略模式就是定义了算法族,分别封装起来,让它们可以互相转换,此模式然该算法的变化独立于使用算法的客户。策略模式也非常完美的符合了“开闭原则”,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。

【24】责任链模式
  为请求创建了一个接收者对象的链。 这种模式对请求的发送者和接收者进行解耦。职责链模式通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
  职责链模式使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值