设计模式——行为型模式
 除了模板方法模式和解释器模式是类行为型模式,其他的全部属于对象行为型模式,下面我们将详细介绍它们的特点、结构与应用。
 模板方法(Template Method)模式:
	定义:定义一个操作中的算法骨架,将算法的一些步骤延迟到子类中,使得子类在可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
	优点:
		它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
		它在父类中提取了公共的部分代码,便于代码复用。
		部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。
	缺点:
		对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
		父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。
	应用场景:例如,一个人每天会起床、吃饭、做事、睡觉等,其中“做事”的内容每天可能不同。我们把这些规定了流程或格式的实例定义成模板,允许使用者根据自己的需求去更新它
 策略(Strategy)模式:
	定义:定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的改变不会影响使用算法的客户。
	策略模式的主要优点如下:
		多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句。
		策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
		策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。
		策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。
		策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。
	其主要缺点如下:
		客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
		策略模式造成很多的策略类。
	应用场景:例如,出行旅游可以乘坐飞机、乘坐火车、骑自行车或自己开私家车等
 命令(Command)模式:
	定义:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。
	命令模式的主要优点如下。
		降低系统的耦合度。命令模式能将调用操作的对象与实现该操作的对象解耦。
		增加或删除命令非常方便。采用命令模式增加与删除命令不会影响其他类,它满足“开闭原则”,对扩展比较灵活。
		可以实现宏命令。命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令。
		方便实现 Undo 和 Redo 操作。命令模式可以与后面介绍的备忘录模式结合,实现命令的撤销与恢复。
	其缺点是:
		可能产生大量具体命令类。因为计对每一个具体操作都需要设计一个具体命令类,这将增加系统的复杂性。
	应用场景:例如,电视机遥控器(命令发送者)通过按钮(具体命令)来遥控电视机(命令接收者)
 职责链(Chain of Responsibility)模式:
	定义:把请求从链中的一个对象传到下一个对象,直到请求被响应为止。通过这种方式去除对象之间的耦合。
	责任链模式是一种对象行为型模式,其主要优点如下:
		降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。
		增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则。
		增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
		责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。
		责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。
	其主要缺点如下。
		不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。
		对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
		职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。
	通常情况下,可以通过【数据链表来实现职责链模式的数据结构】。
	应用场景:例如,公司员工请假,可批假的领导有部门负责人、副总经理、总经理等,但每个领导能批准的天数不同,员工必须根据自己要请假的天数去找不同的领导签名,
			  也就是说员工必须记住每个领导的姓名、电话和地址等信息,这增加了难度。
 状态(State)模式:
	定义:允许一个对象在其内部状态发生改变时改变其行为能力。
	状态模式是一种对象行为型模式,其主要优点如下。
		状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。
		减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。
		有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。
	状态模式的主要缺点如下。
		状态模式的使用必然会增加系统的类与对象的个数。
		状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。
 观察者(Observer)模式:
	定义:多个对象间存在一对多关系,当一个对象发生改变时,把这种改变通知给其他多个对象,从而影响其他对象的行为。
	观察者模式是一种对象行为型模式,其主要优点如下:
		降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
		目标与观察者之间建立了一套触发机制。
	它的主要缺点如下:
		目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。
		当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。
	应用场景:某种商品的物价上涨时会导致部分商家高兴,而消费者伤心;股票价格与股民、微信公众号与微信用户等。
 中介者(Mediator)模式:
	定义:定义一个中介对象来简化原有对象之间的交互关系,降低系统中对象间的耦合度,使原有对象之间不必相互了解。
	中介者模式是一种对象行为型模式,其主要优点如下:
		降低了对象之间的耦合性,使得对象易于独立地被复用。
		将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。
	其主要缺点是:
		当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护。
	应用场景:房屋中介,人才市场。
 迭代器(Iterator)模式:
	定义:提供一种方法来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。
	迭代器模式是一种对象行为型模式,其主要优点如下。
		访问一个聚合对象的内容而无须暴露它的内部表示。
		遍历任务交由迭代器完成,这简化了聚合类。
		它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。
		增加新的聚合类和迭代器类都很方便,无须修改原有代码。
		封装性良好,为遍历不同的聚合结构提供一个统一的接口。
	其主要缺点是:
		增加了类的个数,这在一定程度上增加了系统的复杂性。
 访问者(Visitor)模式:
	定义:在不改变集合元素的前提下,为一个集合中的每个元素提供多种访问方式,即每个元素有多个访问者对象访问。
	访问者(Visitor)模式是一种对象行为型模式,其主要优点如下。
		扩展性好。能够在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能。
		复用性好。可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用程度。
		灵活性好。访问者模式将数据结构与作用于结构上的操作解耦,使得操作集合可相对自由地演化而不影响系统的数据结构。
		符合单一职责原则。访问者模式把相关的行为封装在一起,构成一个访问者,使每一个访问者的功能都比较单一。
	访问者(Visitor)模式的主要缺点如下。
		增加新的元素类很困难。在访问者模式中,每增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作,这违背了“开闭原则”。
		破坏封装。访问者模式中具体元素对访问者公布细节,这破坏了对象的封装性。
		违反了依赖倒置原则。访问者模式依赖了具体类,而没有依赖抽象类。
	应用场景:例如,电影或电视剧中的人物角色,不同的观众对他们的评价也不同;
 备忘录(Memento)模式:
	定义:在不破坏封装性的前提下,获取并保存一个对象的内部状态,以便以后恢复它。
	备忘录模式是一种对象行为型模式,其主要优点如下。
		提供了一种可以恢复状态的机制。当用户需要时能够比较方便地将数据恢复到某个历史的状态。
		实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。
		简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。
	其主要缺点是:
		资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。
	应用场景:如 Word、记事本、Photoshop、Eclipse 等软件在编辑时按 Ctrl+Z 组合键时能撤销当前操作,使文档恢复到之前的状态;
 解释器(Interpreter)模式:
	定义:提供如何定义语言的文法,以及对语言句子的解释方法,即解释器。
	解释器模式是一种类行为型模式,其主要优点如下。
		扩展性好。由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来改变或扩展文法。
		容易实现。在语法树中的每个表达式节点类都是相似的,所以实现其文法较为容易。
	解释器模式的主要缺点如下。
		执行效率较低。解释器模式中通常使用大量的循环和递归调用,当要解释的句子较复杂时,其运行速度很慢,且代码的调试过程也比较麻烦。
		会引起类膨胀。解释器模式中的每条规则至少需要定义一个类,当包含的文法规则很多时,类的个数将急剧增加,导致系统难以管理与维护。
		可应用的场景比较少。在软件开发中,需要定义语言文法的应用实例非常少,所以这种模式很少被使用到。
	实现方式:解释器模式常用于对简单语言的编译或分析实例中,为了掌握好它的结构与实现,必须先了解【编译原理中的“文法、句子、语法树”】等相关概念。
                    
                
                
            
        
浙公网安备 33010602011771号