设计模式之行为型模式

3、应用场景:

①、一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中。

②、一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句。

③、系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时。

系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构。

④、多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为。

4、优点:

①、多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句,如 if…else 语句、switch…case 语句。

②、策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。

③、策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。

④、策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。

⑤、策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。

5、缺点:

①、客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。

②、策略模式造成很多的策略类,增加维护难度。

命令模式

1、概述:

将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。

2、主要角色:

①、抽象命令类(Command)角色:声明执行命令的接口,拥有执行命令的抽象方法 execute()。

②、具体命令类(Concrete Command)角色:是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。

③、实现者/接收者(Receiver)角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者。

④、调用者/请求者(Invoker)角色:是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。

3、应用场景:

①、请求调用者需要与请求接收者解耦时,命令模式可以使调用者和接收者不直接交互。

②、系统随机请求命令或经常增加、删除命令时,命令模式可以方便地实现这些功能。

③、当系统需要执行一组操作时,命令模式可以定义宏命令来实现该功能。

④、当系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作时,可以将命令对象存储起来,采用备忘录模式来实现。

4、优点:

①、通过引入中间件(抽象接口)降低系统的耦合度。

②、扩展性良好,增加或删除命令非常方便。采用命令模式增加与删除命令不会影响其他类,且满足“开闭原则”。

③、可以实现宏命令。命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令。

④、方便实现 Undo 和 Redo 操作。命令模式可以与后面介绍的备忘录模式结合,实现命令的撤销与恢复。

⑤、可以在现有命令的基础上,增加额外功能。比如日志记录,结合装饰器模式会更加灵活。

5、缺点:

①、可能产生大量具体的命令类。因为每一个具体操作都需要设计一个具体命令类,这会增加系统的复杂性。

②、命令模式的结果其实就是接收方的执行结果,但是为了以命令的形式进行架构、解耦请求与实现,引入了额外类型结构(引入了请求方与抽象命令接口),增加了理解上的困难。不过这也是设计模式的通病,抽象必然会额外增加类的数量,代码抽离肯定比代码聚合更加难理解。

责任链模式

1、概述:

为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。注意:责任链模式也叫职责链模式。

2、主要角色:

①、抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。

②、具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。

③、客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

3、应用场景:

①、多个对象可以处理一个请求,但具体由哪个对象处理该请求在运行时自动确定。

②、可动态指定一组对象处理请求,或添加新的处理者。

③、需要在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求。

4、优点:

①、降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。

②、增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则。

③、增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。

④、责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。

⑤、责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。

5、缺点:

①、不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。

②、对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。

③、职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。

状态模式

1**、概述:**

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

2、主要角色:

①、环境类(Context)角色:也称为上下文,它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。

②、抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。

③、具体状态(Concrete State)角色:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。

3、应用场景:

①、当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,就可以考虑使用状态模式。

②、一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态时。

4、优点:

①、结构清晰,状态模式将与特定状态相关的行为局部化到一个状态中,并且将

②、不同状态的行为分割开来,满足“单一职责原则”。

③、将状态转换显示化,减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。

④、状态类职责明确,有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。

5、缺点:

①、状态模式的使用必然会增加系统的类与对象的个数。

②、状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。

③、状态模式对开闭原则的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源码,否则无法切换到新增状态,而且修改某个状态类的行为也需要修改对应类的源码。

观察者模式

1、概述:

指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。

2、主要角色:

①、抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。

②、具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。

③、抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。

④、具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。

3、应用场景:

①、对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。

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

③、实现类似广播机制的功能,不需要知道具体收听者,只需分发广播,系统中感兴趣的对象会自动接收该广播。

④、多层级嵌套使用,形成一种链式触发机制,使得事件具备跨域(跨越两种观察者类型)通知。

4、优点:

①、降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。符合依赖倒置原则。

②、目标与观察者之间建立了一套触发机制。

5、缺点:

①、目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。

②、当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。

中介者模式

1、概述:

定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。

2、主要角色:

①、抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。

②、具体中介者(Concrete Mediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。

③、抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。

④、具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。

3、应用场景:

①、当对象之间存在复杂的网状结构关系而导致依赖关系混乱且难以复用时。

②、当想创建一个运行于多个类之间的对象,又不想生成新的子类时。

4、优点:

①、类之间各司其职,符合迪米特法则。

②、降低了对象之间的耦合性,使得对象易于独立地被复用。

③、将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。

5、缺点:

中介者模式将原本多个对象直接的相互依赖变成了中介者和多个同事类的依赖关系。当同事类越多时,中介者就会越臃肿,变得复杂且难以维护。

迭代器模式

1、概述:

提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。迭代器模式是一种对象行为型模式,其主要优点如下。

2、主要角色:

①、抽象聚合(Aggregate)角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。

②、具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。

③、抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。

④、具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。

3、应用场景:

①、当需要为聚合对象提供多种遍历方式时。

②、当需要为遍历不同的聚合结构提供一个统一的接口时。

③、当访问一个聚合对象的内容而无须暴露其内部细节的表示时。

4、优点:

①、访问一个聚合对象的内容而无须暴露它的内部表示。

②、遍历任务交由迭代器完成,这简化了聚合类。

③、它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。

④、增加新的聚合类和迭代器类都很方便,无须修改原有代码。

封装性良好,为遍历不同的聚合结构提供一个统一的接口。

5、缺点:

增加了类的个数,这在一定程度上增加了系统的复杂性。

访问者模式

1、概述:

将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。

2、主要角色:

①、抽象访问者(Visitor)角色:定义一个访问具体元素的接口,为每个具体元素类对应一个访问操作 visit() ,该操作中的参数类型标识了被访问的具体元素。

②、具体访问者(ConcreteVisitor)角色:实现抽象访问者角色中声明的各个访问操作,确定访问者访问一个元素时该做什么。

③、抽象元素(Element)角色:声明一个包含接受操作 accept() 的接口,被接受的访问者对象作为 accept() 方法的参数。

④、具体元素(ConcreteElement)角色:实现抽象元素角色提供的 accept() 操作,其方法体通常都是 visitor.visit(this) ,另外具体元素中可能还包含本身业务逻辑的相关操作。

⑤、对象结构(Object Structure)角色:是一个包含元素角色的容器,提供让访问者对象遍历容器中的所有元素的方法,通常由 List、Set、Map 等聚合类实现。

3、应用场景:

①、对象结构相对稳定,但其操作算法经常变化的程序。

②、对象结构中的对象需要提供多种不同且不相关的操作,而且要避免让这些操作的变化影响对象的结构。

③、对象结构包含很多类型的对象,希望对这些对象实施一些依赖于其具体类型的操作。

4、优点:

①、扩展性好。能够在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能。

②、复用性好。可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用程度。

③、灵活性好。访问者模式将数据结构与作用于结构上的操作解耦,使得操作集合可相对自由地演化而不影响系统的数据结构。

④、符合单一职责原则。访问者模式把相关的行为封装在一起,构成一个访问者,使每一个访问者的功能都比较单一。

5、缺点:

①、增加新的元素类很困难。在访问者模式中,每增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作,这违背了“开闭原则”。

②、破坏封装。访问者模式中具体元素对访问者公布细节,这破坏了对象的封装性。

先自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以扫码领取!!!!

最后

分享一份NDK基础开发资料

详解:Linux网络虚拟化技术

分享内容包括不限于高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可免费领取!

[外链图片转存中…(img-eqVoGEkv-1711299476867)]

[外链图片转存中…(img-JvJxpXOm-1711299476867)]

[外链图片转存中…(img-m9h4KjFi-1711299476867)]

[外链图片转存中…(img-UsqIJ1TQ-1711299476868)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以扫码领取!!!!

最后

分享一份NDK基础开发资料

[外链图片转存中…(img-T8FJvdIu-1711299476868)]

分享内容包括不限于高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可免费领取!

  • 15
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值