设计模式
分享各设计模基本概念及具体使用。
星火撩猿
莫道君行早,更有早行人;全心敲代码,天道自酬勤。
展开
-
设计模式总结
一个目标:管理变化,提高复用两种手段:分解,抽象八大原则:依赖倒置原则(DIP)开放封闭原则(OCP)单一职责原则(SRP)Liskov替换原则(LSP)接口隔离原则(ISP)对象组合优于类继承封装变化点面向接口编程重构技法:静态——》动态早绑定——》晚绑定继承——》组合编译时依赖——》运行时依赖紧耦合——》松耦合从封装变化角度对模式分类组件协作:Template Method,Strategy,Observer/Event单一职责:Decorat原创 2021-02-23 00:04:43 · 125 阅读 · 2 评论 -
访问器
动机在软件构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的更改,将会给子类带来很繁重的变更负担,甚至破坏原有设计。如何在不更改类层次结构的前提下,在运行时根据需要透明地为类层次结构上的各个类动态添加新的操作,从而避免上述问题?模式定义表示一个作用于某对象结构中的各元素的操作。使得可以在不改变(稳定)各元素的类的前提下定义(扩展)作用于这些元素的新操作(变化)。要点总结Visitor模式通过所谓双重分发(double dispatch)来原创 2021-02-22 23:20:31 · 150 阅读 · 0 评论 -
解析器
动机在软件构建过程中,如果某一特定领域的问题比较复杂,类似的结构不断重复出现,如果使用普遍的编程方式来实现将面临非常频繁的变化。在这种情况下,将特定领域的问题表达为某种语法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。模式定义给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器使用该表示来解释语言中的句子。要点总结Interpreter模式的应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且类似的结构不断重复出现,原创 2021-02-22 23:19:36 · 179 阅读 · 0 评论 -
职责链
动机在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果被显式指定,将必不可少地带来请求发送者与接受者的紧耦合。如何使请求的发送者不需要指定具体的接受者?让请求的接受者自己在运行时决定来处理请求,从而使两者解耦。模式定义使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。要点总结Chain of Responsibility模式的应用场合在于“一个请求可能有多个原创 2021-02-22 22:32:49 · 117 阅读 · 2 评论 -
迭代器
动机在软件构建过程中,集合对象内部结构常常变化各异。但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素;同时这种“透明遍历”也为“同一种算法在多种集合对象上进行操作”提供了可能。使用面向对象技术将这种遍历机制抽象为“迭代器对象”,为“应对变化中的集合对象”提供了一种优雅的方式。模式定义提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露(稳定)该对象的内部表示。要点总结迭代对象:访问一个聚合对象的内容而无需暴露它的内部表示。迭代多态:原创 2021-02-21 21:12:57 · 95 阅读 · 0 评论 -
组合模式
动机软件在某些情况下,客户代码过多地依赖于对象容器复杂的内部实现结构,对象容器内部实现结构(而非抽象接口)的变化将引起客户代码的频繁变化,带来了代码的维护性,扩展性等弊端。如果将“客户代码与复杂的对象容器结构”解耦?让对象容器自己来实现自身的复杂结构,从而使得客户代码就像处理简单对象一样来处理复杂的对象容器?模式定义将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性(稳定)。要点总结Composite模式采用树形结构来实现原创 2021-02-21 21:03:34 · 91 阅读 · 0 评论 -
备忘录模式
动机在软件构建过程中,某些对象的状态在转换过程中,可能由于某种需要,要求程序能够回溯到对象之前处于某个点时的状态。如果使用一些公有接口来让其他对象得到对象的状态,便会暴露对象的细节实现。如何实现对象状态的良好保存和恢复?但同时又不会因此而破坏对象本身的封装性。模式定义在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。要点总结备忘录(Memento)存储原发器(Originator)对象的内部状态,在需要时恢复原发器状原创 2021-02-21 20:34:14 · 104 阅读 · 0 评论 -
状态模式
动机在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转化之间引入紧耦合?模式定义允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。要点总结State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象;但同时维持State的接口,这样实现了具体操作与状原创 2021-02-21 20:21:54 · 108 阅读 · 0 评论 -
中介者
动机在软件构建过程中,经常会出现多个对象互相关联交互的情况,对象之间常常会维持一种复杂的引用关系,如果遇到一些需求的更改,这种直接的引用关系将面临不断的变化。在这种情况下,我们可使用一个“中介对象”来管理对象间的关联关系,避免相互交互的对象之间的紧耦合引用关系,从而更好地抵御变化。模式定义用一个中介对象来封装(封装变化)一系列的对象交互。中介者使各对象不需要显式的相互引用(编译时依赖–>运行时依赖),从而使其耦合松散(管理变化),而且可以独立地改变它们之间的交互。要点总结将多个对原创 2021-02-21 18:59:31 · 137 阅读 · 0 评论 -
适配器模式
动机在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放到新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的。如何应对这种“迁移的变化”?如何既能利用现有对象的良好实现,同时又能满足新的应用环境所要求的接口?模式定义将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。要点总结Adapter模式主要用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用,类库迁移等方面非常有原创 2021-02-21 14:03:26 · 84 阅读 · 0 评论 -
代理模式
动机在面向对象系统中,有些对象由于某种原因(比如对象创建的开销很大,或者某些操作需要安全控制,或者需要进程外的访问等等),直接访问会给使用者,或者系统结构带来很多变化。如何在不失去透明操作对象的同时来管理/控制这些对象特有的复杂性?增加一层间接层是软件开发中常见的解决方式。模式定义...原创 2021-02-21 13:52:38 · 83 阅读 · 0 评论 -
门面模式
“接口隔离”模式在组件构建过程中,某些接口之间直接的依赖常常会带来很多问题,甚至根本无法实现。采用添加一层间接(稳定)接口,来隔离本来互相紧密关联的接口是一种常见的解决方案。典型模式FacadeProxyAdapterMediator动机组件的客户和组件中各种复杂的子系统有了过多的耦合,随着外部客户程序和各子系统的演化,这种过多的耦合面临很多变化的挑战。如何简化外部客户程序和系统间的交互接口?如何将外部客户程序的演化和内部子系统的变化之间的依赖相互解耦?模式定义为子系统中原创 2021-02-21 08:49:44 · 102 阅读 · 0 评论 -
享元模式
动机在软件系统采用纯粹对象方案的问题在于大量细粒度得对象会很快充斥在系统中,从而带来很高的运行时代价——主要指内存需求方面的代价。如何在避免大量细粒度对象问题的同时,让外部客户程序仍然能够透明地使用面向对象的方式来进行操作?模式定义运用共享技术有效地支持大量细粒度的对象。要点总结面向对象很好地解决了抽象性的问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。Flyweight主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。Flyweight采用对象共享的原创 2021-02-21 08:18:35 · 116 阅读 · 0 评论 -
构建器
动机在软件系统中,有时候面临着”一个复杂对象“的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。如何应对这种变化?如何提供一种封装机制来”隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?模式定义将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)。要点总结Builder模式主要用于“分步骤构建一个复杂的对象”原创 2021-02-17 16:16:34 · 116 阅读 · 0 评论 -
原型模式
动机在软件系统中,经常面临着”某些结构复杂的对象“的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。如何应对这种变化?如何向”客户程序(使用这些对象的程序)“隔离出”这些易变对象“,从而使得”依赖这些易变对象的客户程序“不随着需求改变而改变?模式定义使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。要点总结Prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些”易变类“拥有”稳定的接原创 2021-02-17 16:05:13 · 96 阅读 · 0 评论 -
单例模式
动机在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性,以及良好的效率。如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?这应该是类设计者的责任,而不是使用者的责任。模式定义保证一个类仅有一个实例,并提供一个该实例的全局访问点。要点总结Singleton模式中的实例构造器可以设置为protected以允许子类派生。Singleton模式一般不要支持拷贝构造函数和Clone接口,因为这有可能导致多个对象实例,与Singleto原创 2021-02-17 10:38:47 · 106 阅读 · 0 评论 -
抽象工厂
动机在软件系统中,经常面临着”一系列相互依赖的对象“的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。如何应对这种变化?如何绕开常规的对象创建方法(new),提供一种”封装机制“来避免客户程序和这种”多系列具体对象创建工作“的紧耦合?要点总结如果没有应对”多系列对象构建“的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的工厂完全可以。”系列对象“指的是在某一特定系列下的对象之间有相互依赖,或作用的关系。不同系列的对象之间不能有相互依赖。Abs原创 2021-02-17 10:20:44 · 106 阅读 · 0 评论 -
装饰模式
动机某些情况下我们可能会”过度地使用继承来扩展对象的功能“,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。如何使”对象功能的扩展“能够根据需要来动态地实现?同时避免”扩展功能的增多“带来的子类膨胀问题?从而使得任何”功能扩展变化“所导致的影响降为最低?模式定义动态(组合)地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码 &原创 2021-02-17 10:04:19 · 90 阅读 · 0 评论 -
观察者模式
动机在软件构建过程中,我们需要为某些对象建立一种”通知依赖关系“——一个对象(目标对象)的状态发生改变,所有的依赖关系(观察者对象)都将得到通知。如果这样的依赖关系过于亲密,将使软件不能很好地抵御变化。使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。要点总结:使用面向对象的抽象,Observer模式使得我们可以独立地改变目标和观察者,从而使二者之间的依赖关系达致松耦合。目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播原创 2021-02-17 09:00:34 · 99 阅读 · 0 评论 -
策略模式
动机在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?模式定义定义一系列算法,把它们一个个封装起来,并且使它们可互相替换(变化)。该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化)。要点总结Strategy及其子类为组件提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需原创 2021-02-14 13:40:42 · 83 阅读 · 0 评论 -
模板方法
GOF-23 模式分类从目的来看:创建型(Creational)模式:将对象的部分创建工作延迟到子类或者其他对象,从而应对需求变化为对象创建时的具体类实现引来的冲击。结构型(Structural)模式:通过类继承或者对象组合获得更灵活的结构,从而应对需求变化为对象的结构带来的冲击。行为型(Behavioral)模式:通过类继承或者对象组合来划分类与对象间的职责,从而应对需求变化为多个交互的对象行为带来的冲击。从范围来看:类模式处理类与子类的静态关系对象模式处理对象间的动态关系组件协作原创 2021-02-14 13:15:50 · 101 阅读 · 0 评论 -
工厂模式
”对象创建“模式原创 2021-02-13 22:07:39 · 105 阅读 · 0 评论 -
面向对象设计原则
面向对象设计,为什么?变化是复用的天敌,面向对象设计最大的优势在于:抵御变化重新认识面向对象理解隔离变化从宏观层面来看,面向对象的构建方式更能适应软件的变化,能将变化所带来的影响减为最小各司其职从微观层面来看,面向对象的方式更强调各个类的”责任“由于需求变化导致的新增类型不应该影响到原来类型的实现——是所谓各负其责对象是什么从语言实现层面来看,对象封装了代码和数据。从规格层面讲,对象是一系列可被使用的公共接口。从概念层面讲,对象是某种拥有责任的抽象。面向对象设计原则依赖倒置原创 2021-02-12 21:57:57 · 720 阅读 · 0 评论 -
设计模式简介
什么是设计模式每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动。GOF设计模式推荐书籍:《设计模式:可复用面向对象软件的基础》历史性著作《设计模式:可复用面向对象软件的基础》一书中描述了23中经典面向对象设计模式,创立了模式在软件设计中的地位。由于《设计模式》一书中确定了设计模式的地位,通常所说的设计模式隐含地表示”面向对象设计模式“。但这并不意味”设计模式“就等于”面向对象设计模式“。从面向对象谈起,包含底原创 2021-02-12 17:51:59 · 107 阅读 · 2 评论 -
桥模式
”单一职责模式“在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任。典型模式DecoratorBridge动机由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个维度的变化。如何应对这种”多维度的变化“?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?模式定义将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。原创 2021-02-12 14:05:08 · 147 阅读 · 0 评论 -
命令模式
行为变化模式在组件的构建过程中,组件行为的变化经常导致组件本身剧烈的变化。“行为变化”模式将组件的行为和组件本身进行解耦,从而支持组件行为的变化,实现两者之间的松耦合。典型模式:Command,VisitorCommand模式动机在软件构建过程中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合——比如需要对行为进行“记录,撤销/重,事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”和“行为实现者”解耦?将一组行为抽象为对象,可以实现二者之原创 2021-02-10 21:42:16 · 77 阅读 · 0 评论