Tradicionalmente, los modelos de componentes utilizados en el mundo de front se utilizan como un mecanismo de modularidad para descomponer una solución. De forma más ambiciosa, se construyen sistemas de diseño basados en componentes en aras a aumentar la reutilización entre proyectos y mejorar la productividad en los desarrollos.
Sin embargo, para que la reutilización se convierta en una realidad constatable necesitamos cambiar nuestra aproximación al problema. Más que crear arquitecturas polimórficas que acepten distintos tipos de componentes. Necesitamos crear componentes que sean capaces de adaptarse plásticamente y de forma dinámica a cada contexto arquitectónico de uso.
En esta charla presentaremos una colección de técnicas y modelos de adaptación que pueden ser aplicados sobre nuestros sistemas de componentes con independencia del stack tecnológico en que estén implementados: Vue, React, Polymer, etc. Si perteneces al mundo del front y te gusta ver código esta charla te interesará.
2. Arquitecturas Sólidas
de Componentes Web
Madrid 23-24 Noviembre
Los componentes son el resultado de un
minucioso proceso de diseño. Algo que
representa nuestra realidad
3. Arquitecturas Sólidas de Componentes Web3
La Tecnología de Componentes ha
venido a resolver los problemas de
modularidad para hacer
Aplicaciones Web
4. Arquitecturas Sólidas de Componentes Web4
Formas de Adaptación
Estático Dinámico
Ayer Hoy
Fijo
Sólido
Estanco
Cambiante
Flexible
Fluido
La experiencia de uso debe adaptarse a
las condiciones espaciales del entorno
donde se ubica
Adaptación Espacial
5. Arquitecturas Sólidas de Componentes Web5
También es importante dar soporte a un
acceso continuo y permanente a la
experiencia de uso
Adaptación Temporal
Puntual Permanente
Ayer Hoy
Discreto
Instantáneo
Faseado
Continuo
Duradero
Constante
Formas de Adaptación
6. Arquitecturas Sólidas de Componentes Web6
Las experiencias de hoy se desarrollan
dentro del plano social de usuarios
conectados
Adaptación Social
Individual Social
Ayer Hoy
Personal
Privado
Propio
Grupal
Público
Colectivo
Formas de Adaptación
7. Arquitecturas Sólidas de Componentes Web7
Centralizado Distribuido
Ayer Hoy
Focalizado
Local
Único
Dispersas
Ubicuo
Múltiple
Se pretende hacer dispersión de las
actividades de negocio a lo largo de
toda la Web
Adaptación Contextual
Formas de Adaptación
8. Arquitecturas Sólidas de Componentes Web8
Aislado Inmersivo
Ayer Hoy
Acotado
Limitado
Accesible
Pervasivo
Completo
Vinculante
Las nuevas formas de experiencia
digital proponen soluciones inmersivas
brutales
Adaptación Ambiental
Formas de Adaptación
9. Arquitecturas Sólidas de Componentes Web
Arquitecturas Sólidas
de Componentes Web
1
Single Responsibility
YX Z
A
B
C
10. Arquitecturas Sólidas de Componentes Web
Arquitecturas Sólidas
de Componentes Web
2
Single Responsibility
Open Close Design
11. Arquitecturas Sólidas de Componentes Web
Arquitecturas Sólidas
de Componentes Web
3
Single Responsibility
Open Close Design
Liskov Substitution
12. Arquitecturas Sólidas de Componentes Web
Arquitecturas Sólidas
de Componentes Web
4
Single Responsibility
Open Close Design
Liskov Substitution
Interface Segregation
on ()
off()
on ()
off()
13. Arquitecturas Sólidas de Componentes Web
Arquitecturas Sólidas
de Componentes Web
5
Single Responsibility
Open Close Design
Liskov Substitution
Interface Segregation
Dependency Inversion
14. Arquitecturas Sólidas de Componentes Web
Arquitecturas Sólidas
de Componentes Web
1
Single Responsibility
Open Close Design
Liskov Substitution
Interface Segregation
Dependency Inversion
S
O
L
I
D
15. Arquitecturas Sólidas de Componentes Web15
La Adaptación Como
Arquitectura
Necesitamos Idear Nuevas Formas
de Desarrollo de Software
Centradas en la Adaptación
16. Arquitecturas Adaptativas
de Componentes Web
Madrid 23-24 Noviembre
Existe otra forma de hacer arquitecturas.
Una en la que los componentes se
adaptan a cada contexto de uso
17. Arquitecturas Adaptativas de Componentes Web
Contexto Arquitectónico #1 Contexto Arquitectónico #2 Contexto Arquitectónico #3
17
Arquitecturas Adaptativas
de Componentes Web
18. Arquitecturas Adaptativas de Componentes Web18
Contexto Arquitectónico #1 Contexto Arquitectónico #2 Contexto Arquitectónico #3
Arquitecturas Adaptativas
de Componentes Web
19. Arquitecturas Adaptativas de Componentes Web19
Arquitecturas Adaptativas
de Componentes Web
Contexto Arquitectónico #1 Contexto Arquitectónico #2 Contexto Arquitectónico #3
20. Arquitecturas Adaptativas de Componentes Web
Arquitecturas Adaptativas
de Componentes Web
Contexto Arquitectónico #1 Contexto Arquitectónico #2 Contexto Arquitectónico #3
21. Arquitecturas Adaptativas de Componentes Web21
Core
CORE
Componentes &
Extensión Adaptativa
El sujeto de la
extensión adaptativa
class Core {
constructor () {}
fx () {}
fy () {}
[Symbol.iterator] () {}
}
22. Arquitecturas Adaptativas de Componentes Web
Extensión
La lógica de
extensión adaptativa
El sujeto de la
extensión adaptativa
Core
CORE
EXTENSION
Componentes &
Extensión Adaptativa class Core {
constructor () {}
fx () {}
fy () {}
[Symbol.iterator] () {}
}
function Ext (core) {
}
core.map = function (fn) {}
core.reduce = function (fn) {}
core.filter = function (fn) {}
core.every = function (fn) {}
core.some = function (fn) {}
23. Arquitecturas Adaptativas de Componentes Web
Contrato Extensión
La colección de
capacidades del
core
La colección de
capacidades
del core
Contrato Core
CORE
EXTENSION
Componentes &
Extensión Adaptativa class Core {
constructor () {}
fx () {}
fy () {}
[Symbol.iterator] () {}
}
function Ext (core) {
}
core.map = function (fn) {}
core.reduce = function (fn) {}
core.filter = function (fn) {}
core.every = function (fn) {}
core.some = function (fn) {}
24. Arquitecturas Adaptativas de Componentes Web
Componentes &
Extensión Adaptativa
Dependencias que
hacen operar a la
extensión
Contrato de
Extensión Adaptativa
Symbol.iterator
class Core {
constructor () {}
fx () {}
fy () {}
[Symbol.iterator] () {}
}
function Ext (core) {
}
core.map = function(fn) {
let ys = []
for (let x of this)
ys = [...ys, fn(x)]
return ys
}
core.reduce = function (fn) {}
core.filter = function (fn) {}
core.every = function (fn) {}
core.some = function (fn) {}
CORE
EXTENSION
25. Arquitecturas Adaptativas de Componentes Web
Componentes &
Extensión Adaptativa
La forma en que la
extensión trasforma
al core
Técnica Extensión
Symbol.iterator
class Core {
constructor () {}
fx () {}
fy () {}
[Symbol.iterator] () {}
}
function Ext (core) {
}
core.map = function(fn) {
let ys = []
for (let x of this)
ys = [...ys, fn(x)]
return ys
}
core.reduce = function (fn) {}
core.filter = function (fn) {}
core.every = function (fn) {}
core.some = function (fn) {}
CORE
EXTENSION
26. Arquitecturas Adaptativas de Componentes Web
Adición Intercesión
Especialización Delegación
TécnicasEstáticas
EarlyBinding
TécnicasDinámicas
LateBinding
Adaptación en Anchura Adaptación en Profundidad
Structural Adaptation Behavioural Adaptation
Extensión
Core
Extensión
Core
Core
Extensión
Extensión
Core
Hooks de Extensión
Adaptativa
29. Arquitecturas Adaptativas en Acción
Arquitecturas Adaptativas
en Requisitos
La construcción de soluciones basadas en
componentes adaptativos debería resultar
lo más declarativa posible
Extensión Declarativa
A B
A+B
Cada componente y extensión adaptativa
debería operar como una caja negra para
el diseñador de producto
Extensión Encapsulada
Sabe cómo
extender
Sabe cómo
conectarse
30. Arquitecturas Adaptativas en Acción
Arquitecturas Adaptativas
en Requisitos
Deberían poderse instalar extensiones
de forma transparente en tiempo de
carga
Extensión Estática
Igualmente debería ser posible
adaptar los componentes en tiempo
de ejecución a nivel de clase e
instancia
Extensión Dinámicaimport C
C E
Importar
ExtensionExportar
Adaptación
31. Arquitecturas Adaptativas en Acción
Arquitecturas Adaptativas
en Requisitos
La construcción de soluciones adaptativas
debería basarse en la mera aplicación de
extensiones de catálogo.
Extensión Modular
Las extensiones implementan patrones de
composición por medio de la adaptación
de los componentes del entorno
Extensión Compositiva
Catálogo de
Extensiones
Catálogo de
Componentes
Patrón de
composición
32. Arquitecturas Adaptativas en Acción
Arquitecturas Adaptativas
en Requisitos
La instalación de extensiones sobre
componentes debería ser un proceso
reversible y permutable
Extensión Reversible
La actividad adaptativa es una cuestión de
perspectivas. Una extensión es también
un artefacto candidato a ser adaptado
Extensión Recurrente
A B CB
Eliminar y seguir
operando
A B C
33. Arquitecturas Adaptativas en Acción
Arquitecturas Adaptativas
en Requisitos
La lógica adaptativa implementada dentro
de cada extensión debería poder ser
configurable por parámetros ambientales
Extensión Contextual
Origami
Chameleon
PROD
TEST
TEST
PROD
Comportamiento
Paramétrico
34. Arquitecturas Adaptativas en Acción
Fran Diana Jorge
Component
Developer
Me dedico a crear sistemas de
componentes para mi compañía.
Trato que mis diseños maximicen su
reutilización
Extension
Developer
Mi labor es definir lógica de
extensión adaptativa que fomente la
reutilización de los componentes de
nuestro catálogo
Product
Developer
Mi trabajo consiste en consumir
componentes y extensiones del
catálogo y crear productos
alucinantes
Los Roles de
Origami Chameleon
35. Arquitecturas Adaptativas en Acción35
Diseño de Extensiones
Adaptativas
Traits
Roles
Subjects
Mixins
Aspects
Lo que resulta fantástico de Origami Chameleon es
que me permite centrarme en diseñar la lógica
adaptativa de nuestro catálogo de extensiones sin
preocuparme de cómo ésta será instalada
Diana
36. Arquitecturas Adaptativas en Acción
Modelo de Mixins
MIXINS
Cada extensión
se añade como
clase base
Las extensiones
aparecen en el
contrato público
@Mixin
class Storable {
constructor (core) {
this.core = core
this.load ()
}
@Override load () {}
@Override save () {}
}
@Mixin
class Showable {
constructor (core) {
this.core = core
this.show ()
}
@Discard show () {}
@Discard hide () {}
}
Diseño de Extensiones
Adaptativas
37. Arquitecturas Adaptativas en Acción37
TRAITS
this
this
Modelo de Traits
Las extensiones
aparecen en el
contrato público
Cada extensión
gestiona su
propio contexto
@Trait
class Sequenceable {
constructor (core) {
this.core = core
this.size = this.max-this.min
}
@Before previous() { this.core.value-- }
@Before next () { this.core.value++ }
}
@Trait
class Randomizable {
constructor (core) {}
@Before change() {
let r = random (2)
isOdd(r) && this.previous();
!isOdd(r) && this.next();
}
}
Diseño de Extensiones
Adaptativas
38. Arquitecturas Adaptativas en Acción38
ASPECTOS
Modelo de Aspectos
Las extensiones
se enganchan a
hooks
provided
except
before
around
after
fnfn
A cada función se
añade hooks de
intercesión
const Previous = 'previous'
const Next = 'next'
@Aspect
class Notifiable {
constructor (core) {}
@Before(Previous) fn(){ fire(Previous) }
@Before(Next) gn(){ fire(Next) }
}
const ANY = '*'
@Aspect
class Async {
constructor (core) {}
@Around(Any) async(fn, ...args){
return new Promise(function (ok, ko) {
setTimeout (function () {
ok(fn(...args))
}, 0)
})
}
}
Diseño de Extensiones
Adaptativas
39. Arquitecturas Adaptativas en Acción39
SUBJECTS
Modelo de Subjects
Las extensiones
aparecen en el
contrato público
Las extensiones
se acceden
desde una
puerta trasera
@Subject
@Point('Views')
class Views {
constructor (core) {}
get view ( ){}
set view (n){}
set views(views){}
}
@Subject
@Point('Events')
class Events {
constructor (core){}
bind (type, fn) {}
unbind (type, fn) {}
fire (e){}
} Utils(core).Events
.bind (Click, (e)=>{})
.bind (Focus, (e)=>{})
.fire (e)
Utils(core).Views.view =
3
Diseño de Extensiones
Adaptativas
40. Arquitecturas Adaptativas en Acción40
ROLES
Modelo de Roles
Los eventos de
salida son
notificaciones
emitidas desde
el core
Los eventos del core
mueven el ciclo de
vida reactivo
in
out
init
inject
e1
e2
init(ctx)
inject(ctx)
e3
resolve
@Role
class Rendering {
@State
@Begin
@Guard ('load')
@Route ('data' , 'context')
@Route ('error', 'error')
resolve(){}
@State
@Route ('context', 'context')
@Route ('error' , 'data')
context(){}
@State @End
render(){}
@State @End
error(){}
}
Diseño de Extensiones
Adaptativas
41. Arquitecturas Adaptativas en Acción41
Diseño de Componentes
Adaptativos
Extensiones
Componentes
Para mi lo verdaderamente formidable de Origami
Chameleon es lo sencillo que resulta diseñar
componentes de forma modular. Escojo unas cuantas
extensiones del catálogo e indico que quiero que
formen parte de mi componente
Fran
42. Arquitecturas Adaptativas en Acción42
COMPONENT
import Storable from ...
import Loggable from ...
@Component
@Extends(Storable)
@Extends(Loggable)
class Core {
constructor () {}
fx () {}
fy () {}
}
Las
extensiones se
instalan durante
la carga
El componente
se define como
extensible
Las extensiones se
importan como
módulos JS
El componente
está extendido
Core
Storable
Loggable
Diseño de Componentes
Adaptativos
EXTENDS
let cx = new Core ()
let cy = new Core ()
cx.load ()
cy.load ()
import C
Importar
ExtensionExportar
Componente
Extensión Estática Declarativa
Interna
43. Arquitecturas Adaptativas en Acción
import Reflect from Chameleon
import Storable from ...
import Loggable from ...
@Component
class Core {
constructor () {
if (isWeeked) {
Reflect(this).extensions
.install(Storable)
.install(Loggable)
}
}
fx () {}
fy () {
Reflect(this).extensions
.install(Sortable)
}
}
43
Extensión
dinámica
condicional
Core
Storable
Loggable
Extensión
dinámica
Diseño de Componentes
Adaptativos
REFLECT
import
import
Extensión Dinámica Imperativa
Interna
44. Arquitecturas Adaptativas en Acción
Componentes
44
Diseño de Productos
Adaptativos
Con Origami Chameleon he conseguido alcanzar
cotas de productividad que antes ni podía imaginar.
Los componentes de nuestro catálogo se descubren y
operan juntos con poco más que aproximarlos
Jorge
Extensiones
45. Arquitecturas Adaptativas en Acción45
Video CarouselSequenceable
Extensión a
nivel de Clase
sólo si video es
@Component
El Carousel es capaz
de mover cualquier
objeto Sequenceable
Diseño de Productos
Adaptativos
REFLECT
Extensión Estática Imperativa
Externa
import Reflect from Chameleon
import Carousel from ...
import Video from ...
import Sequenceable from ...
import
Reflect(Video).extensions
.install(Sequenceable)
.install(Showable)
let video = new Video()
let carousel = new Carousel(video)
carousel.start()
previous()
next()
new Video():v
install
new Carousel(v)
v.next()
v.previous()
46. Arquitecturas Adaptativas en Acción46
Extensión a
nivel de objeto
Solo la instancia video
es Sequenceable
Diseño de Productos
Adaptativos
REFLECT
Extensión Dinámica Imperativa
Externa
previous()
next()
new Video():v
install
new Carousel(v)
v.next()
v.previous()
import Reflect from Chameleon
import Carousel from ...
import Video from ...
import Sequenceable from ...
import
let video = new Video()
let carousel = new Carousel(video)
Reflect(video).extensions
.install(Sequenceable)
.install(Showable)
carousel.start()
Video
CarouselSequenceable
48. Arquitecturas Adaptativas en Acción48
Origami Chameleon en
Acción
Showable Zoomable Tiltable Minimizable
Example 01 - 04
Showable
Zoomable
Tiltable
Minimizable
on ()
off()
49. Arquitecturas Adaptativas en Acción49
Origami Chameleon en
Acción
Example 01 - 04
Showable
Zoomable
Tiltable
Minimizable
Example 05
Focussable
on ()
off()
on ()
off()
Focussable
ZoomableShowable Tiltable Minimizable
50. Arquitecturas Adaptativas en Acción50
Origami Chameleon en
Acción
Example 01 - 04
Showable
Zoomable
Tiltable
Minimizable
Example 05
Focussable
Example 06 - 07
Coordinable
on ()
off()
on ()
off()
ZoomableShowable Tiltable Minimizable
Coordinable
click click
Focussable
View BView A
51. Arquitecturas Adaptativas en Acción51
Origami Chameleon en
Acción
Example 01 - 04
Showable
Zoomable
Tiltable
Minimizable
Example 05
Focussable
Example 06 - 07
Coordinable
Example 08 - 09
Playable
Sequenceable
Runnable
on ()
off()
on ()
off()
ZoomableShowable Tiltable Minimizable
Coordinable
click click
Focussable
View B
Playable Runnable
next
previous ()
next ()
View A
Sequenceable
52. Arquitecturas Adaptativas en Acción52
State
Componentes
sólidos
Extensión
Adaptativa
Control
Adaptativo
Modelo de Arquitectura
en Origami Chameleon
A B C
Estado de la
Adaptación
Coordinación
Adaptativa
Condiciones
Ambientales