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锚定对应的实例.简单来说 ...
随机推荐
- 洛谷 4302 BZOJ 1090 SCOI2003 字符串折叠 UVA1630 Folding(输出方案版)
[题解] 区间DP. 设f[i][j]表示i~j的最小代价.再枚举中间点k,很容易想到转移方程为f[i][j]=min(f[i][j],f[i][k]+f[k][j]),同时如果i~k可以通过重复获 ...
- BZOJ 1827 洛谷 2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gather
[题解] 很容易想到暴力做法,枚举每个点,然后对于每个点O(N)遍历整棵树计算答案.这样整个效率是O(N^2)的,显然不行. 我们考虑如果已知当前某个点的答案,如何快速计算它的儿子的答案. 显然选择它 ...
- openstack windows2012r2 glance镜像制作
镜像实现: 密码注入 修改密码 根分区扩展 1.下载windows iso镜像 下载地址:http://imsdn.com/MSDN-1.html 例如:cn_windows_server_2012_ ...
- Leetcode 22.生成括号对数
生成括号对数 给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n =3,生成结果为: [ "((()))", "( ...
- poj 3253 Fence Repair(priority_queue)
Fence Repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 40465 Accepted: 13229 De ...
- Android BottomSheet:便捷易用的底部滑出面板(1)
Android BottomSheet:便捷易用的底部滑出面板(1) Android BottomSheet是github上的一个第三方开源项目,其主页:https://github.com/Flip ...
- 47. Spring Boot发送邮件【从零开始学Spring Boot】
(提供源代码) Spring提供了非常好用的JavaMailSender接口实现邮件发送.在Spring Boot的Starter模块中也为此提供了自动化配置.下面通过实例看看如何在Spring Bo ...
- 438D - The Child and Sequence
D. The Child and Sequence time limit per test 4 seconds memory limit per test 256 megabytes input st ...
- python之MD5、base64\base32解密
# -*- coding:utf-8 -*- import hashlib import base64 # 求最大公约数gys # def gys(m, n): # c = 1 # while(c ! ...
- tyvj1271 零式求和
描述 请考虑一个由1到N(N=3, 4, 5 ... 9)的数字组成的递增数列:1 2 3 ... N.现在请在数列中插入“+”表示加,或者“-”表示减,抑或是“ ”表示空白(例如1-2 3就等于1- ...