Обсуждение структуры скрипта с ООП
Приветствую.
Пока без всяких сборщиков, фреймворков и реактивных вещей, старый добрый скрипт, делаю чтобы с использованием объектов и кое какой структурой типа MVC. Только C тут не стал делать. Модель отвечает за данные и алгоритмы. А Вьюха - за html и события. Главное чтобы не лапшекод перемешанный, а с разделением ответственности. Вроде наглядно получилось, ваше мнение по улучшению? Вы таким бы способом делали, если на объектах ( а не просто процедурно)? Реализация игры "Пятнашки": <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> td { border: 2px solid black; width: 20px; height: 20px; text-align: center; } </style> <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script> <script> $(document).ready(function(){ 'use strict'; let model = new Model(); let view = new View(model, '#tablefield', '#result', '#process'); function View(model, tablefieldId, resultId, startGameButton) { this.model = model; this.$tablefield = $(tablefieldId); this.$result = $(resultId); this.$startGameButton = $(startGameButton); let _view = this; this.$startGameButton.click(function(){ if (!_view.model.getIsGameOver()) { _view.$result.html('Игра уже идет').show().fadeOut(2000); return; } _view.model.startGame(); _view.showTable(); _view.initializeTable(); $(this).prop('disabled', true); }); this.showTable = function () { let table = this.model.table; this.$tablefield.html(''); let res = '<table>'; for (let i = 0; i < table.length; i++){ res += '<tr>'; for (let j = 0; j < table[i].length; j++){ let cell = table[i][j]; res += '<td style="' + '' + '">'; res += cell; res += '</td>'; } res += '</tr>'; } res += '</table>'; this.$tablefield.html(res); this.$result.html('Игра начинается, соберите числа от 1 до 15 по рядам сверху вниз').show().fadeOut(4000); } this.initializeTable = function (){ $('td').click(function(){ let model = _view.model; if (model.getIsGameOver()) { _view.$result.html('Игра завершена, начните новую игру').show().fadeOut(2000); return; } let $td = $(this); if ($td.html() == '') { _view.$result.html('Пустую ячейку нельзя перемещать').show().fadeOut(2000); return; } let $tr = $td.parent(); let $table = $tr.parent(); let x = $td.prevAll().length; let y = $tr.prevAll().length; if (model.getIsMoveOk(x, y)) { let coord = model.getEmptyCellCoordinates(); let $emptyTd = $table.children().eq(coord.y).children().eq(coord.x); let val = $td.html(); model.makeMove(x, y); $emptyTd.html(val); $td.html(''); if (model.getIsSuccess()) { _view.$result.html('ВЫ УСПЕШНО СОБРАЛИ ПАЗЛ. ПОЗДРАВЛЯЕМ !!!').show(); model.isGameOver = true; _view.$startGameButton.prop('disabled', false); } } else { _view.$result.html('Ход не корректен, выберите ячейку рядом с пустой').show().fadeOut(2000); } }); } } function Model() { this.isGameOver = true; this.table = []; this.getIsGameOver = function(){ return this.isGameOver; } this.startGame = function(){ this.isGameOver = false; this.table = []; let numbers = []; while (numbers.length < 16) { let num = this.getRandomNumber(0, 15); if (numbers.indexOf(num) === -1) { numbers.push(num); } } // для демо игры //numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,0,14,15]; for (let i = 0; i < 4; i++){ this.table.push([]); for (let j = 0; j < 4; j++){ let el = numbers.shift(); this.table[i].push(el ? el : ''); } } //console.log(this.table); } this.getIsMoveOk = function(x, y){ let coord = this.getEmptyCellCoordinates(); return (Math.abs(coord.x - x) + Math.abs(coord.y - y)) == 1 } this.makeMove = function(x, y){ let coord = this.getEmptyCellCoordinates(); let val = this.table[y][x]; this.table[y][x] = ''; this.table[coord.y][coord.x] = val; //console.log(this.table); } this.getEmptyCellCoordinates = function() { for (let i = 0; i < this.table.length; i++){ for (let j = 0; j < this.table[i].length; j++){ if (!this.table[i][j]) { return { x: j, y: i, }; } } } } this.getIsSuccess = function() { let start = 0; for (let i = 0; i < this.table.length; i++){ for (let j = 0; j < this.table[i].length; j++){ start++; if (start <= 15 && start != this.table[i][j]) { return false; } } } return true; } this.getRandomNumber = function(min, max){ let delta = Math.floor(max - min + 1); let num = Math.random() * delta; return min + Math.floor(num); }; } }); </script> </head> <body > <button id="process">Начать игру</button> <div id="tablefield"> </div> <div id="result" style="color:red;"> </div> </body> </html> |
У меня тут нет чему наследоваться, понятно что в js, с этим не так просто, если без class.
Кстати, насчет наследования, многие считают что это не особо и хорошо в современном ООП дизайне. |
Часовой пояс GMT +3, время: 17:56. |