精华内容
下载资源
问答
  • 行为型模式
    2020-02-13 22:13:20

    复习设计模式有两周了,有必要重新把设计模式的整体结构梳理一下,在此摘录刘伟老师的教材中部分知识点,做个笔记。

    一、设计模式的分类

    根据其 目的 (模式是用来做什么的)可分为 创建型 (Creational) 结构型 (Structural) 行为型 (Behavioral) 三种:
    创建型模式主要用于 创建对象
    结构型模式主要用于 处理类或对象的组合
    行为型模式主要用于 描述对类或对象怎样交互和怎样分配职责
    根据 范围 ,即模式主要是用于处理类之间关系还是处理 对象之间的关系,可分为 类模式 对象模式 两种:
    类模式 处理类和子类之间的关系 ,这些关系通过继承建立,在编译时刻就被确定下来,是属于 静态 的。
    对象模式 处理对象间的关系 ,这些关系在运行时刻变化,更具 动态 性。

    二、GoF设计模式

    创建型模式
    • 抽象工厂模式(Abstract Factory)
    • 建造者模式(Builder)
    • 工厂方法模式(Factory Method)
    • 原型模式(Prototype)
    • 单例模式(Singleton)
    结构型模式
    • 适配器模式(Adapter)
    • 桥接模式(Bridge)
    • 组合模式(Composite)
    • 装饰模式(Decorator)
    • 外观模式(Facade)
    • 享元模式(Flyweight)
    • 代理模式(Proxy)
    行为型模式
    • 职责链模式(Chain of Responsibility)
    • 命令模式(Command)
    • 解释器模式(Interpreter)
    • 迭代器模式(Iterator)
    • 中介者模式(Mediator)
    • 备忘录模式(Memento)
    • 观察者模式(Observer)
    • 状态模式(State)
    • 策略模式(Strategy)
    • 模板方法模式(Template Method)
    • 访问者模式(Visitor)

    三、创建型模式

    创建型模式 (Creational Pattern) 对类的实例化过程进 行了抽象,能够 将软件模块中对象的创建和对象的使用 分离 。为了使软件的结构更加清晰,外界对于这些对象 只需要知道它们共同的接口,而不清楚其具体的实现细 节,使整个系统的设计更加符合单一职责原则。
    创建型模式在 创建什么 (What) 由谁创建 (Who) 时创建 (When) 等方面都为软件设计者提供了尽可能大 的灵活性。创建型模式 隐藏了类的实例的创建细节,通 过隐藏对象如何被创建和组合在一起达到使整个系统独 立的目的

    四、结构型模式

    描述 如何将类或者对 象结合在一起形成更大的结构 ,就像搭积木,可以通过 简单积木的组合形成复杂的、功能更为强大的结构。
    结构型模式可以分为 类结构型模式 对象结构型模式
    类结构型模式关心类的组合 ,由多个类可以组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系。
    对象结构型模式关心类与对象的组合,通过关联关系使得在一个类中定义另一个类的实例对象,然后通过该对象调用其方法。 根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系,因此大部分结构型模式都是 对象结构型模式

    五、行为型模式

    行为型模式 (Behavioral Pattern) 是对 在不 同的对象之间划分责任和算法的抽象化
    行为型模式不仅仅关注类和对象的结构,而 重点关注它们之间的相互作用 通过行为型模式,可以更加清晰地 划分类与
    对象的职责 ,并 研究系统在运行时实例对象 之间的交互 。在系统运行时,对象并不是孤 立的,它们可以通过相互通信与协作完成某 些复杂功能,一个对象在运行时也将影响到 其他对象的运行。
    行为型模式分为 类行为型模式 对象行为型模式 两种:
    类行为型模式 :类的行为型模式 使用继承关系在几个类之间分配行为 ,类行为型模式主要通过多态等方式来分配父类与子类的职责。
    对象行为型模式 :对象的行为型模式则 使用对象的聚合关联关系来分配行为 ,对象行为型模式主要是通过对象关联等方式来分配两个或多个类的职责。根据“合成复用原则”,系统中要尽量使用关联关系来取代继承关系,因此大部分行为型设计模式都属于对象行为型设计模式
    更多相关内容
  • 行为型模式(BehavioralPattern)是对在不同的对象之间划分责任和算法的抽象化。行为型模式不仅仅关注类和对象的结构,而且重点关注它们之间的相互作用。在系统运行时,对象并不是孤立的,它们可以通过相互通信与协作...
  • 行为型模式简介

    千次阅读 2020-01-08 16:56:49
    行为型模式简介 行为型类模式使用继承描述算法和控制流,而行为型对象模式则描述一组对象怎样协作完成单个对象无法完成的任务。 一、职责链,CHAINOFRESPONSIBILITY,对象行为型模式 使多个对象都有机会处理请求...

    行为型模式简介

        行为型类模式使用继承描述算法和控制流,而行为型对象模式则描述一组对象怎样协作完成单个对象无法完成的任务。

    一、职责链,CHAIN OF RESPONSIBILITY,对象行为型模式

    使多个对象都有机会处理请求,从而避免请求的发送者和接收着之间的耦合关系。将这些对象生成一条链,并沿着这条链传递该消息,直到有一个对象处理它为止。

     

    适用性

          有多个对象处理请求,那个对象处理该请求在运行时可自动确定。

          你想在不指名接受者的情况下,向多个对象中的一个提交请求。

          可处理一个请求的对象集合应被动态指定。

    二、命令,COMMAND,对象行为型模式

        将一个请求封装成一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

    适用性

        抽象出待执行的动作以参数化某对象,你可用过程语言中的回调(call back)函数表达这种参数化机制。所谓回调函数是指函数先在某处注册,而它将在稍后某个需要的时候被调用。Command模式是回调机制的一个面向对象的替代品。

    在不同的时刻指定、排列和执行请求。

    支持取消操作。

    支持修改日志。

    用构建在原语操作上的高层操作构造一个系统。

    三、解释器,INTERPRETER,类行为型模式

        给定一个语言,定义它的方法的一种表示,并定义一个解释器,这个解释器用该表示来解释语言中的句子。

     

    四、迭代器,ITERATOR,对象行为型模式

    提供一处方法顺序访问一个聚合中各个元素,而不需要暴露该对象的内部表示。

     

    适用性

    l         访问一个聚合对象的内容而无需暴露他的内部表示。

    l         支持对句和对象的多种遍历。

    l         为遍历不同的聚合结构提供一个统一的接口。

    五、中介者,MEDIATOR,对象行为型模式

        用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

     

    每一个同事类都知道它的中介者对象。每一个同事对象在需与其他的同事通信的时候,都与它的中介者通信

    适用性

    1.一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。

    2.一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。

    3.想定制一个分布在多个类中的行为,而又不想生成太多的子类。

        Facade协作是单向的,即Facade对象对这个子系统提出请求,反之不行。Mediator提供了各Colleague对象不支持的协作行为,而且协议是多向的。

    六、备忘录,MEMENTO,对象行为型模式

    在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

     

    适用性

    1)必须保存一个对象在某一个时刻的(部分)状态,这样以后需要时它才能恢复到先前的状态。

    2)如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

    七、观察者,OBSERVER,对象形为型模式

        定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并被自动更新。

     

    ConcreteObserver维护一个指向ConcreteSubject对象的引用。

        当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中可以使他们各自独立地改变和复用。

        当对一个对象的改变需要同时改变其它对象,而不知道具体由多少对象有待改变。

        当一个对象必须通知其他对象,而它又不能假定其他对象是谁,换言之,你不希望这些对象是紧密耦合的。

    八、状态,STATE,对象形为型模式

        允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎是修改了它的类。

     

    适用性

    一个对象的行为取决与它的状态,并且它必须在运行时根据状态改变它的行为。

    一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。

    九、策略,STRTEGY,对象行为型模式

        定义一系列算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。

     

    适用性

    1.许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。

    2.需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间/时间权衡的算法。当这些变体实现为一个算法的类层次时,可以使用策略模式。

    3.算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的,与算法相关的数据结构。

    4.一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

    十、模板方法,TEMPLATE METHOD,类行为型模式

        定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TEMPLATE METHOD使得子类可以不改变一个算法的结构就可重定义该算法的某些特定步骤。

    反向控制,父类调用子类。

    适用性

    一次性实现一个算法的不变部分,并将可变的部分留给子类来实现,

    各个子类中公共的行为应该被提取出来并集中到一个公共父类中以避免代码的重复。

    控制子类的扩展,模板方法旨在特定点调用”hook”操作

    hook操作:可被重定义的

    原语操作:抽象操作,必须被重定义的。

    十一、访问者,VISITOR,对象行为型模式

        表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的操作。

     

    适用性:

    1.一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。

    2.需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作"污染"这些对象的类。Visitor使得你可以将相关的操作集中起来定义在一个类中。当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作。

    3.定义对象结构的类很少改变,但经常需要在结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。

    讨论

    封装变化是很多行为模式的主题。当一个程序的某个方面的特征经常发生变化时,这些模式就定义一个封装这个方面的对象。

    Strategy对象封装算法

    State对象封装与状态相关的行为

    Mediator对象封装对象间协议

    Iterator对象封装访问遍历操作

    大多数模式有两种对象:封装该方面特征的新对象,使用这些新对象的已有对象。一些模式引入总是被用作参数的对象。

    展开全文
  • 1 创建型模式 本人理解:以C++为例,创建对象时,用关键字new来创建(实例化)对象。用一个函数或类将new的过程封装起来,就是创建型模式。 《设计模式》中的描述: 创建型模式抽象了实例化过程。它们帮助一个系统...

    1 创建型模式

    本人理解:以C++为例,创建对象时,用关键字new来创建(实例化)对象。用一个函数或类将new的过程封装起来,就是创建型模式。

    《设计模式》中的描述:
    创建型模式抽象了实例化过程。它们帮助一个系统独立于如何创建、组合和表示它的那些对象。
    一个类----创建型模式使用继承改变被实例化的类,
    一个对象-创建型模式将实例化委托给另一个对象。
    (看后,一头雾水)

    工厂模式(Factory Pattern)
    抽象工厂模式(Abstract Factory Pattern)
    单例模式(Singleton Pattern)
    建造者模式(Builder Pattern)
    原型模式(Prototype Pattern)

    2 结构型模式

    本人理解:创建型模式关注一个类或对象的实例化;结构型模式关注多个类或对象组合成更复杂的对象,是为了更灵活的构造对象。

    《设计模式》中的描述:结构性模式涉及到如何组合类和对象以获得更大的结构。
    结构型类----模式采用继承机制来组合接口和实现。
    结构型对象-模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能的一些方法。
    (看后,一头雾水)

    适配器模式(Adapter Pattern)
    桥接模式(Bridge Pattern)
    过滤器模式(Filter、Criteria Pattern)
    组合模式(Composite Pattern)
    装饰器模式(Decorator Pattern)
    外观模式(Facade Pattern)
    享元模式(Flyweight Pattern)
    代理模式(Proxy Pattern)

    3 行为型模式

    本人理解:上述两种模式都是出于一定目的(复用代码、修改时更灵活、容易维护等等)创建对象,对象之间一通信,一个程序就跑起来啦,把对象之间通信这部分,再总结总结,起个名字,就叫“行为型模式”。

    《设计模式》中的描述:行为模式涉及到算法和对象间职责的分配。
    行为模式不仅描述对象和类的模式,还描述它们之间的通信模式。
    行为模式使用继承机制在类间分派行为。(还是一头雾水)

    责任链模式(Chain of Responsibility Pattern)
    命令模式(Command Pattern)
    解释器模式(Interpreter Pattern)
    迭代器模式(Iterator Pattern)
    中介者模式(Mediator Pattern)
    备忘录模式(Memento Pattern)
    观察者模式(Observer Pattern)
    状态模式(State Pattern)
    空对象模式(Null Object Pattern)
    策略模式(Strategy Pattern)
    模板模式(Template Pattern)
    访问者模式(Visitor Pattern)

    各个模式之间的关系图

    参见《设计模式》第8页
    在这里插入图片描述

    设计模式的六大原则

    1、开闭原则(Open Close Principle)

    本人理解:增加新功能时,重新定义一个接口(开),不要修改原来的接口(闭)(为了向下兼容,如果修改了,可能对已经使用这个接口的代码造成影响)。

    开闭原则的意思是:对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。

    2、里氏代换原则(Liskov Substitution Principle)
    本人理解:子类包括基类的全部功能。

    里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

    3、依赖倒转原则(Dependence Inversion Principle)

    这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。

    4、接口隔离原则(Interface Segregation Principle)

    这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。

    5、迪米特法则,又称最少知道原则(Demeter Principle)

    最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。

    6、合成复用原则(Composite Reuse Principle)

    合成复用原则是指:尽量使用合成/聚合的方式,而不是使用继承

    展开全文
  • 具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册模式结构行为型模式(三
  • 行为型模式 模板模式、策略模式、状态模式、观察者模式、备忘录模式

      本系列文章共分为六篇:
        设计模式(一)设计模式的分类与区别
        设计模式(二)创建型模式介绍及实例
        设计模式(三)结构型模式介绍及实例
        设计模式(四)行为型模式介绍及实例(上)
        设计模式(五)行为型模式介绍及实例(下)
        设计模式(六)设计模式的常见应用

      上篇文件介绍了结构型模式,本篇将介绍行为型模式。行为型模式的主要关注点是“描述类或对象之间怎样通信、协作共同完成任务,以及怎样分配职责”。因为行为型模式较多,分成上下两篇来介绍。

    一、模板模式

    1.1 模板模式定义

      定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。

    一句话总结:父类定义固定的框架和公共部分,子类实现可变部分/步骤。

    1.2 模板模式特点

    优点

    1. 封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
    2. 在父类中提取了公共的部分代码,便于代码复用。
    3. 部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。

    缺点

    1. 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
    2. 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。

    1.3 模板模式主要角色

      模板方法模式UML图示:

    1. 抽象类
       负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。这些方法的定义如下:
        模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。为了防止恶意的操作,一般模板方法都加上final关键字,不允许被覆写
        基本方法:是整个算法中的一个步骤,包含以下几种类型:

    1>抽象方法:在抽象类中申明,由具体子类实现。
    2>具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它。
    3>钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。

    1. 具体子类
       实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的一个组成步骤。

    1.4 模板模式实现方式

      此处,以两个人张三和李四上班为例,主要涉及三个部分:起床、吃早饭、乘坐交通工具去上班,起床是公共方法,吃早饭可以推迟到之类,乘什么样的交通工具可以用钩子方法来判别。示例代码如下:

    /*抽象类*/
    abstract class Worker {
        public void WorkerWay() {
        	getUp();
            haveBreakfast();
            if(!haveCar()){
                takeBus();  
            }else{
            	drive();
            }
        }  
        /*具体方法*/
        public void getUp() {
            System.out.println("起床");
        }
        public void takeBus(){
        	System.out.println("坐公交上班");
        }
        public void drive(){
        	System.out.println("开车上班");
        }
        /*钩子方法*/
        public boolean haveCar(){   return true;   }
        /*抽象方法*/
        public abstract void haveBreakfast();  
    }
    /*具体子类:张三*/
    public class Zhangsan extends Worker{
    	@Override
    	public void haveBreakfast() {
    		System.out.println("吃三明治、喝牛奶");
    	}
        public boolean haveCar(){   return false;   }
    }
    /*具体子类:李四*/
    public class Lisi extends Worker{
    	@Override
    	public void haveBreakfast() {
    		System.out.println("吃包子、喝豆浆");
    	}
        public boolean haveCar(){     return true;   }
    }
    /*测试类*/
    public class TemplateTest {
    	public static void main(String[] args) { 
    		Zhangsan zhangsan =new Zhangsan();
    		System.out.println("张三的上班方式:");
    		zhangsan.WorkerWay();
    		Lisi lisi =new Lisi();
    		System.out.println("李四的上班方式:");
    		lisi.WorkerWay();		
    	}
    }
    

      结果如下:

    张三的上班方式:
    起床
    吃三明治、喝牛奶
    开车上班
    李四的上班方式:
    起床
    吃包子、喝豆浆
    坐公交上班

    1.5 模板模式应用场景

    1. 算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。
    2. 当多个子类存在公共的行为时,可以将其提取出来并集中到一个公共父类中以避免代码重复。首先,要识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
    3. 当需要控制子类的扩展时,模板方法只在特定点调用钩子操作,这样就只允许在这些点进行扩展。
    4. 重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数(见“模板方法模式的扩展”)约束其行为。

    二、策略模式

    2.1 策略模式定义

      该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。

    一句话总结:有多种算法,供客户端替换使用。

    2.2 策略模式主要角色

      策略模式的UML类图如下:

      Strategy类,定义所有支持的算法的公共接口;ConcreteStrategy类,封装了具体的算法或行为;Context,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用。

      注意事项:具体策略数量超过 4 个,则需要考虑使用混合模式。

    2.3 策略模式特点

    优点

    1. 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句。策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
    2. 可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。
    3. 提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。
    4. 把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。

    缺点

    1. 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
    2. 策略模式造成很多的策略类。

    2.4 策略模式实现方式

      此处,以小明做饭为例,当他想吃面时,做了一份臊子面;想吃饭时,做了一份炒饭。示例代码如下:

    /*抽象策略*/
    public interface  Cook {
    	 public void cooking(); 
    }
    /*具体策略:做面*/
    public class NoodleCook implements Cook{
    	public void cooking() {
    		System.out.println("做了一份臊子面");
    	}
    }
    /*具体策略:做饭*/
    public class RiceCook implements Cook{
    	public void cooking() {
    		System.out.println("做了一份炒饭");
    	}
    }
    /*环境类*/
    public class Context {
        private Cook cook;
        public Cook getCook(){    return cook;   }
        public void setCook(Cook cook){
            this.cook=cook;
        }
        public void cooking(){
        	cook.cooking();
        }
    }
    /*测试类*/
    public class StrategyTest {
    	public static void main(String[] args) { 
    		Context context = new Context();
    		System.out.println("小明要吃面");
    		Cook cook = new NoodleCook();
    		context.setCook(cook);
    		context.cooking();
    		System.out.println("小明要吃饭");
    		cook = new RiceCook();
    		context.setCook(cook);
    		context.cooking();
    	}
    }
    

      结果如下:

    小明要吃面
    做了一份臊子面
    小明要吃饭
    做了一份炒饭

    2.5 策略模式应用场景

    1. 一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中。
    2. 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句。
    3. 系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时。
    4. 系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构。
    5. 多个类的区别仅仅在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为
    6. 算法需要自由切换的场景。

    三、状态模式

    3.1 状态模式定义

      对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

    一句话总结:对象的行为依赖于其状态,将状态提取为对象,降低对象之间的耦合。

    3.2 状态模式主要角色

      状态模式UML图示如下:

      State类是抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。
      ConcreteState是具体的状态类,每一个子类实现一个与Context的一个状态相关的行为。
      Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态。

    3.3 状态模式特点

    优点

    1. 状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。
    2. 减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。
    3. 有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。

    缺点

    1. 状态模式的使用必然会增加系统的类与对象的个数。
    2. 状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。

    3.4 状态模式实现方式

      此处,以档位切换为例,某个开关有3个档位,且遵从高 --> 中 --> 低 --> 高的切换方式。示例代码如下:

    /*抽象状态*/
    public abstract class Switch {
    	public abstract void setPre(Context context);
    	public abstract void setNext(Context context);
    }
    /*具体状态1:低档位*/
    public class LowSwitch extends Switch{
    	@Override
    	public void setPre(Context context) {
            System.out.println("当前是低档位,向前切换为中档位");
            context.setSwitch(new MiddSwitch());
    	}
    	@Override
    	public void setNext(Context context) {
            System.out.println("当前是低档位,向后切换为高档位");
            context.setSwitch(new HighSwitch());
    	}
    	@Override
    	public String toString() {    return "低档位";  }
    }
    /*具体状态2:中档位*/
    public class MiddSwitch extends Switch{
    	@Override
    	public void setPre(Context context) {
            System.out.println("当前是中档位,向前切换为高档位");
            context.setSwitch(new HighSwitch());
    	}
    	@Override
    	public void setNext(Context context) {
            System.out.println("当前是中档位,向后切换为低档位");
            context.setSwitch(new LowSwitch());
    	}
    }
    /*具体状态3:高档位*/
    public class HighSwitch extends Switch{
    	@Override
    	public void setPre(Context context) {
            System.out.println("当前是高档位,向前切换为低档位");
            context.setSwitch(new LowSwitch());
    	}
    	@Override
    	public void setNext(Context context) {
            System.out.println("当前是高档位,,向后切换为中档位");
            context.setSwitch(new MiddSwitch());
    	}
    }
    /*环境类*/
    public class Context {
        private Switch switch1;
        //定义环境类的初始状态
        public Context(){
            this.switch1 = new LowSwitch();
        }
        //设置档位
        public void setSwitch(Switch sw){
            switch1 = sw;
        }
        //读取档位
        public Switch getSwitch(){
        	System.out.println("当前档位是:"+switch1.toString());
            return(switch1);
        }
        //往前设置一个档位
        public void setPre(){
        	switch1.setPre(this);
        }
        //往后设置一个档位
        public void setNext(){
        	switch1.setNext(this);
        }
    }
    /*测试类*/
    public class SwtichTest {
        public static void main(String[] args){
            Context context=new Context();    //创建环境       
            context.getSwitch();    //处理请求
            context.setPre();
            context.setPre();
            context.setNext();
        }
    }
    

      结果如下:

    当前档位是:低档位
    当前是低档位,向前切换为中档位
    当前是中档位,向前切换为高档位
    当前是高档位,,向后切换为中档位

    3.5 状态模式应用场景

    1. 一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,就可以考虑使用状态模式。即行为随状态改变而改变的场景,这也是状态模式的根本出发点,例如权限设计,人员的状态不同即使执行相同的行为结果也会不同,在这种情况下需要考虑使用状态模式。
    2. 一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态时。
    3. 条件、分支判断语句的替代者。

      注意:状态模式适用于当某个对象在它的状态发生改变时,它的行为也随着发生比较大的变化,也就是说在行为受状态约束的情况下可以使用状态模式,而且使用时对象的状态最好不要超过 5 个。

    四、观察者模式

    4.1 观察者模式定义

      指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。
      在实际环境中,观察者常常和责任链模式一起使用,共同负责对事件的处理,其中某个观察者负责是否将事件进一步传递
      在实际运用中,通知观察者的参数,往往可以封装成一个类,比如封装成一个事件(Event),示例:按键事件,从Event中往往可以获取到被观察者。

    一句话总结:一个对象变化了,要通知到别的对象,以便处理这种变化。

    4.2 观察者模式主要角色

      观察者模式UML图示如下:

      Subject类,抽象通知者(或主题),一个办用一个抽象类或一个接口实现。它把所有对观察者对象的引用保存在一个集合里,每个主题都可以有任何数量的观察者。主题中至少应包含三类方法:添加观察者、删除观察者和通知。
      Observer类,抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,重选ing观察者一般用一个抽象类或一个接口实现。
      ConcreteSubject类,叫做具体主题或具体通知者,将有关状态存入具体观察者对象。在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题通常用一个具体子类实现。
      ConcreteObserver类,具体观察者,实现抽象观察者角色所要求的的更新接口,以便使本身的状态和主体的状态相协调。具体观察者角色通常用一个具体子类实现。

    4.3 观察者模式特点

    优点

    1. 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
    2. 目标与观察者之间建立了一套触发机制。

    缺点

    1. 目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。
    2. 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。

      观察者比较多,而且处理时间比较长,采用异步处理来考虑线程安全和队列的问题。

    4.4 观察者模式实现方式

      此处,以小明追小说为例,有两本小说《剑来》和《英雄志》都未完结,他关注了这两部小说,当则两部小说更新时,他都会收到对应的消息。代码示例如下:

    /*抽象主题:小说*/
    public abstract  class Story {
    	 protected List<Observer> observers=new ArrayList<Observer>();
    	    //增加观察者方法
    	    public void add(Observer observer){
    	        observers.add(observer);
    	    }    
    	    //删除观察者方法
    	    public void remove(Observer observer){
    	        observers.remove(observer);
    	    }   
    	    public abstract void notifyObserver(int chapterNum); //通知观察者方法
    }
    /*具体主题1:剑来*/
    public class Story1 extends Story{
    	private String name = "jianlai";
        public void notifyObserver(int chapterNum){       
            for(Object obs:observers){
                ((Observer)obs).response(this.name,chapterNum);
            }
        }
    }
    /*具体主题2:英雄志*/
    public class Story2 extends Story{
    	private String name = "yingxiongzhi";
        public void notifyObserver(int chapterNum){      
            for(Object obs:observers){
                ((Observer)obs).response(this.name,chapterNum);
            }
        }
    }
    /*抽象观察者*/
    public interface Observer {
    	void response(String storyName,int number);
    }
    /*具体观察者:小明*/
    public class ObserverXiaoming implements Observer{
        private String name = "小明";
    	public void response(String storyName,int chapterNum) {
    		if("jianlai".equals(storyName)){
    			System.out.println("《剑来》更新了"+chapterNum+"章,"+this.name+"等养肥了在看");
    		}else{
    			System.out.println("《英雄志》更新了"+chapterNum+"章,"+this.name+"立马去看");
    		}
    	}
    }
    /*测试类*/
    public class ObserverTest {
        public static void main(String[] args){
        	Story story1=new Story1();  
        	Story story2=new Story2(); 
        	Observer observer=new ObserverXiaoming();           
        	story1.add(observer); 
        	story2.add(observer);           
        	story1.notifyObserver(20);
            story2.notifyObserver(10);
        }
    }
    

      示例结果如下:

    《剑来》更新了20章,小明等养肥了在看
    《英雄志》更新了10章,小明立马去看

    4.5 观察者模式应用场景

    1. 对象间存在一对多关系,一个对象的状态发生改变会影响其他对象
    2. 当一个抽象模型有两个方面,其中一个方面依赖于另一方面时,可将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
    3. 关联行为场景。需要注意的是,关联行为是可拆分的,而不是“组合”关系。
    4. 事件多级触发场景。
    5. 跨系统的消息交换场景,如消息队列的处理机制。

    五、备忘录模式

    5.1 备忘录模式定义

      在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式。

    一句话总结:可以保存和撤销对象的行为。

    5.2 备忘录模式主要角色

      备忘录模式UML图示如下:

      Originator(发起人):负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。Originator可根据需要决定Memento存储Originator的哪些内部状态。
      Memento(备忘录):负责存储Originator对象的内部状态,并可防止Originator以外的其他对象访问备忘录Memento。备忘录有两个接口:Caretaker只能看到备忘录的窄接口,它只能将备忘录传递给其他对象;Originator能看到一个宽接口,允许它返回到先前状态所需的所有数据。
      Caretaker(管理者):负责保存好备忘录Memento,不能对备忘录的内容进行操作或检查。

      注意:

    1. 备忘录的生命期;
    2. 备忘录的性能,不要在频繁建立备份的场景中使用备忘录模式(比如一个 for 循环中)。

    5.3 备忘录模式特点

    优点

    1. 提供了一种可以恢复状态的机制。当用户需要时能够比较方便地将数据恢复到某个历史的状态。
    2. 实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。
    3. 简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。

    缺点

    1. 资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。

    5.4 备忘录模式实现方式

      此处,以小亮周末做的一些事情为例,如:上午健身、下午和朋友聚餐、晚上看小说为例,用备忘录来记住他周末一天做的事,示例代码如下:

    /*备忘录*/
    public class Memento {
        private String state;
        public Memento(String state) {
            this.state = state;
        }
        public String getState() {   return state;   }
    }
    /*发起人:小亮*/
    public class OriginatorXiaoliang {
        private String state;
        public String getState() {    return state;  }
        public void setState(String state) {
            this.state = state;
        }
        public Memento saveStateToMemento(){    return new Memento(state);  }
        public void getStateFromMemento(Memento memento){
            state = memento.getState();
        }
    }
    /*管理者*/
    public class CareTaker {
        private List<Memento> mementoList = new ArrayList<Memento>();
        public void add(Memento memento){
            mementoList.add(memento);
        }
        public Memento get(int index){    return mementoList.get(index);  }
    }
    /*测试类*/
    public class MementoTest {
        public static void main(String[] args) {
        	OriginatorXiaoliang xiaoliang = new OriginatorXiaoliang();
            CareTaker careTaker = new CareTaker();
            xiaoliang.setState("健身");
            careTaker.add(xiaoliang.saveStateToMemento());
            xiaoliang.setState("和朋友聚会");
            careTaker.add(xiaoliang.saveStateToMemento());
            xiaoliang.setState("看小说");
            System.out.println("小亮晚上做的事: " + xiaoliang.getState());
            xiaoliang.getStateFromMemento(careTaker.get(0));
            System.out.println("小亮上午做的事: " + xiaoliang.getState());
            xiaoliang.getStateFromMemento(careTaker.get(1));
            System.out.println("小亮下午做的事: " + xiaoliang.getState());
        }
    }
    

      测试结果:

    小亮晚上做的事: 看小说
    小亮上午做的事: 健身
    小亮下午做的事: 和朋友聚会

    5.5 备忘录模式应用场景

    1. 需要保存与恢复数据的场景,如玩游戏时的中间结果的存档功能。
    2. 需要提供一个可回滚操作的场景,如Word、记事本、Photoshop,Eclipse等软件在编辑时按Ctrl+Z组合键,还有数据库中事务操作。
    3. 数据库连接的事务管理就是用的备忘录模式。

      注意:

    • 1、备忘录的生命期
    • 2、备忘录的性能。不要在频繁建立备份的场景中使用备忘录模式(比如一个 for 循环中)。
    展开全文
  • 程序设计模式作业十二(行为型模式二)1
  • 设计模式之行为型模式(7种)

    千次阅读 2022-04-22 16:41:56
    目录 一、模版方法模式(template ) ...模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不...
  • 本课程重点介绍了十一种行为型模式:职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式。
  • 实验4、行为型模式应用实验(1)
  • 基于Python的行为型模式设计
  • 基于Python的行为型模式设计.pdf
  • 设计模式-行为型模式总结

    千次阅读 2017-07-27 20:50:56
    行为型模式行为型模式涉及到算法和对象间职责的分配。它不仅描述对象或者类的模式,还描述它们之间的通信模式。这些设计模式刻画了在运行难以跟踪的复杂的控制流。它们将你的注意力从控制流转移到对象之间的联系...
  • Java经典设计模式共有21中,分为三大类:创建型模式(5种)、结构型模式(7种)和行为型模式(11种)。本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:J设计模式之五大创建型模式(附实例...
  • 设计模式-对象行为型模式

    千次阅读 2018-04-19 19:24:03
    【对象行为型模式】涉及到算法和对象间职责的分配,描述了对象和类的模式,以及它们之间的通信模式。 用来对类或对象怎样交互和怎样分配职责进行描述 1、 策略模式(strategy) 是指定义一系列的算法,把它们一个...
  • 行为型模式讲义

    2016-09-23 23:32:13
    GoF的行为型模式讲义
  • 在这里与各位分享本人从网络上下载的C#面向对象设计模式纵横谈系列视频,共有25节,除了第一节需要各位贡献一点资源分以作为对本人上传资源的回馈,后面的其他资源均不需要... 这是第15节:行为型模式Command命令模式
  • 总体来说设计模式分为三大类:...3、行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 1、创建型模式 软
  • 行为型模式

    千次阅读 2022-08-06 11:44:34
    本篇是我们设计模式的第四章节,还是对行为型模式进行讲解主要讲解:模板方法模式、观察者模式、策略模式、责任链模式。并对于每一个模式进行概念、例子、uml 以及应用场景等进行说明。希望对读者有所帮助.............
  • 软件设计模式,行为型模式:ChainOf Responsibility Command Interpreter Iterator Mediator Memento Observer State Strategy Template method Visitor
  • 设计模式——行为型模式

    千次阅读 2019-04-23 21:47:51
    1. 策略模式(Strategy) 2.状态模式(State) 3.责任链模式(Chain Of Responsibility) 4.解释器模式(Interpreter) 5.命令模式(Command) 6.观察者模式(Observer) 7.备忘录模式(Memento) 8.迭代器模式...
  • 在这里与各位分享本人从网络上下载的C#面向对象设计模式纵横谈系列视频,共有25节,除了第一节需要各位贡献一点资源分以作为对本人上传资源的回馈,后面的其他资源均不... 这是第18节:行为型模式Iterator迭代器模式
  • 设计模式-行为型模式

    千次阅读 2017-12-30 18:30:51
    原文地址:http://blog.csdn.net/column/details/pattern.html?&page=1行为型模式 模版方法模式 策略模式 状态模式 命令模式 迭代器模式 备忘录模式 观察者模式 中介者模式 访问者模式 责任链模式 解释器模式 模版...
  • 设计模式Part3——行为型模式

    千次阅读 2021-11-17 08:29:01
    行为型模式用于描述程序在运行时复杂的流程控制,即描述对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,是一种微观关系的体现。行为型模式包括:第一组(观察者模式、模板方法、命令模式、状态模式、...
  • 行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式: 类行为模式:...
  • 行为型模式
  • C#面向对象设计模式纵横谈(18):(行为型模式) Iterator 迭代器模式

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 294,152
精华内容 117,660
关键字:

行为型模式