。 Receive
がの最終的なであるので、scala.PartialFunction
を構成できるすべてのメッセージを処理したい場合は、例えば:
Receive createReceive() {
return thenAccept(
receiveBuilder()
.match(Foo.class, this::processFoo)
.match(Bar.class, this::processBar)
.match(Bash.class, this::processBash)
.match(OtherThing.class, this::processOtherThing)
.build(),
this::doSomethingForAllMessages
);
}
<T> Receive thenAccept(Receive origin, FI.UnitApply<T> action) {
return new Receive(thenAccept(origin.onMessage(), action));
}
<A, B> PartialFunction<A, B> thenAccept(PartialFunction<A, B> fn,
FI.UnitApply<A> action) {
return Function.unlift(thenAccept(fn.lift(), action));
}
<A, B> Function1<A, Option<B>> thenAccept(Function1<A, Option<B>> fn,
FI.UnitApply<A> action) {
return it -> {
Option<B> value = fn.apply(it);
action.apply(it);
return value;
};
}
は場合は、あなたのニーズを達成するためにscala
APIを操作する必要はありません。なんらかの理由で、Function1
は、以前のバージョンのscala
の@FunctionalInterfaceではありません。 ReceiveBuilder
を作成することができます。例えば:
public Receive createReceive() {
return thenAccept(
receiveBuilder()
.match(Foo.class, this::processFoo)
.match(Bar.class, this::processBar)
.match(Bash.class, this::processBash)
.match(OtherThing.class, this::processOtherThing),
this::doSomethingForAllMessages
).build();
}
ReceiveBuilder thenAccept(ReceiveBuilder origin, FI.UnitApply<Object> action) {
return ReceiveBuilder.create().matchAny(allOf(
origin.build().onMessage()::apply,
action
));
}
FI.UnitApply<Object> allOf(FI.UnitApply<Object>... actions) {
return it -> {
for (FI.UnitApply<Object> action : actions) {
action.apply(it);
}
};
}
ORあなたはReceiveBuilder
を組み合わせることにより、セマンティクスの一貫性を保つことができます。 ReceiveBuilder
に属しているよう
public Receive createReceive() {
return both(
receiveBuilder()
.match(Foo.class, this::processFoo)
.match(Bar.class, this::processBar)
.match(Bash.class, this::processBash)
.match(OtherThing.class, this::processOtherThing),
receiveBuilder().matchAny(this::doSomethingForAllMessages)
).build();
}
ReceiveBuilder both(ReceiveBuilder left, ReceiveBuilder right) {
return ReceiveBuilder.create().matchAny(it -> Stream.of(left,right)
.map(ReceiveBuilder::build)
.map(Receive::onMessage)
.forEach(action->action.apply(it)));
}
ORthenAccept
挙動が見えますが、あなたはそれを達成するためのより多くの努力を取る必要がある、と継承を使用しているとき、それはカプセル化を破ります。
public Receive createReceive() {
return AcceptableReceiveBuilder.create()
.match(Foo.class, this::processFoo)
.match(Bar.class, this::processBar)
.match(Bash.class, this::processBash)
.match(OtherThing.class, this::processOtherThing)
.thenAccept(this::doSomethingForAllMessages)
.build();
}
class AcceptableReceiveBuilder extends ReceiveBuilder {
private List<FI.UnitApply<Object>> afterActions = new ArrayList<>();
public static AcceptableReceiveBuilder create() {
return new AcceptableReceiveBuilder();
}
@Override
public
<P> AcceptableReceiveBuilder match(Class<P> type, FI.UnitApply<P> action) {
return this.matchUnchecked(type, action);
}
@Override
public
AcceptableReceiveBuilder matchUnchecked(Class<?> type,
FI.UnitApply<?> action) {
return (AcceptableReceiveBuilder) super.matchUnchecked(type
, compose(action));
}
@Override
public
<P> AcceptableReceiveBuilder match(Class<P> type,
FI.TypedPredicate<P> condition,
FI.UnitApply<P> action) {
return this.matchUnchecked(type, condition, action);
}
@Override
public
<P> AcceptableReceiveBuilder matchUnchecked(Class<?> type,
FI.TypedPredicate<?> condition,
FI.UnitApply<P> action) {
return (AcceptableReceiveBuilder) super.matchUnchecked(type, condition
, compose(action));
}
@Override
public
<P> AcceptableReceiveBuilder matchEquals(P value, FI.UnitApply<P> action) {
return (AcceptableReceiveBuilder) super.matchEquals(value
, compose(action));
}
@Override
public
<P> AcceptableReceiveBuilder matchEquals(P value,
FI.TypedPredicate<P> condition,
FI.UnitApply<P> action) {
return (AcceptableReceiveBuilder) super.matchEquals(value, condition
, compose(action));
}
@Override
public
AcceptableReceiveBuilder matchAny(FI.UnitApply<Object> action) {
return (AcceptableReceiveBuilder) super.matchAny(compose(action));
}
private
<P> FI.UnitApply<P> compose(FI.UnitApply<P> action) {
return value -> {
action.apply(value);
for (FI.UnitApply<Object> it : afterActions) {
it.apply(value);
}
};
}
public
AcceptableReceiveBuilder thenAccept(FI.UnitApply<Object> action) {
afterActions.add(action);
return this;
}
}
[matchAny(http://doc.akka.io/japi/akka/2.5/akka/japi/pf/ReceiveBuilder.html#matchAny-akka.japi.pf.FI.UnitApply-)を満たしていますあなたの要件。 –
私はテストして見ていきますが、それはドキュメントに表示されているもの、たとえばhttp://doc.akka.io/docs/akka/current/java/actors.htmlとは一致しません。私は各メッセージクラスで異なる動作が必要ですが、すべてのメッセージについても共通の処理が必要です。 –