2015-12-02 78 views
0

實施阿卡演員我用Java實現簡單的計數器演員:如何在實用的風格與Java

public class CounterJavaActor extends UntypedActor { 

    int count = 0; 

    @Override 
    public void onReceive(Object message) throws Exception { 
     if (message.equals("incr")) { 
      count += 1; 
     } else if (message.equals("get")) { 
      sender().tell(count, self()); 
     } 
    } 

} 

在上coursera「Scala的功能性反應編程」課程,我看到櫃檯的功能impementation:

/** 
* Advantages: 
* state change is explicit 
* state is scoped to current behaviour 
*/ 
class CounterScala extends Actor{ 

    def counter(n: Int) : Receive = { 
    case "incr" => context.become(counter(n+1)) 
    case "get" => sender ! n 
    } 

    def receive = counter(0) 
} 

UPD: 我的問題,在Java中我不能追償的功能調用,比如在斯卡拉counter(n+1)。意思是:

public class CounterJava8Actor extends AbstractActor { 
    //counter(0) in scala 
    private PartialFunction<Object, BoxedUnit> counter; 

    private int n = 0; 

    public CounterJava8Actor() { 
     counter = 
      ReceiveBuilder. 
       matchEquals("get", s -> { 
        sender().tell(n, self()); 
       }). 
       matchEquals("inc", s -> { 
        //become(counter(n+1) in scala 
        context().become(counter); 
       }).build(); 
     receive(counter); 
    } 
} 

可以用java的功能樣式來實現它嗎?

回答

2

根據文檔,您可以使用成爲在Java/unbecome 8

http://doc.akka.io/docs/akka/snapshot/java/lambda-actors.html#become-unbecome

這裏從那裏

public class HotSwapActor extends AbstractActor { 
    private PartialFunction<Object, BoxedUnit> angry; 
    private PartialFunction<Object, BoxedUnit> happy; 

    public HotSwapActor() { 
    angry = 
     ReceiveBuilder. 
     matchEquals("foo", s -> { 
      sender().tell("I am already angry?", self()); 
     }). 
     matchEquals("bar", s -> { 
      context().become(happy); 
     }).build(); 

    happy = ReceiveBuilder. 
     matchEquals("bar", s -> { 
     sender().tell("I am already happy :-)", self()); 
     }). 
     matchEquals("foo", s -> { 
     context().become(angry); 
     }).build(); 

    receive(ReceiveBuilder. 
     matchEquals("foo", s -> { 
     context().become(angry); 
     }). 
     matchEquals("bar", s -> { 
     context().become(happy); 
     }).build() 
    ); 
    } 
} 

複製的範例代碼,也可以使用UntypedActor像文檔解釋這裏

http://doc.akka.io/docs/akka/snapshot/java/untyped-actors.html

public class Manager extends UntypedActor { 

    public static final String SHUTDOWN = "shutdown"; 

    ActorRef worker = getContext().watch(getContext().actorOf(
     Props.create(Cruncher.class), "worker")); 

    public void onReceive(Object message) { 
    if (message.equals("job")) { 
     worker.tell("crunch", getSelf()); 
    } else if (message.equals(SHUTDOWN)) { 
     worker.tell(PoisonPill.getInstance(), getSelf()); 
     getContext().become(shuttingDown); 
    } 
    } 

    Procedure<Object> shuttingDown = new Procedure<Object>() { 
    @Override 
    public void apply(Object message) { 
     if (message.equals("job")) { 
     getSender().tell("service unavailable, shutting down", getSelf()); 
     } else if (message instanceof Terminated) { 
     getContext().stop(getSelf()); 
     } 
    } 
    }; 
} 

要懂得參數添加到Procedure你可以看到這樣的回答:

Akka/Java getContext().become with parameter?

,這裏是用java實際的解決方案8

private PartialFunction<Object, BoxedUnit> counter(final int n) { 
    return ReceiveBuilder. 
     matchEquals("get", s -> { 
      sender().tell(n, self()); 
     }). 
     matchEquals("inc", s -> { 
      context().become(counter(n + 1)); 
     }).build(); 
} 


public CounterJava8Actor() { 
    receive(counter(0)); 
} 
+0

我的問題 - 斯卡拉樣的函數調用在部分函數上。我更新我的問題 – zella

+0

這很容易,但斯卡拉語法有些尷尬我:( – zella