设计模式遵循的原则
- 单一职责原则
不要存在多于一个职责导致类变更,也就是说一个类只负责一项职责。
- 依赖倒置原则
多使用抽象的接口来描述相同的动作,降低实现这个动作的人和物的耦合度
- 接口隔离原则
一个类对于另一个类的依赖应该建立在最小的接口上。举例不要把多个类的方法都抽象在一个接口中。
- 里氏替换原则
- 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
- 子类可以增加自己独特的方法。
- 重载的方法,参数列表要比被重载的方法更多。
- 重写的方法,方法的返回值要比父类更。int-long、float-double
- 迪米特法则
对于被依赖的类来说。无论逻辑多么复杂,都尽量地将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息
- 开闭原则
尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有代码。
GOF 23种设计模式简介
设计模式其实一门艺术。设计模式来源于生活,不要为了套用设计模式而去使用设计模 式。设计模式是在我们迷茫时提供的一种解决问题的方案,或者说用好设计模式可以防范于未然。 设计模式总结的是经验之谈,总结的是前人的经验,提供给后人去借鉴使用,前人栽树, 后人乘凉。设计模式可以帮助我们提升代码的可读性、可扩展性;降低维护成本;解决复杂的业务问题,
- 但是,千万千万不要死记硬背,生搬硬套。
- 只有先理解才能更好的运用于业务场景中,学习设计模式的方法我建议 穷举法 + 类比法
- 对于每种设计模式的优点和缺点,当你理解了思想,自然而然就能总结出来。
- 本篇文章主要就是介绍思想,至于优点和缺点留给你们自己总结。
下面我们还是先来总体预览一下GOF 23种设计模式的归纳和总结
- 23种设计模式的总体关系,看看即可!
工厂模式
工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。
比如说手机工厂,我们为什么需要工厂?当你把原材料交给他后,他就能经过一系列的步骤把手机交给你,如果你需要对该手机的某个步骤修改,你就可以很轻松的对工厂中的某个环节进行修改。
单例模式
通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例)
比如说我们使用手机不可能每次想用的时候都去买一个新的,也就是说你只会有一个手机,不管是打电话还是玩游戏都会使用同一个手机来完成。
建造者模式
建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
比如说我们想买一个汉堡,此时的汉堡仅仅只是两片面包(相当于new出来了对象),我们此时不能够直接把该汉堡给客户,还需要对这个汉堡进行添加菜叶、奶酪、火腿等等(相当于给对象的属性赋值),我们把这些加工操作做完后才可以把该汉堡给用户。(相当于new对象和给对象中的属性赋值分离)
原型模式
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
Java中通过实现Cloneable接口,调用clone()方法来完成拷贝
比如说我们写了一篇文章要传给1000个人,不会有人手动写1000篇文章,都是直接复制粘贴。
组合模式
组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构。
比如说我们定义一个书架实体类用来存放书实体类,我们不可能把每个书都以属性的形式存放在书架实体类中,我们通常的做法是创建一个书的List集合,然后向外暴露一个方法用来放书,这种形式就是最简单的组合模式
代理模式
其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
生活中的中介、黄牛、代理商都属于代理模式
适配器模式
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
最典型的就是插排
装饰器模式
装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
比如说我们准备送女朋友10个礼物用了10个盒子嵌套的把所有礼物放到一个盒子中,然后盒子放到下一个盒子,这样的话每打开一个盒子都会给女朋友一个惊喜。
门面模式
门面模式,是指提供一个统一的接口去访问多个子系统的多个不同的接口,它为子系统中的一组接口提供一个统一的高层接口。使得子系统更容易使用。
就比如说我们想要启动电脑,只要按下开机键就行了,我们不知道电脑内部做了什么,其实电脑内部实际上也启动了多个模块,如cpu、硬盘、内存等等。
桥接模式
桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interfce)模式。
享元模式
享元模式(英语:Flyweight Pattern)是一种软件设计模式。它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。
最典型的例子就是线程池
模板模式
模板方法模式定义了一个算法的步骤,并允许子类别为一个或多个步骤提供其实践方式。让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤。
生活中处处可见
责任链模式
责任链模式是一种设计模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
观察者模式
观察者模式(有时又被称为模型(Model)-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
策略模式
策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。
比如说淘宝你买完东西付钱后,可以选择用微信、支付宝、银行卡、余额付款,程序就会根据你的支付方式选择对应的策略完成付款。
解释器模式
一种设计模式。定义了一个解释器,来解释给定语言和文法的句子。其实质是把语言中的每个符号定义成一个(对象)类,从而把每个程序转换成一个具体的对象树。
最典型的例子就是JVM虚拟机,它可以解释各种语言,比如说java、C、C++、GO语言
命令模式
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志。以及支持可撤销的操作。
最典型的例子就是遥控器,通过遥控命令来指定物体进行操作
迭代器模式
迭代器模式提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。
Java中的循环经常用到
调节者模式
定义一个对象将一系列对象如何相互作用的操作进行封装。调解者通过避免一个对象明确指向其余的对象来促使自由耦合,同时能够让你单独的改变他们之间的相互作用。
我们不需要关心另一个对象做什么,只要把它交给一个负责管理的对象,而管理者负责对这些对象进行相互调用。
备忘录模式
备忘录模式是一种软件设计模式:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
Redis的RDB策略就利用了备忘录模式
状态模式
状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。
访问者模式
访问者模式是一个相对比较简单,但结构又稍显复杂的模式,它讲的是表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
比如说,年底,CEO和CTO开始评定员工一年的工作绩效,员工分为工程师和经理,CTO关注工程师的代码量、经理的新产品数量;CEO关注的是工程师的KPI和经理的KPI以及新产品数量。由于CEO和CTO对于不同员工的关注点是不一样的,这就需要对不同员工类型进行不同的处理。
- 上面仅仅只是23种模式的简单思想,如果想深入了解这肯定是不够的。
各种设计模式的关联关系和对比
单例模式和工厂模式
实际业务代码中,通常会把工厂类设计为单例。
策略模式和工厂模式
- 工厂模式包含工厂方法模式和抽象工厂模式是创建型模式,策略模式属于行为型模 式。
- 工厂模式主要目的是封装好创建逻辑,策略模式接收工厂创建好的对象,从而实现不同的行为。
单例模式和享元模式
单例模式必须是一个对象,享元模式可以是从多个对象中拿一个
策略模式和职责链模式
- 策略模式更加关注对于任务用什么方法来执行。
- 职责链模式更加关注与任务的分派
模板方法模式和工厂方法模式
工厂方法是模板方法的一种特殊实现。 工厂方法可以理解为只有一个方法的模板必须由子类来实现,而模板方法更加注重与整体流程,子类可以选择实现或者不实现模板中的某个方法。并且模板方法的每个方法的顺序不可改变。
模板方法模式和策略模式
- 模板方法和策略模式都有封装算法。
- 策略模式是使不同算法可以相互替换,且不影响客户端应用层的使用。
- 模板方法是针对定义一个算法的流程,将一些有细微差异的部分交给子类实现。
- 模板方法模式不能改变算法流程,策略模式可以改变算法流程且可替换。策略模式通 常用来代替if...else...等条件分支语句。
装饰者模式和静态代理模式
- 装饰者模式关注点在于给对象动态添加方法,而代理更加注重控制对对象的访问。
- 代理模式通常会在代理类中创建被代理对象的实例,而装饰者模式通常把被装饰者作 为构造参数。
- 装饰者模式必须要和被装饰者有同一个接口,或者实现被装饰者。
- 装饰者和代理者虽然都持有对方引用,但逻辑处理重心是不一样的。
- 其实装饰者模式和动态代理模式的区别还是显而易见的
装饰者模式和适配器模式
1、装饰者模式和适配器模式都是属于包装器模式(Wrapper Pattern)。
2、装饰者模式可以实现被装饰者与相同的接口或者继承被装饰者作为它的子类,而适配 器和被适配者可以实现不同的接口。
适配器模式和静态代理模式
适配器可以结合静态代理来实现,保存被适配对象的引用,但不是唯一的实现方式。
适配器模式和策略模式
在适配业务复杂的情况下,利用策略模式优化动态适配逻辑。
Spring中常用的设计模式对比
- 至于如何使用的只能通过源码分析,然后加上设计模式更好的理解spring