Вот рабочий код Java, который предоставляет базовый класс двигателя, который обрабатывает регистрацию слушателя баланса, для ряда реализаций двигателей, используемых различными играми. например будет демонстрационный движок, поддерживающий демо-баланс для демонстрационной игры и денежной версии того же движка, который получает баланс от бэк-офиса и т. д. Суть здесь не в действительной java, а в том, как реализовать такой шаблон в JavaScript. Я попробовал около 30 различных способов сделать это, в том числе с использованием John Resigs «простого наследования JavaScript» и сахара extend(), определенного в «JavaScript: окончательное руководство», используя различные шаблоны модулей, используя это = это и т. д. ни один из которых работал над этой проблемой.Как реализовать этот шаблон java в JavaScript (используя наследование)?
Вот код Java рабочий:
Файл Engine.java:
package com.test;
public abstract class Engine {
BalanceListener externalBalanceListener = null;
double balance = 0;
public void registerBalanceListener(BalanceListener balanceListener) {
externalBalanceListener = balanceListener;
balanceListener.update(balance); // call once when first register
}
public double getBalance() {
return balance;
}
protected void setBalance(double newBal) {
if (newBal != balance) {
balance = newBal;
if (externalBalanceListener != null) {
externalBalanceListener.update(newBal);
}
}
}
public abstract double startGame(double stake, int numLines);
}
BalanceListener.java Файл
package com.test;
public interface BalanceListener {
void update(double balance);
}
DemoEngine.java Файл
package com.test;
import java.util.Random;
public class DemoEngine extends Engine {
public DemoEngine() {
setBalance(10000);
}
public double startGame(double stake, int numLines) {
double wonAmount;
Random random = new Random();
setBalance (getBalance() - (stake * numLines));
// some game logic
wonAmount = Math.round((random.nextDouble() * 10)) * stake;
setBalance (getBalance() + wonAmount);
return wonAmount;
}
}
DemoGame.java Файл
package com.test;
public class DemoGame {
public class MyListener implements BalanceListener {
public MyListener(){
}
public void update(double balance) {
System.out.println("new balance: " + balance);
}
}
public static void main(String[] args) {
Engine engine = new DemoEngine();
DemoGame demoGame = new DemoGame();
BalanceListener balanceListener = demoGame.new MyListener();
engine.registerBalanceListener(balanceListener);
engine.startGame(10, 20);
}
}
Здесь была равнина (неудачная) попытка получить то же самое, работая в JavaScript (см http://jsfiddle.net/fmX67/)
function Engine() {
this.balance = 0;
this.externalBalanceListener;
this.registerBalanceListener = function(l) {
this.externalBalanceListener= l;
this.externalBalanceListener(this.balance);
};
this.getBalance = function() {
return this.balance;
};
this.setBalance = function (newBal) {
if (newBal != this.balance) {
this.balance = newBal;
if (this.externalBalanceListener != undefined) {
this.externalBalanceListener(newBal);
}
}
};
};
function DemoEngine() {
this.startGame = function(stake, numLines) {
var won;
setBalance(this.getBalance() - stake*numlines);
won = Math.round(Math.random() * 10) * Stake;
this.setBalance(this.getBalance() + won);
return won;
};
}
DemoEngine.prototype = Engine;
function DemoGame() {
function balanceListener(balance) {
console.log(balance);
}
var engine = new DemoEngine();
engine.registerBalanceListener(balanceListener); // This throws an exception: Uncaught TypeError: Object [object Object] has no method 'registerBalanceListener'
engine.startGame(10, 25);
}
var game = new DemoGame();
Очевидно, что я не имею идея, что я делаю (несмотря на чтение нескольких книг JS). Я предполагаю, что могу использовать композицию вместо того, чтобы пытаться наследовать, но это ограничивает использование языка и какие шаблоны могут быть реализованы.
Редактировать: здесь рабочая версия с ответом Шона Уэста. см http://jsfiddle.net/fmX67/3/
function Engine() {
this.balance = 0;
this.externalBalanceListener;
this.registerBalanceListener = function(l) {
this.externalBalanceListener= l;
this.externalBalanceListener(this.balance);
};
this.getBalance = function() {
return this.balance;
};
this.setBalance = function (newBal) {
if (newBal != this.balance) {
this.balance = newBal;
if (this.externalBalanceListener != undefined) {
this.externalBalanceListener(newBal);
}
}
};
};
function DemoEngine() {
this.setBalance(1000);
this.startGame = function(stake, numLines) {
var won;
this.setBalance(this.getBalance() - stake*numLines);
won = Math.round(Math.random() * 10) * stake;
this.setBalance(this.getBalance() + won);
return won;
};
}
DemoEngine.prototype = new Engine();
function DemoGame() {
function balanceListener(balance) {
console.log(balance);
}
var engine = new DemoEngine();
engine.registerBalanceListener(balanceListener); // This throws an exception: Uncaught TypeError: Object [object Object] has no method 'registerBalanceListener'
engine.startGame(10, 25);
}
var game = new DemoGame();
Это не похоже на код ... – Amberlamps
Что вы сделали до сих пор? – turnt