2016-11-12 01 Егор Непомнящих. Агрегация и осведомленность

Preview:

Citation preview

Агрегация и осведомленностьили как сократить объем кода вашего FrontEnd на 7%

Непомнящих Егор, ИСС Арт

О себе 2005-2010 - ОмГУ ИМИТс 2008 - ИСС Арт

Специализация: JavaScript

Умения: TypeScript, Java, Scala, Unity 3D, PHP, Ruby, ...

Собственный MV-фреймворк (jWidget)

Тимлид и эксперт

Фанат ООП и Iron Maiden

Что такое агрегация и осведомленность

Что такое агрегация и осведомленность

Что такое агрегация и осведомленность

Параграф 1.6 - Сравнение структур времени выполнения и времени компиляции.

Использующийобъект

Использованныйобъект

Агрегирующийобъект

Агрегируемыйобъект

Агрегация

"У машины есть корпус, колеса и двигатель"

Осведомленность

"Каждый человек знает, какие книги он прочитал"

Агрегация в C++

class Department; class University { private: Department faculty[20];};

Агрегация по значению

Агрегация в C++

class Engine;

class Car { private: Engine* engine; public: Car() { engine = new Engine(); } virtual ~Car() { delete engine; }};

Агрегация по ссылке

Осведомленность в C++

class Book; class Person { private: Book** booksRead;};

Агрегация в jWidget

● JW.Class имеет деструктор● object.destroy() - вызов деструктора● destroyObject - реализация деструктора● own - агрегация объекта

Агрегация в jWidget

class Car extends JW.Class { engine = this.own(new Engine());}

var car = new Car();car.destroy(); // Двигатель уничтожен

Реальный примерclass MyView extends JW.Class { constructor() { super(); this._layout(); $(window).resize(() => this._layout()); }

_layout() { // ... }}

var myView = new MyView();myView.destroy(); // чего-то не хватает?

Реальный примерclass MyView extends JW.Class { constructor() { super(); this._layout(); $(window).bind("resize", () => this._layout()); }

destroyObject() { $(window).unbind("resize", () => this._layout()); super.destroyObject(); }

_layout() { // ... }}

Реальный примерclass MyView extends JW.Class { constructor() { super(); this._layout(); this._onLayout = () => this._layout(); $(window).bind("resize", this._onLayout); }

destroyObject() { $(window).unbind("resize", this._onLayout); super.destroyObject(); }

_layout() { // ... }}

Реальный пример

class MyView extends JW.Class { constructor() { super(); this._layout(); this.own($(window).jwon( "resize", this._layout, this)); }

_layout() { // ... }}

Агрегирующие свойства и коллекции

Агрегирующие свойства и коллекции

Агрегирующие свойства

var property = new JW.Property().ownValue();property.set(new SampleValue(1));

property.set(new SampleValue(2));// SampleValue(1) неявно уничтожается

property.destroy();// SampleValue(2) неявно уничтожается

Агрегирующие коллекции

var array = new JW.Array().ownItems();array.add(new SampleValue(1));array.add(new SampleValue(2));

array.set(new SampleValue(3), 0);// SampleValue(1) неявно уничтожается

array.remove(1);// SampleValue(2) неявно уничтожается

array.destroy();// SampleValue(3) неявно уничтожается

Паттерн 1

Простое обновление объекта

1. Простое обновление объекта

1. Простое обновление объектаclass MyView extends JW.Class { private content; constructor(event) super(); this.initContent(); this.own(event.bind(() => this.refreshContent())); } destroyObject() { this.doneContent(); super.destroyObject(); } initContent() { this.content = new Content(); } doneContent() { this.content.destroy(); } refreshContent() { this.doneContent(); this.initContent(); }}

1. Простое обновление объекта

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

пересоздается, поместите его в агрегирующее свойство.

1. Простое обновление объекта

1. Простое обновление объекта

1. Простое обновление объектаclass MyView extends JW.Class { private content = this.own(new JW.Property()).ownValue(); constructor(event) super(); this.refreshContent(); this.own(event.bind(() => this.refreshContent())); } refreshContent() { this.content.set(new Content()); }}

1. Простое обновление объектаclass MyView extends JW.Class { private content = this.own(new JW.Property()).ownValue(); constructor(event) super(); this.refreshContent(); this.own(event.bind(() => this.refreshContent())); } refreshContent() { this.content.set(null); // опционально this.content.set(new Content()); }}

Паттерн 2

Простая отмена операции

2. Простая отмена операции

2. Простая отмена операции

Если в момент уничтожения или смены состояния объекта может выполняться

некоторая операция, но вы не знаете этого наверняка, то для ее отмены следует

воспользоваться агрегирующим свойством.

2. Простая отмена операции

Класс

Класс

Класс

2. Простая отмена операцииclass MyPage extends JW.UI.Component { private currentOperation = this.own(new JW.Property()).ownValue();

afterRender() { super.afterRender(); this.currentOperation.set(new Request( "/api/data", (result) => this._onDataLoad(result))); }

_onDataLoad(result) { this.currentOperation.set(new Animation( "fade in", () => this._onAnimationFinish())); }

_onAnimationFinish() { this.currentOperation.set(null); }}

Паттерн 3

Массовое уничтожение объектов

3. Массовое уничтожение объектов

3. Массовое уничтожение объектов

3. Массовое уничтожение объектов

3. Массовое уничтожение объектов

initContent() { this.objects = this.factory.createObjects();}

doneContent() { this.objects.forEach((obj) => obj.destroy());}

class Factory { createObjects() { return [ new Object1(), new Object2(), new Object3() ]; }}

3. Массовое уничтожение объектов

Если объект вызовом некоторой функции провоцирует создание множества объектов, то

функции следует возвращать один объект, агрегирующий в себе все эти объекты.

3. Массовое уничтожение объектов

refreshContent() { this.objects.set(this.factory.createObjects());}

class Factory { createObjects() { var objects = new JW.Class(); objects.own(new Object1()); objects.own(new Object2()); objects.own(new Object3()); return objects; }}

Паттерн 4

Уничтожение драйвера объекта

4. Уничтожение драйвера объекта

Драйвер объекта - это объект, обеспечивающий его актуальность.

4. Уничтожение драйвера объектаПример: динамическая смена цветовой схемы приложения

Основная схема Шоколадная схема

Цвет "normal"

Цвет "marginal"

Цвет "critical"

currentScheme

4. Уничтожение драйвера объектаПример: динамическая смена цветовой схемы приложения

Основная схема Шоколадная схема

Цвет "normal"

Цвет "marginal"

Цвет "critical"

currentScheme

4. Уничтожение драйвера объектаПример: динамическая смена цветовой схемы приложения

Основная схема Шоколадная схема

Цвет "normal"

Цвет "marginal"

Цвет "critical"

currentScheme

4. Уничтожение драйвера объектаПример: динамическая смена цветовой схемы приложения

Основная схема Шоколадная схема

Цвет "normal"

Цвет "marginal"

Цвет "critical"

currentScheme

4. Уничтожение драйвера объекта

class ColorScheme { colors: {[key: string]: Color};}

class ColorSchemeManager { currentScheme: ColorScheme;

getCurrentColor(key: string): Color { return this.currentScheme.colors[key]; }}

4. Уничтожение драйвера объектаclass ColorSchemeManager { currentScheme = new JW.Property<ColorScheme>();

getCurrentColor(key: string): JW.Property<Color> { var color = new JW.Property<Color>(); color.set(this.currentScheme.get().colors[key]); this.currentScheme.changeEvent.bind(() => { color.set(this.currentScheme.get().colors[key]); }); return color; }}

// Где-то в клиентеvar color = manager.getCurrentColor('marginal');this.own($('.color-box').jwcss('background-color', color));

4. Уничтожение драйвера объектаclass ColorSchemeManager { currentScheme = new JW.Property<ColorScheme>();

getCurrentColor(key: string): JW.Property<Color> { var color = new JW.Property<Color>(); color.set(this.currentScheme.get().colors[key]); this.own(this.currentScheme.changeEvent.bind(() => { color.set(this.currentScheme.get().colors[key]); })); return color; }}

// Где-то в клиентеvar color = manager.getCurrentColor('marginal');this.own($('.color-box').jwcss('background-color', color));

4. Уничтожение драйвера объектаclass ColorSchemeManager { currentScheme = new JW.Property<ColorScheme>();

getCurrentColor(key: string, owner): JW.Property<Color> { var color = new JW.Property<Color>(); color.set(this.currentScheme.get().colors[key]); owner.own(this.currentScheme.changeEvent.bind(() => { color.set(this.currentScheme.get().colors[key]); })); return color; }}

// Где-то в клиентеvar color = manager.getCurrentColor('marginal', this);this.own($('.color-box').jwcss('background-color', color));

4. Уничтожение драйвера объекта

Если функция возвращает объект, который имеет свой драйвер, заагрегируйте этот

драйвер в самом объекте.

4. Уничтожение драйвера объектаclass ColorSchemeManager { currentScheme = new JW.Property<ColorScheme>();

getCurrentColor(key: string): JW.Property<Color> { var color = new JW.Property<Color>(); color.set(this.currentScheme.get().colors[key]); this.currentScheme.changeEvent.bind(() => { color.set(this.currentScheme.get().colors[key]); }); return color; }}

// Где-то в клиентеvar color = manager.getCurrentColor('marginal');this.own($('.color-box').jwcss('background-color', color));

4. Уничтожение драйвера объектаclass ColorSchemeManager { currentScheme = new JW.Property<ColorScheme>();

getCurrentColor(key: string): JW.Property<Color> { var color = new JW.Property<Color>(); color.set(this.currentScheme.get().colors[key]); color.own(this.currentScheme.changeEvent.bind(() => { color.set(this.currentScheme.get().colors[key]); })); return color; }}

// Где-то в клиентеvar color = this.own(manager.getCurrentColor('marginal'));this.own($('.color-box').jwcss('background-color', color));

4. Уничтожение драйвера объекта

class ColorSchemeManager { currentScheme = new JW.Property<ColorScheme>();

getCurrentColor(key: string) { return this.currentScheme.$$mapValue( (scheme) => scheme.colors[key]); }}

Заключение

https://habrahabr.ru/post/270879/

Recommended