我是Akka的新手,我很喜歡這項技術,但我無法理解如何在沒有業務邏輯的情況下爲演員做飯。假設我需要製作一款遊戲。遊戲對玩家有限制,在選擇贏家後不能多選。Akka。如何擺脫演員內部的業務邏輯?
public class Game {
private List<String> participants;
private int maxParticipants;
private String winner;
private boolean ended;
public int getMaxParticipants() {
return maxParticipants;
}
public int getParticipantsSize() {
return participants.size();
}
public void addParticipant(String participant) {
participants.add(participant);
}
public boolean isEnded() {
return ended;
}
public void chooseWinner() {
if (ended) {
// do some stuff
}
winner = participants.get(randomNumber);
ended = true;
}
}
和演員類:
public class GameActor extends UntypedActor {
private Game game = new Game();
@Override
public void onReceive(Object message) throws Exception {
if (message instanceof AddParticipant) {
// For example there can't be more then two participants.
// I want to have this "if" inside my Game class, not here
if (game.getParticipantsSize() >= game.getMaxParticipants()) {
// do something about it
}
game.addParticipant(message.getParticipant());
}else if (message instanceof ChooseWinner){
// We can't choose winner after game ended. I don't want to have this logic here
game.chooseWinner();
}
}
}
現在我明白了幾種方法。在簡單的情況下,他們都可以工作,但他們都非常有限:
上升例外。僅適用於負面情況。如果一切正常,我 不知道下一步該怎麼做。另外catch塊是醜陋的,我不想 想維護GameFullException,GameEndedException等等。
返回一些價值。像addParticipant中的布爾值,如果它是 成功。要麼是有限的使用情況,要麼是 返回值的另一層ifelse。
- 遊戲類可以引發事件,我的演員可以訂閱它。
像這樣:
public class Game {
private List<Listener> listeners = new ArrayList<>();
public void addListener(Listener listener) {
listeners.add(listener);
}
public void riseEvent(Event event) {
listeners.forEach(l->l.handle(event));
}
}
而且單個收聽的是演員:
public class GameActor extends UntypedActor {
private Game game = new Game();
@Override
public void onReceive(Object message) throws Exception {
if (message instanceof AddParticipant) {
game.addParticipant(message.getParticipant());
}else if (message instanceof ChooseWinner){
game.chooseWinner();
}else if(message instanceof Event){
// do something with actor state if needed
}
}
public void handle(Event event) {
self().tell(event, self());
}
}
第三人似乎最有趣和最強大的我,但它只是似乎錯了,我的模型這裏有一個用戶,它是一個演員,然後由模型事件發送給自己。 當然,這個遊戲課只是一個例子(我不確定它是否是我的問題的一個很好的例證),這樣簡單的邏輯可以在演員中完成,並且沒問題,但我對如何解耦的原理感興趣演員的業務邏輯,因爲我不認爲演員是許多原因的商業邏輯的好地方。我對Scala和Java都很感興趣。一些例子會很棒。
也許你是對的,我只需要做一點小小的轉變。起初我想到演員喜歡另一種同步技術。主要原因是因爲我不想在演員中擁有業務邏輯,因爲演員很難測試簡單的函數和類。但也許這是我需要爲簡單併發付出的代價。 –
我明白你爲什麼會這樣說,但我認爲你是對的。演員很容易測試。發送消息給他們,並測試他們的反應!併發性問題不是你可以避免的 - 如果你想要一個類同時接收消息,擴展Actor類型可能是允許它們參與的最簡單的機制。 –