设计模式详解

什么是设计模式??

          1. 设计模式通过定义,使用,测试去解决特定问题,与OOP思想不可分割;

           2.针对软件设计中的重复性问题,可维护性强,可扩展性强;

           3.设计模式不仅描述了软件的架构方法,还说明了类与对象的交互关系,尤其是在运行时的关系。

           4.恰当使用设计模式会提高代码复用性----    复用:引入封装和间接调用,会减低系统性能并且提高代码复杂性。

 

  设计模式与软件架构

             1.模式是一种内在逻辑;软件架构有血有肉,以一种软件形式存在。

             2.模式独立于编程语言;框架以软件代码形式存在,依存于某种编程语言。

             3.模式是通用的,可用于不同应用之上;框架提供特定领域的应用功能。

             4.模式提供了优化设计的方法,有助于软件框架的设计;设计模模式在实际使用中也会以某种框架的形式实现。

 

GoF提出的23种设计模式;分为三类

创建型模式(5种):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式(7种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、

                                    状态模式、访问者模式、中介者模式、解释器模式

 

一.创建型模式:注重完成对象的实例化

                  对象创造型模式:完成对象创建,并将对象中部分内容放到其他对象中创建;

                  类创造性模式:完成类实例化,并将类中部分对象放到子类中创建(继承机制);

     <1>工厂方法模式:允许在子类中实现本类的实例化
        

              工厂模式详解 : https://mp.youkuaiyun.com/postedit/82391045

    <2>抽象工厂模式:提供一个用于创建相关对象或相互依赖对象的接口,无需指定对象的具体类

              工厂模式详解 : https://mp.youkuaiyun.com/postedit/82391045

 

     <3>建造者模式(生成器模式):将复杂对象的构建与表示分离,是的在同一构建过程中可以创建不同的表示

                  1.生成器:生产过程中的各个对象/不同类别用户需要展现的具体形式;

                   2.实例:Java API中 StringBuffer/StringBuilder 的使用;

                   3.房子建造:HouseBuilder(有哪些步骤)---->HouseDirect(步骤执行的顺序)----->HouseClient(需要建两栋房子)

                   4.生成器模式 VS 抽象工厂模式区别??

                          生成器模式:逐步完成对象构建&&对象构建序列化&&明确对象类型 只是有不同的表示而已;

                          抽象工厂模式:由工厂需要主动完成构建对象(不需要分步)&& 用户不知子对象类型;

 

    <4>原型模式:拷贝原型实例实现新对象的创建

         1.原型模式不创建对象,复制现有相似对象(克隆:复制对象的操作)

         2.克隆的方法:               

             浅层复制:原变新变,无新对象,新对象只是对原对象的引用;将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。

              深层复制:新对象与原对象无关,原对象的参数、对象、引用在新的对象中都重新拷贝;将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。深复制进行了完全彻底的复制,而浅复制不彻底。

         3.客户端类(管理和创建原型对象)通过调用原型类(声明一个接口用于克隆自己)的克隆操作创建一个新对象,具体原型类(clone()处理克隆操作&&创建自身新实例)实现克隆自己的操作,只是向调用者返回了克隆对象,从而保证客户端不知道具体原型类的类型,只是通过原型类实现了对他们的引用;

         Java原声代码中提供了克隆方法:clone()----占Java堆中的一块内存;

 

   <5>单例模式:确保某个类在系统中仅有一个实例,并提供一个访问它的全局访问点
               

                   单例模式详解: https://mp.youkuaiyun.com/postedit/82314278 

 

二.结构型模式:完成代码的结构划分

 

 <1>适配器模式(包装模式):为已有类提供新的接口

            1.客户端请求不同接口时实现类的重用;

            2.当你想用的类无法提供符合要求的接口就需要适配器;

            3. 接口转换工具,使得接口不兼容而无法一起工作的类可以一起工作,即变成客户端需要的接口;

  

            4.适配器类(Adapter):按目标类接口的要求对适配器类接口实现接口形式的适配转换;

                                                     实现适配对象类与目标类之间的接口适配(对客户端向适配度对象的的请求进行翻译);

                                                      核心:允许访问新的 方法

            5.适配对象类(Adapte):需要适配的现有接口

 

            6.适配器模式的实际应用:

                    <1>使用继承的适配器模式(类适配器):重写基类的方法;

                   <2>使用关联的适配器模式(对象适配器):不从基类继承 完成适配器创建,而是将基类作为一个属性,嵌入适配器内部;

                   <3>接口的适配器模式:接口的适配器模式,借助于一个抽象类,该抽象类实现了该接口,实现了所有的方法,而我们不和原始的接口打交道,只和该抽象类取得联系,所以我们写一个类,继承该抽象类,重写我们需要的方法就行;

 

    <2>桥接模式:允许将类的接口与其接口的实现相互解耦。

                           允许类及接口独立变化,增加类重用次数(扩展性)。

                           允许运行时对接口的不同实现方式动态切换,代码更灵活。

                实例: 风扇的开关。开关是电器的控制接口,而一旦闭合开关,实际上使风扇运转的是风扇电机。

                            开关和风扇彼此独立。。。

 

<3>组合模式:为客户端处理复杂的树结构(树的结构可变化)。

       1.组合模式:一组对象的集合,这组对象----一组组合模式构成的对象或者原始对象;

       2.组合模式中存在树状结构:在分支节点和叶子节点也都可以执行相同的操作,分支节点还是一个组合模式,叶子节点是一个原始对象了,它不再需要被继承和扩展。

      3.组合模式:对树结构中的各个对象执行通用的操作(类继承结构 && 可以用迭代器来遍历组合模式);

       4.实例:Windows系统中的文件结构(任何文件系统都包含文件、目录或者两者的组合)。

 

<4>装饰模式:附加新功能或者修改现有功能,在运行时动态地修改对象。

           1.装饰模式:可以选择一个类的某个对象,对其进行修改 而不会影响这个类的其他对象(运行时动态变化);

            2.继承(扩展功能):直接为类增加功能,而装饰模式会通过将对象与其他对象进行包装(在对象周围添加装饰类)的方式将功能添加到类;

            3.装饰类:在调用被装饰的实例(通过其他对象实现功能扩展)之前或者之后实现对其功能的扩展;

            4.具体组件:定义实现组件接口的对象。实际需要加以装饰的对象,对装饰的过程一无所知;

           5.Java API中装饰模式的实例:不改变对象的前提下实现对特定对象的功能扩展;在Java API中装饰模式(增加对象功能,而不需修改对象)用于处理 输入流和输出流的类,如:BufferReader()--方便高效的从文件读取文本;

 

  <5>门面模式:允许为客户端建立一个统一接口以访问不同子系统的不同接口,从而简化客户端。

         1.实例:当你站在一个大厦里,你只能看到它的内外部装修,并不知道大厦的内部结构和内部设计;大厦的装修隐藏了整个大厦的内部复杂结构,职位我们提供一个漂亮的外观。

         2.门面模式  隐藏了系统内部的复杂结构 并为客户端提供一个简单啊接口,以便客户端对系统进行访问(简化你的工作);

          3.实例 如:JDBC接口的应用------- 作为用户只需要创建数据库连接。并不需要关系 底层驱动的具体实现方法;

                             启动车辆:用户只需要转动钥匙,系统就会发出操作完成启动过程

                             电器上的快捷按钮 按键等等。。。。。

 

           4.门面层:知道子系统内各个类的具体功能,并将客户端请求转换成对系统内部对象的调用。

                             客户端使用门面层不需要再去直接访问子系统的内部对象;

            5.门面模式注重代码解耦:系统内部代码与接口子系统代码相互解耦;

            6.门面模式强调代码抽象:通过提供一个复杂接口并隐藏其后的复杂性,从而实现抽象;

            7.门面模式 :并不是保障系统安全、隐重要数据与实现的代码层,控制器不是门面模式;门面模式的目的是为了简化设计,实现各个依赖子系统之间的解耦。

            8.门面模式 与中介者模式(对交互对象之间的通信进行抽象,借助中介者实现通信功能)相似。。

 

 <6>享元模式:客户端调用类时会在运行时创建大量对象,该模式会重新设计类已优化内存开销。

            1.享元模式主要用于 需要创建大量类似性质的对象时----大量对象消耗内存的问题--> 通过共享对象来减少内存负荷

                    内存负荷具体实现:根据对象属性将对象分为 内蕴状态 (26个字母本身)/ 外蕴状态(字母的字体和颜色)

             2.模式内部角色:

                         抽象享元角色:具有内蕴状态的对象;

                         具体享元角色:存储内蕴状态,操总外蕴状态  具体享元角色必须是共享的;

                          享元工厂角色:创建和管理享元角色,该工厂也确保了享元角色的共享;

              3.策略:通过复用相同对象来减少对象创建的数量(共享是关键);

              4.享元模式核心:节约内存和共享对象。。。享元角色共享的越多,所节约的内存越多。。

              5.共享性:意味着引用计数和垃圾回收机制,用于享元模式不再需要对存储空间进行处理;

              6.享元模式、门面模式、组合模式区别?

                         享元模式--主要用于如何让处理大量的细小对象;

                         门面模式--通过一个单一对象来代表整个子系统;

                        组合模式:享元模式常于组合模式结合实现共享的叶节点;

 

  <7>代理模式:为其他对象提供一种代理以控制对你这个对象的访问。

             1.目的:一个对象不能直接引用另一个对象,简化客户端并实行对象访问。

             2.代理模式: 根据目的不同,由各种不同类型的代理:保护性代理(访问权限)、虚拟代理(开销过大,远程对象);

             3.ATM取款机机相对于银行柜台就是一个代理;

             4.代理模式:用一个简单对象表示一个复杂对象(即对一个复杂对象的引用);

             5. 模式内部角色:

                     抽象角色:由真实角色实现的接口,表达真实角色的功能(该接口也要由代理角色实现---使代理角色可用于

                                        所有真实角色使用的地方);

                     代理接口:维护了能允许代理角色访问真实角色的引用(实现同一接口),提供对真实角色的访问

                     真实角色:代理角色所代表的真是角色;

           6.对某个对象进行访问控制 ,一个原因是为推迟对象的创建和初始化,以避免大量的资源开销,直到真正需要它时创建;

           7.与装饰模式的区别:都是实现对某个类的代替,但是装饰类是这个类的子类;

           8.与适配器模式的区别:适配器为适配对象提供不同的接口,而大爱里模式提供相同接口;

           9.框架应用:spring 中 AOP 实现

 

三.行为模式:用于定义对象之间的通信和控制流程

           行为模式:对象间的数据交换 && 对象间保持 松耦合。。

           行为模式:用来避免硬编码和依赖性;

                         对象行为型模式:使用对象组合而非继承,一组对象合作完成而单个对象无法完成;

                          类行为型模式:使用继承而不是对象组合来描述算法和流程控制(如:解释器模式/模板方法模式);

 

    <1>责任链模式(COR):在一系列对象链之间传递请求的方法

             1. 目的:特定设计使得请求的发送者和接收者之间进行解耦,发送者不需要关心接收者的接口;

             2.使用问题:职责链上某个对象知道答案,却没有回答问题的机会, OOP设计中一个对象的行为不能转移到其他对象,

                                  且每个对象都是自我封闭的;

             3.实例:ATM取款机、sevlet过滤器、Java的异常处理机制(catch中的异常逐条扫描);

 

             4.职责链的角色:

                     抽象处理者:定义用于处理请求的接口;

                     具体处理者:负责处理请求,自行处理/发送给下一个处理者(请求在责任链上向下传递);

                     客户端:将命令职责链中第一个能够处理该请求的对象;

           5.职责链模式的应用场景

                   <1>发送者并不知道在链中的哪个对象会响应请求;

                   <2>责任链中的每个对象都有责任决定是否对请求进行响应,如果这些对象有能力响应他就会响应;

                   <3>如果对象决定向后传递请求,那他需要具有选择下一个节点和继续传递的能力;

                   <4>也有可能没有节点能响应请求(有些请求无法得到处理);

                   <5>会在运行时确定哪些对象能够响应请求;

 

     <2>命令模式:用于在需要向对象发出请求的情况,发出请求的对象无须了解请求的操作内容,也无须了解请求的实际接受对象;

            1.相关术语:客户端、调用者、接收者。。

             2.内部机制角色:     

                      客户端会创建具体命令类对象并指定其接收者

                     调用者(开关类)对象会存储具体命令类对象,调用者用execute() 方法执行请求;

                     具体命令类(打开空调/关闭空调)对象通过将接收者(空调)存储为实例变量来指定接收者的行为;

             3.命令模式:将调用操作的对象和执行操作的对象之间对命令进行解耦。实现调用者和接收者之间解耦

             4.命令模式将请求转换成对象,关键还是命令接口(会声明执行操作的接口); 

             5.责任链模式、命令模式的区别??

                        责任链模式需要经过每个对象的传递,直到某个对象对请求响应;命令模式 请求会根据命令找到特定对象

                        并调用完成响应;

 

<3>迭代器模式:用于顺序访问集合(组合)对象中的元素,无须了解其内部结构;

           1. 优点:能不考虑数据的存储方式而直接对各种类型的数据进行迭代;

           2.Java中的迭代器类型:栈、队列、Vector、ArrayList等。。。

           3.应用场景:

                    <1>需要访问一个聚合(容器)对象的内容,而无需须了解其内部表示;

                     <2>支持对聚合对象的多种遍历方式;

                     <3>为遍历不同的聚合结构提供统一的接口(支持多态迭代);

 

  <4>中介者模式:定义简单的类间通信(数据交互);

           1.  核心:一个中介者对象,负责协调一系列对象(同时类)之间一系列不同的数据请求。。

           2.实例:中介者在汽车启动时告知面板灯点亮,当大灯打开时,有告诉面板等熄灭。如过关掉大灯,又要告诉面板灯亮起来。同事类之间不会之间沟通,彼此的交互完全通过中介者实现。这样就能通过在一点处理所有请求来减小系统的复杂度,从而实现所有同事类之间的松耦合。。

 

 <5>观察者模式:一中通知多个类进行改变的方法;

           1.观察者模式:被观察者状态变化能传递给观察者,主要解决一对多的关系;

           2.实例:我们观众是一个观察者(提供商),电视是一个被观察者(听众);

           3.被观察者会提供一个带有特定方法的接口,用于在被观察者对象所维护的观察者对象集合中能够添加或删除观察者;

              该接口也会有一个通知方法,用于在对象状态发生改变时调用(会通知观察者被观察者的状态发生了改变);

           4.观察者也有一个接口:提供了一个更新观察者的方法,用于在被观察者的通知方法中对各个观察者进行调用;

           5.接口交互:任何具体实现了观察者接口的观察者都能够向被观察者进行更新----实现了被观察者和观察者之间的松耦合

 

<6>策略模式在类中进行算法封装;

           1.作用:需要使用不同的算法来处理不同的数据时;一种可以在运行时选择设计模式的设计模式

<7>状态模式当一个对象状态改变时改变其功能(根据内部状态实现不同行为);

<8>解释器模式:在程序中解析特定语言(在代码中使用特定语言的方法);

<9>备忘录模式:捕获和恢复对象的内部状态

<10>模板方法模式:将算法中的部分步骤延迟到子类中进行计算

<11>访问者模式:在不改变类的条件下为该类定义一个新的操作
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值