There's a bunch of ways to pass the parameters between the classes, so that kind of depends on other things, like if you use an event system, how tight the classes can be coupled to each other etc.(有很多方法可以在类之间传递参数,因此这种类型取决于其他因素,例如是否使用事件系统,类之间可以紧密耦合的程度等等。)
A 'simple' example would be this, where we pass functions ( callbacks ) between Match and Game, and between Matches and Match.(一个简单的例子就是这样,我们在Match和Game之间以及Matchs和Match之间传递函数(回调)。) The Game won't know or care what calling finished()
will do, it just knows it should pass it the winning player.(游戏不会知道或不在乎调用finished()
会做什么,只是知道它应该将获胜的玩家传递给它。)
class Game { constructor(players, rounds) { this.rounds = rounds; // clone the player objects, adding a score to each. this.players = players.map( player => Object.assign({}, player, { score: 0 })); } play( finished ) { for( let round = 1, rounds = this.rounds; round < rounds; round += 1 ) { // random winner of the round. const random_index = Math.floor( Math.random() * this.players.length ); const winner = this.players[ random_index ]; winner.score += 1; } finished( this.winner()); } winner() { return this.players.reduce(( winner, player ) => { if ( player.score > winner.score ) winner = player; return winner; }, { score: 0 }); } } class Match { constructor(game) { this.game = game; this.id = Math.random().toString(); this.isActive = false; } startMatch(finished){ this.isActive = true; this.game.play( winner => { console.log( `player ${ winner.name } won with ${ winner.score } points` ); this.stopMatch(); finished( this.id ); }); } stopMatch(){ this.isActive = false; } } class Matches { constructor() { this.matches = []; } createMatch(match){ this.matches.push( match ); } getMatch(id){ if(id){ return this.matches.find((match) => match.id = match ) } else { return null; } } endMatch( id ) { this.matches = this.matches.filter( match => match.id !== id ); } startAll() { this.matches.forEach( match => match.startMatch( id => this.endMatch( id ))); } } const players = [{ name: 'Alice' }, { name: 'Bob' }, { name: 'Carol' }]; const matches = new Matches(); document.querySelector( 'button' ).addEventListener( 'click', () => { const bestOfFive = new Game( players, 5 ); const match = new Match( bestOfFive ); matches.createMatch( match ); matches.startAll(); });
<button>Play</button>
If you so desire, you can move the new Match()
and new Game()
creation back into the constructors.(如果您愿意,可以将new Match()
和new Game()
创建移回构造函数中。)
// fake ajax request from the front end to the back end. const ajax = function( payload ) { console.log( 'ajax call to the back end' ); return back_end.request( payload ); }; const front_end = { id: 'someId', render: function( content ) { if ( content ) document.querySelector( 'table' ).outerHTML = content; }, makeMove: function() { console.log( 'Alice moves a white pawn from A2 to A3' ); const move = 'A2 to A3'; const result = this.sendToBackEnd( JSON.stringify({ id: front_end.id, move: move })); console.log( 'back end responsed, rendering result' ); front_end.render( result ); }, sendToBackEnd: function( action ) { // this will be async, so look into promises // or use a callback as before return ajax( action ); } }; const database = [ { id: 'someId', state: 'someWaytoDescribeState' } ]; const back_end = { validate: function( game, move ) { console.log( 'the move is one space down' ); console.log( 'A pawn is allowed to move one down up' ); console.log( 'The targetted space is empty' ); return true; }, request: function( payload ) { console.log( 'back end received request, recreating action' ); const action = JSON.parse( payload ); console.log( 'created action, searchign game' ); const game = database.find( game => game.id === action.id ); if ( game ) { console.log( 'game found, validating move' ); const is_valid = back_end.validate( action.move ); if ( is_valid ) { console.log( 'Move "' + action.move + '" is valid, updating database' ); // insert database code console.log( 'database updated' ); return `<table> <tr> <td></td> <td>A</td> <td>B</td> <td>C</td> </tr> <tr> <td>1</td> <td>tower</td> <td>knight</td> <td>rook</td> </tr> <tr> <td>2</td> <td>empty</td> <td>pawn</td> <td>pawn</td> </tr> <tr> <td>3</td> <td class="move">pawn</td> <td>empty</td> <td>empty</td> </tr> </table>`; } else { console.log( 'invalid move, board should stay the same' ); return null; } } else { console.log( 'game not found, should send error' ); } } }; document.querySelector( 'button' ).addEventListener( 'click', () => front_end.makeMove());
table { border-collapse: collapse; } td { border: 1px solid black; height: 50px; text-align: center; width: 50px; } td.move { background-color: orange; }
<table> <tr> <td></td> <td>A</td> <td>B</td> <td>C</td> </tr> <tr> <td>1</td> <td>tower</td> <td>knight</td> <td>rook</td> </tr> <tr> <td>2</td> <td class="move">pawn</td> <td>pawn</td> <td>pawn</td> </tr> <tr> <td>3</td> <td>empty</td> <td>empty</td> <td>empty</td> </tr> </table> <button>Make Move</button>
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…