GithubHelp home page GithubHelp logo

game-of-life's Introduction

game-of-life

Conway's Game of Life in Javascript

Installation

  1. Clone repository
git clone https://github.com/Maksimus-Prime/game-of-life.git
  1. Install dependencies using npm (I use Node.js v6.10.2)
npm install

Run

Development

npm run dev

Production

npm run prod

Tests

npm run test

Look at the result.

game-of-life's People

Contributors

kinda-neat avatar

Watchers

 avatar

game-of-life's Issues

Автоматический биндинг

Погугли про методы автоматического биндинга методов класса, чтобы не нужно было каждый раз писать 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));

Отдельный .spec файл для каждого компонента MVC

У тебя компоненты щас низко зависимы: это хорошо, то есть контроллер можно использовать с любым view или моделью и тд, но тестируются они все в одном файле. То есть перенести модель с другой проект с ее тестами не получиться.

Названия булевых переменных

В целом названы как нужно. Но в некоторых местах нужно подправить.
Для булевых переменных https://github.com/airbnb/javascript#accessors--boolean-prefix

interface ICell {
  x: number;
  y: number;
  alive: boolean;
}

ну и весь проект проверить на это. (где-то правильно названо, где-то - наверно забыл подправить)

getModel & getView излишни

Они по сути только заставляют тебя дублировать код и главное, вносят неочевидную зависимость — каждый раз при добавлении метода надо туда его еще пробрасывать, об этом легко забыть даже тебе через пару неделек будет, а что говорить, если проект будут другие люди поддерживать. Просто несколько часов может запросто потеряно на поиск такой вот баги, что просто забыл в getModel новый метод прокинуть. И в целом всегда с подозрением относись к такому коду, где нужно повторно дублировать список чего бы то ни было, чтобы все начало работать. Все в идеале должно автоматически подхватывать в таких случаях, а у тебя тут можно просто инстанс и передавать на самом деле

«Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живёте»
:)

Вынести сборку в отдельную папку

В первых двух макетах у тебя проект собирается в отдельную public папку. Сделать здесь так же, что бы в корневой папке не было ничего лишнего.

Обрабатывать в контроллере отсутсвие модели или вью

Раз уж ты позволяешь создать контроллер без указания вью и модели, то тебе надо тайпинги поправить

  private model: IModel | undefined;
  private view: IView | undefined;

И везде сделать явную обработку и бросать кастомный эксепшен с четким текстом что не так и как исправить

Опять же избегать вложенных функций в методах

Если ты создаешь анонимную функцию в методе, а не передаешь другой метод по ссылке, то тебе нужна очень твердая аргументация :) так что лучше убери, если не можешь железобетонно доказать, что без этого тут никак

В модели все мутации замыканий внутри методов убрать

У тебя много плохих практик связанных с тем, что ты объявляешь мутабельную переменную, а потом начинаешь ее во вложенных функциях или блках кода менять, это не декларативно и тяжело читается, так как в голове постоянно надо держать все возможные состотяния. Чаще всего это можно сделать аккуратней через методы перебора массивов. Посмотри на getAliveNeighbors и nextBoardState и предложи, как их можно отрефакторить и сделать гораздо более читаемыми

Все интерфейсы в отдельный файл / реализовать интерфейсы

Все интерфейсы следует описывать в отдельных файлах . можно в один файл все разместить. И самое главное: интерфейсы должны быть реализованы классом . То есть, например, класс контроллера должен реализовывать его интерфейс: class Controller implements IController.

префикс $

this.$startButton = $("#startButton")[0] as HTMLButtonElement;

У TS же есть JQuery object. Префикс $ показывает, что элемент является JQuery объектом. У тебя же это HTMLElement.

Префикс полезен, когда с твоим кодом будет работать другой человек. Ему не нужно будет разбираться какие методы можно применять к переменной (каким объектом она является) - по префиксу сразу будет ясно.

Let it crash

Лушче в throwConsoleError явно бросать эксепшен и аварийно закрывать программу, сейчас у тебя просто дальше код не идет и это менее очевидно. И переименовать, так как не надо тут показывать способ вывода ошибки, в продакшене он может быть HTTP запросом на сервер :)

циклы for

По максимуму заменить циклы for на перебирающие методы массивов

Конструктор класса должен быть минимальным по функционалу

Если есть схожие по типу операции их стоит выносить в отдельный метод.
Например во View: Поиск DOM-элементов вынести в отдельный метод и вызывать его в конструкторе. Так же и с назначением обработчиков событий. Так будет гораздо читаемым класс.

Название обработчиков

Название обработчика должно показывать, то, что он выполняет, а не то, что он обрабатывает.

public cellClicked(cellKey: string): void {
    this.model.editCellAliveState(cellKey);
  }

Если класс будет большим, то при задании обработчика, например, для кнопки, с таким подходом будет что-то типо: onClick=buttonClicked - Придется проматывать вниз чтобы понят что он делает. + по семантике его можно будет назначить только для клика по кнопке. Аналогично у тебя сейчас с cellClicked

Обработка подписки на события в отдельный модуль

Вынести в отдельный модуль весь функционал обработки подписки, отписки и тд по событиям. В view пользоваться предоставляемыми новым модулем методами.

Сейчас сильно загрязнено view и этот функционал (если бы это был реальный проект) мог бы понадобиться во многих других элементах.

count + 0? :)

В первой итерации ты вообще нуль с нулем складывать будешь? :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.