设计模式及优点总结.docx

上传人:wux****ua 文档编号:9111953 上传时间:2020-04-03 格式:DOCX 页数:18 大小:719.07KB
返回 下载 相关 举报
设计模式及优点总结.docx_第1页
第1页 / 共18页
设计模式及优点总结.docx_第2页
第2页 / 共18页
设计模式及优点总结.docx_第3页
第3页 / 共18页
点击查看更多>>
资源描述
桥接模式Bridge将抽象部分与它的实现部分分离,使它们都可以独立地变化。什么叫抽象与它的实现分离,这并不是说,让抽象类与其派生类分离,因为这没有任何意义。实现指的是抽象类和它的派生类用来实现自己的对象。由于实现的方式有多种,桥接模式的核心意图就是把这些实现独立出来,让它们独自地变化。这就使得每种实现的变化不会影响其他实现,从而达到应对变化的目的。 桥接模式的结构图如下: 将抽象部分与它的实现部分分离,这不是很好理解,我的理解就是实现系统可能有很多角度分类,每一种分类都有可能变化,那么就把这种多角度分离出来让它们独立变化,减少它们之间的耦合。也就是说,在发现我们需要多角度去分类实现对象,而只用继承会造成大量的类增加,不能满足开放封闭原则时,就应该要考虑桥接模式。单例模式Singleton 单例模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点。 通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象,一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且他可以提供一个访问该实例的方法。单例模式的结构图如下:单例模式因为Singletion类封装它的唯一实例,这样它可以严格控制客户怎样访问它以及何时访问它。简单地说就是对唯一实例的受控访问。 当在多线程情景下使用时,需要对GetInstance全局访问点加锁。适配器模式(Adapter)将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作。 也就是说系统的数据和行为都是正确的但接口不符时,我们应该考虑用适配器模式,目的是使控制范围之外的一个原有对象与某个接口匹配。适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况,比如说需要对早期代码复用一些功能等应用上很有实际价值。 适配器又两种类型,类适配器模式和对象适配器模式。但由于类适配器通常是通过多重继承实现的,而C#、VB.Net、JAVA等语言都不支持多重继承,也就是一个类只有一个父类,所以,我们这里主要讲对象适配器。适配器模式的结构图如下:Target:这是客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。Adaptee:需要适配的类。Adapter:通过在内部包装一个Adaptee对象,把源接口转换成目标接口。2、何时使用适配器模式在使用一个已存在的类时,如果它的接口,也就是它的方法和你的要求不相同时,就应该考虑使用适配器模式。这样客户端可以调用统一接口就行了,这样客户端代码就可以更简单、更直接、更紧凑。 但是适配器模式也是无奈之举,很有点亡羊补牢的感觉,但是是软件就有维护的一天,所以,通常在软件开发的中后期或维护期在考虑使用它。这也就是说,一个项目在设计阶段类和方法名就应该要有规范,最好前期就设计好,然后如果在开发阶段发现接口不一致,这时候首先也不应该考虑使用适配器模式,而应该首先考虑去重构统一接口。只有在双方都不太容易修改的时候再使用适配器模式,而不是一有不同就使用它。备忘录模式(Memento)在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。被网络模式结构图Originator(发起人):负责创建一个备忘录,用以记住当前时刻它的内部状态,并可使用备忘录恢复内部状态。Originator可根据需要决定Memento存储Originator的那些内部状态。Memento(备忘录):负责存储Originator对象的内部状态,并可防止Originator以外的其他对象访问备忘录。备忘录有两个接口,Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象。Originator能够看到一个宽接口,允许访问返回到先前状态所需的所有数据。Caretaker(管理者):负责保存好备忘录,不能对备忘录的内容进行操作或检查。2、何时使用备忘录模式Memento模式比较适合功能比较复杂的,但需要维护或者记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。 如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销的状态。状态模式(State)当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。状态模式的结构图如下:State:抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。ConcreteState:具体状态,每一个子类实现一个与Context的一个状态相关的行为。Context:维护一个ConcreteState子类的实例,这个实例定义当前的状态。2、状态模式的好处与用处将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所以,通过定义新的子类可以很容易地增加新的状态和转换。这样就消除了庞大的条件分支语句。大的分支语句判断会使得它们难以修改和扩展。状态模式通过把各种状态转移逻辑分不到State的子类之间,来减少相互间的依赖。当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。组合模式将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。组合模式的结构图如下:Component为组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的子部件。 Leaf:在组合中表示节点对象,叶节点没有子节点。 Composite:定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如说Add、Remove。2、组合模式的透明方式和安全方式a)透明方式:也就是说在Component中声明所有用来管理子对象的方法,其中包括Add、Remove等。这样实现Component接口的所有子类都具备了Add和Remove。这样做的好处就是叶节点和枝节点对于外界没有区别,它们具备完全一致的行为接口。但问题也很明显,因为Leaf类本身不具备Add()、Remove()方法的功能,所以,实现它是没有意义的。b)安全方式:也就是说在Component接口中不去声明Add和Remove方法,那么子类的Leaf也就不需要去实现它,而是在Composite声明所有用来管理子对象的方法,这样做就不会出现刚出现的问题,不过由于不够透明,所以树叶和树枝将具有不同相的接口,客户端的调用要做相应的判断,带来了不便。3、组合模式的适用场合当发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑使用组合模式。迭代器模式(Iterator)提供一种方法顺序访问一个聚合对象中各个元素,而不不暴露该对象的内部表示。当需要访问一个聚焦对象,而且不管这些对象是什么都需要遍历的时候,就应该考虑使用迭代器模式。特别当需要对聚焦有多种方式遍历时,更应该考虑迭代器模式,为遍历不同的聚焦结构提供如开始、下一个、是否结束、当前哪一个等统一接口。 迭代器模式的结构图如下:Aggregate:聚焦抽象类。Iterator:迭代器抽象类,用于定义得到开始对象、得到下一个对象、判断是否到结尾、当前对象等抽象方法,统一接口。ConcreteAggregate:具体聚焦类,继承Aggregate。ConcreteIterator:具体迭代器类,继承Iterator,实现开始、下一个、是否结尾、当前对象等方法。2、迭代器的好处迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码同名地访问集合内部的数据。 但是由于它太普遍了,所以各种高级语言都对它进行了封装,所以,反而给人感觉此模式本身不太常用。组合模式将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。组合模式的结构图如下:Component为组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的子部件。 Leaf:在组合中表示节点对象,叶节点没有子节点。 Composite:定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如说Add、Remove。2、组合模式的透明方式和安全方式a)透明方式:也就是说在Component中声明所有用来管理子对象的方法,其中包括Add、Remove等。这样实现Component接口的所有子类都具备了Add和Remove。这样做的好处就是叶节点和枝节点对于外界没有区别,它们具备完全一致的行为接口。但问题也很明显,因为Leaf类本身不具备Add()、Remove()方法的功能,所以,实现它是没有意义的。b)安全方式:也就是说在Component接口中不去声明Add和Remove方法,那么子类的Leaf也就不需要去实现它,而是在Composite声明所有用来管理子对象的方法,这样做就不会出现刚出现的问题,不过由于不够透明,所以树叶和树枝将具有不同相的接口,客户端的调用要做相应的判断,带来了不便。3、组合模式的适用场合当发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑使用组合模式。抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 结构图如下:AbstractProductA和AbstractProductB是两个抽象产品,之所以为抽象,是因为它们都有可能有两种不同的实现,如:产品1是用SQL数据库实现的、而产品2是由Access数据库实现的。AbstractFactory是一个抽象工厂接口,它里面应该包含所有的产品创建的抽象方法。而ConcreteFactory1和ConcreteFactory2就是具体的工厂了。由这两个工厂产生具体的产品。如图中,ConcreteFactory1生产ProductA 1和ProductB 1这两个具体产品。通常是在运行时刻再创建一个ConcreteFactory类的实例,这个具体的工厂再创建具有特定实现的产品对象,说,为创建不同的产品对象,客户端应该使用不同的具体工厂。2、抽象工厂的优缺点优点,易于交换产品系列,由于具体工厂类,在一个应用中只需在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,他只需改变具体工厂即可使用不同的产品配置。它让具体的创建实例过程与客户端分离,客户端是通过他们的抽象接口操作实例,产品的具体类名也被具体的工厂的实现分离,不会出现在客户代码中。 缺点是当需要新增一个抽象产品时,不止需要新增3个类(AbstractProductC、ProductC1、ProductC1),而且需要修改3个类(ConcreteFactory、ConcreteFactory 1、ConcreteFactory 2)。 针对解决这一缺陷可以使用简单工厂+反射技术(由于篇幅过长不给出详述)。观察者模式又叫发布订阅模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生改变时,会通知所有观察者对象。这个主题对象在状态发生变化时,同会通知所有观察者对象,使它们能够自动更新自己。结构图如下:Subject类,它把所有观察者对象的引用,保存在一个聚集里,每个subject都可以任何数量的观察者。抽象subject提供一个接口可以增加和删除观察者对象。Observer类,抽象观察者,为所有的具体观察者定义一个接口,在得到Subject的通知时更新自己。ConcreteSubject类,具体Subject,将有关状态存入具体观察者对象;在具体主题的内部改变时,给所有登记过的观察者发出通知。ConcreateObserver类,具体观察者,实现抽象观察者较色所要求的更新接口,以便使本身的状态与subject的状态相协调。2、观察者模式的特点当一个对象的改变要同时改变其他对象,且它不知道具体有多少对象等待改变时,应该考虑使用观察者模式。 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自地独立地改变和复用。3、事件委托 虽然,观察者模式消除了通知者和观察者的直接依赖,但是它们还是相互依赖对方的抽象(抽象观察者和抽象通知者),而且,观察者必须要实现“更新”接口。这样如果,其中的一方如抽象观察者一旦不再存在,抽象通知者便无法通知下去。而在编程中经常有通知者和观察者之间就根本不知道对方,这样,如果由客户端来决定通知谁就好了事件委托就可以实现。 委托就是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何的方法一样,具有参数和返回值。委托可以看作是对函数的抽象,是函数的“类”,委托的实例将代表一个具体的函数。 一个委托可以搭载多个方法,所有方法被依次唤起,更重要的是它可以使委托对象所搭载的方法并不需要同属于一个类。 但是委托也是有前提的,那就是委托对象所搭载的所有方法必须具有相同的原型和形式,也就是拥有相同的参数列表和返回类型。建造者模式将一个复杂对象的构建于它的表示分离,使得同样的构建过程可以创建不同的表示。结构图如下:Builder;是为创建一个Product对象的各个部件指定的抽象接口。ConcreteBuilder:它是具体的建造者,实现Builder接口,构造和装备各个部件。Product:为具体的产品。Director:用于构建一个使用Builder接口的对象。 建造者模式主要用于创建一些复杂的对象,这些对象内部构建间的构造顺序通常是稳定的,但对象内部的构建通常面临这复杂的变化。 建造者模式的好处是使得构建代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以,若需要改一个产品的内部表示,只需要再定义一个具体的建造者就可以了。 建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用的模式。外观模式,为子系统中的一组接口提供一个一致的界面,次模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式的结构图如下:Facade 外观类:知道哪些子系统负责处理请求,将客户的请求代理给适当的子系统对象。SubSystem Classes 子系统类集合,实现了子系统的功能,处理Facade对象指派的任务。注意子类中没有Facade的任何信息,即没有对Facade的对象的引用。何时使用外观模式: 这要分三个阶段说,首先,在设初期,应该要有意识的将不同的两个层分离,比如说经典的三层架构,就需要考虑在数据访问层和业务逻辑层,业务逻辑层和表示层的层与层之间建立外观的Facade,这样可以为复杂的子系统提供一个简单的接口。其次,在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂,增加外观Facade可以提供一个简单的接口,减少他们之间的依赖。第三,在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,但因为含有重要的功能,新的开发必须要依赖它时,用外观模式Facade也是非常合适的。你可以为新系统开发一个外观Facade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作。简单工厂模式解释: 简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。简单工厂模式的UML图: 简单工厂模式中包含的角色及其相应的职责如下: 工厂角色(Creator):这是简单工厂模式的核心,由它负责创建所有的类的内部逻辑。当然工厂类必须能够被外界调用,创建所需要的产品对象。 抽象(Product)产品角色:简单工厂模式所创建的所有对象的父类,注意,这里的父类可以是接口也可以是抽象类,它负责描述所有实例所共有的公共接口。 具体产品(Concrete Product)角色:简单工厂所创建的具体实例对象,这些具体的产品往往都拥有共同的父类。简单工厂模式深入分析: 简单工厂模式解决的问题是如何去实例化一个合适的对象。 简单工厂模式的核心思想就是:有一个专门的类来负责创建实例的过程。 具体来说,把产品看着是一系列的类的集合,这些类是由某个抽象类或者接口派生出来的一个对象树。而工厂类用来产生一个合适的对象来满足客户的要求。 如果简单工厂模式所涉及到的具体产品之间没有共同的逻辑,那么我们就可以使用接口来扮演抽象产品的角色;如果具体产品之间有功能的逻辑或,我们就必须把这些共同的东西提取出来,放在一个抽象类中,然后让具体产品继承抽象类。为实现更好复用的目的,共同的东西总是应该抽象出来的。 在实际的的使用中,抽闲产品和具体产品之间往往是多层次的产品结构,如下图所示:简单工厂模式使用场景分析及代码实现: GG请自己的女朋友和众多美女吃饭,但是GG自己是不会做饭的或者做的饭很不好,这说明GG不用自己去创建各种食物的对象;各个美女都有各自的爱好,到麦当劳后她们喜欢吃什么直接去点就行了,麦当劳就是生产各种食物的工厂,这时候GG不用自己动手,也可以请这么多美女吃饭,所要做的就是买单O(_)O哈哈,其UML图如下所示:
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 管理文书 > 工作总结


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!