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锚定对应的实例.简单来说 ...
随机推荐
- Linux 应用总结:自动删除n天前的日志
linux是一个很能自动产生文件的系统,日志.邮件.备份等.虽然现在硬盘廉价,我们可以有很多硬盘空间供这些文件浪费,让系统定时清理一些不需要的文件很有一种爽快的事情.不用你去每天惦记着是否需要清理日志 ...
- HDU - 6446 Tree and Permutation
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6446 本题是一个树上的问题——DFS. 一棵N个结点的树,其结点为1~N.树具有N-1条边,每一条边具有 ...
- Linux学习总结(18)——Linux使用init命令关机、重启、切换模式
reboot可能是每个用过Linux的人都知道的命令,但有一个命令"init"才是命令中的精英. 最近有个同事学习安装了CentOS,明明安装的是带桌面的系统,但是启动后进入了命令 ...
- image url to base64
image url to base64 https://www.base64-image.de/ https://www.browserling.com/tools/image-to-base64 h ...
- POJ 2115 简单的模线性方程求解
简单的扩展欧几里得题 这里 2^k 不能自作聪明的用 1<<k来写 , k >= 31时就爆int了 , 即使定义为long long 也不能直接这样写 后来老老实实 for(int ...
- S - Arc of Dream 矩阵快速幂
An Arc of Dream is a curve defined by following function: where a 0 = A0 a i = a i-1*AX+AY b 0 = B0 ...
- 对象和变量的并发访问synchronized解析以及死锁分析排查
一.synchronized java并发编程中存在“非线程安全"问题.“非线程安全"是指发生在多个线程对同一个对象中的实例变量并发访问时,产生的”脏读“现象,使用synchron ...
- 一篮子苹果,每天吃一半多一个吃,第十天吃一半多一个后就剩余一个,求一共多少个苹果,JAVA版
/** * @author xuzhu **/public class TestApple { public static void main(String[] args) { int days = ...
- 18、Java并发性和多线程-饥饿与公平
以下内容转自http://ifeve.com/starvation-and-fairness/: 如果一个线程因为CPU时间全部被其他线程抢走而得不到CPU运行时间,这种状态被称之为“饥饿”.而该线程 ...
- bridge 上网
手头有一台机器上有一个虚拟机 虚拟机为桥接 本机为静态IP上网 想让虚拟机上网的方式是 本机不设ip 网卡设置DHCP. 虚拟机设置静态ip