Conway's Game of Life in Javascript
- Clone repository
git clone https://github.com/Maksimus-Prime/game-of-life.git
npm install
npm run dev
npm run prod
npm run test
Look at the result.
Вижу, что поудалял, но во view еще в одном месте используется
Погугли про методы автоматического биндинга методов класса, чтобы не нужно было каждый раз писать bind(this)
this.view.subscribe("startGame", this.startGame.bind(this));
this.view.subscribe("pauseGame", this.pauseGame.bind(this));
this.view.subscribe("restartGame", this.restartGame.bind(this));
this.view.subscribe("changeWidth", this.changeWidth.bind(this));
this.view.subscribe("changeHeight", this.changeHeight.bind(this));
this.view.subscribe("cellClicked", this.cellClicked.bind(this));
У тебя компоненты щас низко зависимы: это хорошо, то есть контроллер можно использовать с любым view или моделью и тд, но тестируются они все в одном файле. То есть перенести модель с другой проект с ее тестами не получиться.
В целом названы как нужно. Но в некоторых местах нужно подправить.
Для булевых переменных https://github.com/airbnb/javascript#accessors--boolean-prefix
interface ICell {
x: number;
y: number;
alive: boolean;
}
ну и весь проект проверить на это. (где-то правильно названо, где-то - наверно забыл подправить)
Они по сути только заставляют тебя дублировать код и главное, вносят неочевидную зависимость — каждый раз при добавлении метода надо туда его еще пробрасывать, об этом легко забыть даже тебе через пару неделек будет, а что говорить, если проект будут другие люди поддерживать. Просто несколько часов может запросто потеряно на поиск такой вот баги, что просто забыл в getModel новый метод прокинуть. И в целом всегда с подозрением относись к такому коду, где нужно повторно дублировать список чего бы то ни было, чтобы все начало работать. Все в идеале должно автоматически подхватывать в таких случаях, а у тебя тут можно просто инстанс и передавать на самом деле
«Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живёте»
:)
Сейчас у тебя в некоторых местах явно этот принцип нарушен
В первых двух макетах у тебя проект собирается в отдельную public папку. Сделать здесь так же, что бы в корневой папке не было ничего лишнего.
Раз уж ты позволяешь создать контроллер без указания вью и модели, то тебе надо тайпинги поправить
private model: IModel | undefined;
private view: IView | undefined;
И везде сделать явную обработку и бросать кастомный эксепшен с четким текстом что не так и как исправить
Хелперы общего назначения выноси в отдельные файла. Я про objectLength
и аналоги
Если ты создаешь анонимную функцию в методе, а не передаешь другой метод по ссылке, то тебе нужна очень твердая аргументация :) так что лучше убери, если не можешь железобетонно доказать, что без этого тут никак
Там должен быть чистоый vanilla js, нельзя полагаться на alert, например
А как ее запускать, вот так: npm run npm i
? :)
У тебя много плохих практик связанных с тем, что ты объявляешь мутабельную переменную, а потом начинаешь ее во вложенных функциях или блках кода менять, это не декларативно и тяжело читается, так как в голове постоянно надо держать все возможные состотяния. Чаще всего это можно сделать аккуратней через методы перебора массивов. Посмотри на getAliveNeighbors
и nextBoardState
и предложи, как их можно отрефакторить и сделать гораздо более читаемыми
Все интерфейсы следует описывать в отдельных файлах . можно в один файл все разместить. И самое главное: интерфейсы должны быть реализованы классом . То есть, например, класс контроллера должен реализовывать его интерфейс: class Controller implements IController
.
this.$startButton = $("#startButton")[0] as HTMLButtonElement;
У TS же есть JQuery object. Префикс $ показывает, что элемент является JQuery объектом. У тебя же это HTMLElement.
Префикс полезен, когда с твоим кодом будет работать другой человек. Ему не нужно будет разбираться какие методы можно применять к переменной (каким объектом она является) - по префиксу сразу будет ясно.
Лушче в throwConsoleError явно бросать эксепшен и аварийно закрывать программу, сейчас у тебя просто дальше код не идет и это менее очевидно. И переименовать, так как не надо тут показывать способ вывода ошибки, в продакшене он может быть HTTP запросом на сервер :)
По максимуму заменить циклы for на перебирающие методы массивов
Если есть схожие по типу операции их стоит выносить в отдельный метод.
Например во View: Поиск DOM-элементов вынести в отдельный метод и вызывать его в конструкторе. Так же и с назначением обработчиков событий. Так будет гораздо читаемым класс.
Название обработчика должно показывать, то, что он выполняет, а не то, что он обрабатывает.
public cellClicked(cellKey: string): void {
this.model.editCellAliveState(cellKey);
}
Если класс будет большим, то при задании обработчика, например, для кнопки, с таким подходом будет что-то типо: onClick=buttonClicked
- Придется проматывать вниз чтобы понят что он делает. + по семантике его можно будет назначить только для клика по кнопке. Аналогично у тебя сейчас с cellClicked
Вынести в отдельный модуль весь функционал обработки подписки, отписки и тд по событиям. В view пользоваться предоставляемыми новым модулем методами.
Сейчас сильно загрязнено view и этот функционал (если бы это был реальный проект) мог бы понадобиться во многих других элементах.
В первой итерации ты вообще нуль с нулем складывать будешь? :)
newBoard здесь не нужна
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.