akka设计模式系列-Chain模式
链式调用在很多框架和系统中经常存在,算不得上是我自己总结的设计模式,此处只是简单介绍在Akka中的两种实现方式。我在这边博客中简化了链式调用的场景,简化后也更符合Akka的设计哲学。
trait Chained{
def receive:Receive = Actor.emptyBehavior
}
trait IntReceiveChained1 extends Chained{
override def receive:Receive = super.receive orElse {
case i:Int => println(s"IntReceiveChained1 receive Int $i")
}
}
trait IntReceiveChained extends Chained{
override def receive:Receive = super.receive orElse {
case i:Int => println(s"IntReceive receive Int $i")
}
}
trait StringReceiveChained extends Chained {
override def receive:Receive = super.receive orElse {
case i:Int => println(s"StringReceive receive Int $i")
case s:String => println(s"StringReceive receive String $s")
}
}
class ChainedActor extends Actor with IntReceiveChained with StringReceiveChained with IntReceiveChained1 {
override def receive:Receive = super.receive orElse {
case any =>
println(s"ChainingActor receive any $any")
}
}
object ChainingPattern1 {
def main(args: Array[String]): Unit = {
val system = ActorSystem("ChainingPattern1",ConfigFactory.load())
val chainingActor = system.actorOf(Props(new ChainedActor),"ChainedActor")
chainingActor ! 123
chainingActor ! "test"
}
}
输出:
IntReceive receive Int 123
StringReceive receive String test
上面这一种实现方式跟akka没有太大关系,是用scala的trait实现的。在类中调用多个Trait中都有的方法时,首先会从最右边的Trait的方法开始执行,然后依次向左执行,形成一个调用条。这个相当于设计模式中的责任链模式的一种具体实现依赖。只不过是用orElse来实现,以保证每种类型的消息都只被处理一次。我们也可以把orElse替换掉,根据条件判断是否继续调用后续函数,这个需要我们根据业务场景来选择,我就不再展开了。
trait Chaining { self => Actor
private var chainedReceives = List.empty[Receive]
def registerReceive( newReceive:Receive ): Unit = {
chainedReceives = newReceive :: chainedReceives
}
def receive:Receive = chainedReceives.reduce(_ orElse _)
}
trait IntReceive extends Chaining{
registerReceive{
case i:Int => println(s"IntReceive receive Int $i")
}
}
trait StringReceive extends Chaining {
registerReceive{
case s:String => println(s"StringReceive receive String $s")
}
}
class ChainingActor extends Actor with IntReceive with StringReceive{
}
object ChainingPattern2 {
def main(args: Array[String]): Unit = {
val system = ActorSystem("ChainingPattern2",ConfigFactory.load())
val chainingActor = system.actorOf(Props(new ChainingActor),"chainingActor")
chainingActor ! 123
chainingActor ! "test"
}
}
输出:
IntReceive receive Int 123
StringReceive receive String test
这种实现方式是将Receive函数注册到一个列表中,通过reduce把处理函数orElse串起来。与第一种方式一样,对相同的类型也都是只匹配一次。此处只是为了简化设计模式的介绍,读者也都可以根据需求修改对chainedReceives的处理方式,比如所有函数都匹配一遍,或者根据业务条件选择性的匹配。
Akka的Chain模式并不常用,但非常有用。有了它,我们就可以自由组合对消息的处理过程了。如果某个receive需要对大量的消息进行处理,我们可以对消息进行分类,创建不同的链式函数去匹配处理,可以做到高内聚低耦合的效果。
akka设计模式系列-Chain模式的更多相关文章
- akka设计模式系列-While模式
While模式严格来说是while循环在Akka中的合理实现.while是开发过程中经常用到的语句之一,也是绝大部分编程语言都支持的语法.但while语句是一个循环,如果循环条件没有达到会一直执行wh ...
- akka设计模式系列-Backend模式
上一节我们介绍了Akka使用的基本模式,简单点来说就是,发消息给actor,处理结束后返回消息.但这种模式有个缺陷,就是一旦某个消息处理的比较慢,就会阻塞后面所有消息的处理.那么有没有方法规避这种阻塞 ...
- akka设计模式系列-Aggregate模式
所谓的Aggregate模式,其实就是聚合模式,跟masterWorker模式有点类似,但其出发点不同.masterWorker模式是指master向worker发送命令,worker完成某种业务逻辑 ...
- akka设计模式系列-基础模式
本文介绍akka的基本使用方法,由于属于基础功能,想不出一个很高大上的名称,此处就以基础模式命名.下文会介绍actor的使用方法,及其优劣点. class SimpleActor(name:Strin ...
- akka设计模式系列-慎用ask
慎用ask应该是Akka设计的一个准则,很多时候我们应该禁用ask.之所以单独把ask拎出来作为一篇博文,主要是akka的初学者往往对ask的使用比较疑惑. "Using ask will ...
- akka设计模式系列-消息模型(续)
在之前的akka设计模式系列-消息模型中,我们介绍了akka的消息设计方案,但随着实践的深入,发现了一些问题,这里重新梳理一下设计方法,避免之前的错误.不当的观点给大家带来误解. 命令和事件 我们仍然 ...
- akka设计模式系列
由于本人爱好Scala,顺便也就爱好Akka,但目前网上对Akka的介绍大多都是概念上或技术方向上的介绍,基本没有Akka设计模式或者Actor模型设计模式的资料.这对于Akka的普及非常不利,因为即 ...
- PHP设计模式系列 - 外观模式
外观模式 通过在必需的逻辑和方法的集合前创建简单的外观接口,外观设计模式隐藏了调用对象的复杂性. 外观设计模式和建造者模式非常相似,建造者模式一般是简化对象的调用的复杂性,外观模式一般是简化含有很多逻 ...
- akka设计模式系列-actor锚定
actor锚定模式是指使用actorSelection对acor进行锚定的设计模式,也可以说是一个对actor的引用技巧.在某些情况下,我们可能需要能够根据Actor的path锚定对应的实例.简单来说 ...
随机推荐
- [BOI2008]Elect 选举
背包. #include <algorithm> #include <iostream> #include <cstdlib> #include <cstri ...
- Ubuntu下安装oh-my-zsh
本文参考 https://www.jianshu.com/p/9a5c4cb0452d 此文已在ubuntu下确实安装成功,只不过懒得截图了,可以参照上述地址,我在他原基础上进行了一些更改. 安装Oh ...
- hdu 5122(2014ACM/ICPC亚洲区北京站) K题 K.Bro Sorting
传送门 对于错想成lis的解法,提供一组反例 1 3 4 2 5同时对于这次案例也可以观察出解法:对于每一个数,如果存在比它小的数在它后面,它势必需要移动,因为只能小的数无法向右移动,而且每一次移动都 ...
- Spring核心技术(二)——Spring的依赖及其注入
本文将继续前文,描述Spring IoC中的依赖处理. 依赖 一般情况下企业应用不会只有一个对象(或者是Spring Bean).甚至最简单的应用都要多个对象来协同工作来让终端用户看到一个完整的应用的 ...
- 校长的收藏(洛谷 U4534)
题目背景 XS中学的校长喜欢收集手办,家里面都是价值不菲的手办. 校长喜欢给手办们排队并且对于某些些区间内的手办喜爱有加. 现在,校长外出散步(找乐子),你潜入他的房间打算借(偷走)他的手办炫耀一下. ...
- Ubuntu 16.04安装Chrome浏览器
一.先有一个hosts能访问Google 参考:http://www.cnblogs.com/EasonJim/p/5999060.html 二.安装方法有两种,如下所示: 1.下载deb包(推荐) ...
- YAML/Properties配置文件与Spring Boot(转)
多年来,Java开发人员依赖于属性文件或xml文件来指定应用程序配置.在企业应用程序中,人们可以为每个环境(如开发,分段和生产)创建单独的文件,以定义相应环境的属性.但是,通过Spring引导,我们可 ...
- internalsviewer
https://intview2.codeplex.com/ https://internalsviewer.codeplex.com/releases/view/21139
- gh-ost: triggerless online schema migrations:Blog by Shlomi Noach:
http://code.openark.org/blog/category/mysql https://rj03hou.github.io/mysql/gh-ost/
- Apache配置基于域名的虚拟主机
一.设定 模拟域名 www.wang.org.blog.wang.org.bbs.wang.org 网站文件夹 /var/html/www./var/html/blog./var/html/bbs ...