В этот раз я все сделаю правильно!

Алексей Распопов, DataRobot.

В этот раз я все сделаю правильно!

This time I'll build things the right way

whoami

О проекте

Зачем страдать?

Требования

React/JSX

bro

JSX

Универсальный язык разметки компонентов, совместим с разными реализациями при этом не требуя изменений.

Легко читается и пишется, так как представляет собой смесь давно знакомых вещей.

Не прячет ошибки и не дает возможности делать что-то неявно.

      {collection.map(item => (
        <ItemView key={item.id} item={item} />
      ))}
    
      <item-view *ngFor="let item of collection" [item]="item">
      </item-view>
    
      {{#each item in collection}}
        {{item-view item=item}}
      {{/each}}
    

Статическая типизация

bro

Типизация

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

Flow

not bro

Flow

Immutable JS

bro

Immutable JS

Легкие операции в Immutable JS

      case MessageActionTypes.MESSAGE_CREATED:
        return threads.mergeIn([action.message.threadId], {
          lastMessage: action.message.text,
          timestamp: action.message.timestamp,
        });
    
      type ResourceModel = { id: string, ... };
      const defaults: ResourceModel = { id: '', ... };
      class Resource extends Record(defaults) { ... }
    
      class Resource extends Record(defaults) {
        constructor(data: ResourceModel) { super(data); }
      }
    
      const resource = new Resource({ id: shortid.generate(),
                                      ... });
    

Data Access Object

bro

      class Resources {
        async create(model)
        async retrieve(criterias)
        async update(id, model)
        async destroy(id)
      }
    

Data Access Object

Flux

bro

Flux — что хорошего

Flux + типизация

      class PredResponse extends Action<{ datarow: DataRow,
                                          results: Prediction }> {}
    

Flux — что плохого

      export default class Actor {
        constructor(dispatcher) {
          this.dispatcher = dispatcher;
          this.dispatchToken = this.dispatcher.register((message) => {
            this.receive(message);
          });
        }
        disable() {
          this.dispatcher.unregister(this.dispatchToken);
        }
      }
    
      class PredictionQueue extends Actor {
        constructor(dispatcher) {
          super(dispatcher);
          this.predictions = new Predictions();
        }
        async receive(message) {
          switch (message.constructor) {
          case SyncDataRow:
            // ...
          }
        }
      }
    

React Transmit

not bro

Transmit

LocalForage

bro

LocalForage

LocalForage

      import Storage from 'localforage';
      export default Storage.createInstance({
        name: 'prediction-optimization-ux/reasons',
        version: 1,
      });
    
      await Reasons.setItem(id, reason);
    

PostCSS + CSS Modules

bro

CSS Modules

      /PredictionInsight.react.js
      /PredictionInsight.style.css
    

React + D3 + React Motion ❤️

❤️

Docker

bro

Docker

Python ❤️

Python tool set

Data Access Object — доступ к данным

      class Resources():
        async def create(model)
        async def retrieve(criterias)
        async def update(id, model)
        async def destroy(id)
    

Data Access Object — обработка запросов

      class ResourcesView(View):
        async def post()
        async def get()
        async def patch()
        async def delete()
    

Async/Await

bro

Async/await

Спасибо за внимание