2013-07-17 3 views
0

Вот рабочий код 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(); 
+0

Это не похоже на код ... – Amberlamps

+0

Что вы сделали до сих пор? – turnt

ответ

1

Как ни странно это может показаться кому-то наступающем из Java в вашей попытке вы хотите изменить:

DemoEngine.prototype = Engine; 

Для этого:

DemoEngine.prototype = new Engine(); 

Это ответ довольно хорош, если вы хотите получить дополнительную информацию: What is the 'new' keyword in JavaScript?

+0

Результат, который сработал! Все еще озадачен наследованием JS (да, я разработчик Java), несмотря на то, что пробирается сквозь все классические (непробиваемые) книги и статьи JS. Мой мозг недостаточно велик, чтобы в то же время получить все необходимые языковые концепции JS (наследование java тривиально по сравнению). –