行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。
行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。
观察者模式
定义:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时会通知所有观察者对象,是他们能够自动更新自己。
例子:防止老板回来查岗,前台人员提醒大家
两个概念主题:观察者、被观察者,当观察者状态发生改变时,需要通知相应的观察者。当一个对象变化是,其他依赖该对象的对象都会收到通知。
作用;减少了观察者与被观察者之间的耦合度
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递
模板方法
例子:复制试卷让不同的学生来做
适用性:
定义:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,模板方法使的子类可以不改变一个算法的结构即可重定义该 算法的某些特定步骤。(先在父类中把需要的框架列出来,在父类中把一些方法虚写或抽象,然后把这些方法推迟到子类 中重写出来。)
它通过把不变的行为搬移到超类中,去除子类中的重复代码来体现它的优势,也就是提供了一个代码复用的平台。
优点:封装不变部分,扩展可变部分;行为有父类控制,子类实现
缺点:按照我们的设计习惯,抽象类负责声明最抽象、最一般的食物属性和方法,实现类完成具体的事物属性和方法。但是模板 方法模式却颠倒了,抽象类定义了部分抽象方法,有子类实现,子类执行的结果影响了父类的结果,也就是子类对父类产 生了影响,这在复杂的项目中会带来代码阅读的难度,而且也会让新手产生不适感
命令模式
命令模式
例子:烤羊肉串-烤肉串者和服务员
定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销 的操作。
利用服务员降低顾客与烧烤者之间的耦合度
适用:需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
状态模式
例子:小菜一天的工作状态
定义:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
主要是解决过于复杂的逻辑判断,将与特定状态相关的行为局部化,并且将不同状态的行为分割开来,将特定的状态相关的行为都放到一个对象中,由于所有与状态相关的代码都存在与某个类中,所以通过定义新的子类可以很容易的增加新的状态和转换
职责链模式
例子:小菜请假经理--总监--总经理
定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链 传递该请求,直到有一个对象处理他为止。分离职责,动态组合。
动态组合是职责链模式的精华,因为要实现请求对象和处理对象的解耦,请求对象并不知道最终的处理对象,所以需要动态的将可能的处理对象组合进来,也正因为组合是动态的,所以可以很方便的修改和增加处理对象,从而使系统具有更好的灵活性和扩展性。
解释器模式
定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器适用该表示来解释语言中的句子。
例子:乐谱
适用:重复发生的问题可以使用解释器模式
例如,多个应用服务器,每天产生大量的日志,需要对日志文件进行分析处理,由于各个服务器的日志格式不同,但是数 据要素是相同的,按照解释器的说法就是终结符表达式都是相同的,但是非终结符表达式就需要制定了。在这种情况下, 可以通过程序来一劳永逸地解决该问题。
一个简单语法需要解释的场景
中介者模式
定义:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式的相互引用,从而使耦合松散,而且可以独立的改变他们之间的交互。
例子:联合国安理会去充当美国和伊拉克的中介。
优点:联合国机构的出现减少了美国与伊拉克之间的耦合,任何国家的改变不会影响到其他国家,而只是与安理会发生变化,
适当地使用中介者模式可以避免同事类之间的过度耦合,使得各同事类之间可以相对独立地使用。
使用中介者模式可以将对象间一对多的关联转变为一对一的关联,使对象间的关系易于理解和维护。
使用中介者模式可以将对象的行为和协作进行抽象,能够比较灵活的处理对象间的相互作用。
缺点:模式中“中介”承担了很大的责任,所以一旦中介出现了问题,那么整个系统都会收到很大的影响。
适用:中介者模式一般应用于一组对象以定义良好但是复杂的方式进行通信的场合,以及向指定一个分布在多个类中的行为,而 又不想生成太多的子类的场合。
访问者模式
定义:一个作用于某对象结构中的各元素的操作,他是你可以在不改变各元素的类的前提下定义作用于这些元素的操作。
例子:男人,女人的成功失败
适用:1对于数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。
2不同的子类,依赖于不同的其他对象
3要对一组对象,进行许多不相关的操作,又不想在类中是现在这些方法
4定义的类很少改变,但是执行的操作却经常发生改变。
策略模式
定义:定义了多个算法,并将他们封装起来(一般每个算法封装成一个单独的类)
作用:就是把具体的算法实现从业务逻辑中剥离出来,称为一系列独立算法类,使得它们可以互相替换。
它的着重点不是如何来实现算法,而是如何组织和调用这些算法,从而让我们的程序结构更加的灵活、可扩展。
备忘录模式
定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态(其实不一定是在对象之外,可以是 类自主备份和恢复),这样以后就可以将该对象恢复到原先保存的状态。
优点:如果某个操作错误地破坏了数据的完整性,此时可以使用备忘录模式将数据恢复成原来正确的数据。
备份的状态数据保存在发起人角色之外,这样发起人就不需要对各个备份的状态进行管理。而是由备忘录角色进行管理,而备忘录角色又是由管理者角色管理,符合单一职责原则。
提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用先前存储起来的备忘录将状态复原。
实现了信息的封装,一个备忘录对象是一种原发器对象的表示,不会被其他代码改动,这种模式简化了原发器对象,备忘录只保存原发器的状态,采用堆栈来存储备忘录对象可以实现多次撤销操作,可以通过在负责人中定义集合对象来存储多个备忘录。
缺点:在实际的系统中,可能需要维护多个备份,需要额外的资源,这样对资源的消耗比较严重。资源消耗过大,如果类的成员变量太多,就不可避免占用大量的内存,而且每保存一次对象的状态都需要消耗内存资源,如果知道这一点大家就容易理解为什么一些提供了撤销功能的软件在运行时所需的内存和硬盘空间比较大了。
适用:如果系统需要提供回滚操作时,使用备忘录模式非常合适。
保存一个对象在某一个时刻的状态或部分状态,这样以后需要时它能够恢复到先前的状态
迭代器模式
定义:提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
例子:
你需要对聚集有多种方式遍历时,可以考虑用迭代器模式。
迭代器模式就是分离了集合对象的遍历,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码透明的访问集合内部的数据。