{"id":81,"date":"2020-04-30T10:00:00","date_gmt":"2020-04-30T15:00:00","guid":{"rendered":"http:\/\/80bits.blog\/?p=81"},"modified":"2020-04-30T00:03:52","modified_gmt":"2020-04-30T05:03:52","slug":"atomic-design-con-flutter-metodologia-de-diseno","status":"publish","type":"post","link":"https:\/\/80bits.blog\/index.php\/2020\/04\/30\/atomic-design-con-flutter-metodologia-de-diseno\/","title":{"rendered":"Atomic Design con flutter. Metodolog\u00eda de dise\u00f1o"},"content":{"rendered":"\n<p>Por efectos de la pandemia me he puesto aprender un mont\u00f3n de cosas y entre estas esta programar en Flutter\/Dar, quise hacer un desarrollo siguiendo una metodolog\u00eda que se llama <strong>Atomic Design<\/strong> o dise\u00f1o at\u00f3mico.<\/p>\n\n\n\n<p><strong>Disclaimer:<\/strong> <em>Puesto que estoy aprendiendo ambas cosas a la vez tanto flutter como el modelo de dise\u00f1o at\u00f3mico, es probable que tenga errores en cuanto a dise\u00f1o concepto e implementaci\u00f3n,<\/em> as\u00ed que si\u00e9ntete libre de comentarlos y o de corregir el c\u00f3digo en GitHub.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Flutter<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"937\" height=\"461\" src=\"http:\/\/80bits.blog\/wp-content\/uploads\/2020\/04\/flutter_logo.png\" alt=\"\" class=\"wp-image-99\"\/><figcaption>Flutter Logo<\/figcaption><\/figure>\n\n\n\n<p>Es un framework\/SDK desarrollado por google para crear aplicaciones multiplataforma tales como: Androi, iOS, Web, y es el Framework oficial de su nuevo sistema Fuchsia, el cual aun no ve la luz, pero bueno es otra historia, se distingue por crear interfaces de usuario de una forma declarativa usando c\u00f3digo, nada de estar editando xml, xaml o story boards y por su alto rendimiento grafico.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dart<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"560\" height=\"315\" src=\"http:\/\/80bits.blog\/wp-content\/uploads\/2020\/04\/dart_logo.png\" alt=\"Dart Logo\" class=\"wp-image-101\"\/><figcaption>Dart Logo<\/figcaption><\/figure>\n\n\n\n<p>Es un lenguaje de programaci\u00f3n orientado a objetos igualmente creado por google, en la web se podr\u00eda decir que es una competencia a TypeScript.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Atomic<em> <\/em>Design<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"800\" height=\"192\" src=\"http:\/\/80bits.blog\/wp-content\/uploads\/2020\/04\/atomic_design.jpg\" alt=\"Atomic Design\" class=\"wp-image-84\"\/><figcaption>Atomic Design by genitalico<\/figcaption><\/figure>\n\n\n\n<p>Es una metodolog\u00eda que propone la separaci\u00f3n del dise\u00f1o basado en elementos modulares para poder reutilizarlos, pero parte de la primicia en la que cada elemento debe funcionar tanto individualmente como en conjunto, esta metodolog\u00eda fue creada por <a rel=\"noreferrer noopener\" href=\"https:\/\/bradfrost.com\/\" target=\"_blank\">Brad Frost.<\/a><\/p>\n\n\n\n<p>No quiero explayarme mucho en que es cada cosa, ya que en las respectivas webs lo explican mucho mejor as\u00ed que pasemos a lo divertido.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Login Atomico<\/h2>\n\n\n\n<p>Empece dise\u00f1ando la vista mas sencilla del mundo es la siguiente:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"411\" height=\"731\" src=\"http:\/\/80bits.blog\/wp-content\/uploads\/2020\/04\/login_example_atomic_design.jpg\" alt=\"Ejemplo Login\" class=\"wp-image-88\"\/><figcaption>Ejemplo Login by genitalico<\/figcaption><\/figure>\n\n\n\n<p>Esta vista consta de solo 5 elementos, que son: <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Imagen <\/li><li>Campo correo <\/li><li>Campo contrase\u00f1a <\/li><li>Circulo de progreso <\/li><li>Bot\u00f3n entrar<\/li><\/ul>\n\n\n\n<p>Estos los voy a separar en \u00e1tomos de acuerdo al modelo at\u00f3mico como sigue:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Campo de Texto<\/li><li>Imagen<\/li><li>Circulo de progreso<\/li><li>Boton<\/li><\/ul>\n\n\n\n<p>Como es una ventana muy simple la separaci\u00f3n de elementos quedo de manera similar a un dise\u00f1o tradicional, pero tal cual deje los elementos en el c\u00f3digo estos pueden ser altamente reutilizados.<\/p>\n\n\n\n<p>El mockup del desarrollo at\u00f3mico final quedo c\u00f3mo sigue.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"800\" height=\"600\" src=\"http:\/\/80bits.blog\/wp-content\/uploads\/2020\/04\/mockup_atomicds.jpg\" alt=\"Mockup Atomic Design\" class=\"wp-image-89\"\/><figcaption>Mockup Atomic Design by gen\u00e9tico<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">C\u00f3digo<\/h2>\n\n\n\n<p>Flutter tiene similitudes con ReactJS en cuanto a los estados de los componentes en este caso son los widgets incluso ambos tiene un m\u00e9todo setState, en flutter <em>todo es un widget qu\u00e9dense con eso<\/em>.<\/p>\n\n\n\n<p>Hay dos clases interesantes en flutter <em>StatelessWidget<\/em> y <em>StatefulWidget<\/em>, la primera es para widgets sin estado, esto es widgets o hablando de la interfaz son elementos que no mutan al igual que por ejemplo un objeto inmutable en POO, de hecho es lo mismo a nivel de c\u00f3digo. El segundo es un elemento que va a mutar, a nivel visual es un elemento que dada algunas condiciones cambiara, por ejemplo de color blanco a rojo etc.<\/p>\n\n\n\n<p><strong><em>La version de flutter que use es la 1.12.13+hotfix9 y dart 2.7.2.<\/em><\/strong><\/p>\n\n\n\n<p>El c\u00f3digo para esa vista es bastante simple mas all\u00e1 de la complejidad de flutter para crear los elementos pero a nivel arquitectura y siguiendo la metodolog\u00eda de dise\u00f1o at\u00f3mico, lo deje de la siguiente manera:<\/p>\n\n\n\n<p><em>Sobre la estructura de nombres fue lo mejor que se me ocurri\u00f3 para agilizar el post y no ahondar mucho en buenas practicas.<\/em><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Atomos<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">TextFieldStandard1<\/h4>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"411\" height=\"150\" src=\"http:\/\/80bits.blog\/wp-content\/uploads\/2020\/04\/TextFieldStandard1.jpg\" alt=\"\" class=\"wp-image-107\"\/><\/figure>\n\n\n\n<p>Es el dise\u00f1o de uno de los campos de texto, el cual recibe algunos par\u00e1metros:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>hintText. Es el texto que se muestra pero se oculta cu\u00e1ndo se escribe dentro.<\/li><li>prefixIcon. Es el icono que se muestra a la izquierda del campo.<\/li><li>obscureText. Este es un valor boleado que oculta el texto en puntos, ideal para contrase\u00f1as y que lo pongo en true en el campo de password.<\/li><li>textColor. Es el color del hinText.<\/li><li>controller. Es un objeto de tipo TextEditingController y lo uso para para recoger el valor que se escriba dentro del campo.<\/li><li>onTap. Es un tipo VoidCallback que a su vez es solo un alias para una funci\u00f3n sin retorno, este sirve para implementar alg\u00fan evento cuando toquen el campo.<\/li><li>FocusNode. Objeto que sirve para obtener o aplicar foco a un elemento, este me sirve para solventar un problema de dart.<\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">CPIStandard1<\/h4>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"411\" height=\"150\" src=\"http:\/\/80bits.blog\/wp-content\/uploads\/2020\/04\/CPIStandard1.jpg\" alt=\"CPIStandard1\" class=\"wp-image-106\"\/><\/figure>\n\n\n\n<p>Este es el circulo de progreso animado, es bastante simple y solo esta envuelto en una clase Opacity, esto por que necesitaba una manera de ocultarlo, mostrarlo y manteniendo su espacio en el dise\u00f1o, as\u00ed que solo recibe un par\u00e1metro para esta acci\u00f3n.:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>opacity. Es un valor double que en este caso representa el nivel de opacidad, que va de 0 a 1, para este caso 1 es mostrar 0 ocultar.<\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">BtnStandard1<\/h4>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"411\" height=\"150\" src=\"http:\/\/80bits.blog\/wp-content\/uploads\/2020\/04\/BtnStandard.jpg\" alt=\"\" class=\"wp-image-111\"\/><\/figure>\n\n\n\n<p>Simplemente es el bot\u00f3n y recibe los par\u00e1metros:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>color. Color de fondo.<\/li><li>textColor. El color del texto<\/li><li>text. El texto del bot\u00f3n.<\/li><li>onPressed. Tipo VoidCallback para pasar la funci\u00f3n a ejecutar cuando se toque el bot\u00f3n.<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Moleculas<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">EmailPassword<\/h4>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"411\" height=\"150\" src=\"http:\/\/80bits.blog\/wp-content\/uploads\/2020\/04\/login_password.jpg\" alt=\"login password by genitalico\" class=\"wp-image-114\"\/><figcaption>login password by genitalico<\/figcaption><\/figure>\n\n\n\n<p>Esta es la \u00fanica mol\u00e9cula en este dise\u00f1o y consta de dos \u00e1tomos que reciben distintos par\u00e1metros, esta mol\u00e9cula para no enredarme y terminar r\u00e1pido internamente instancia y pasa par\u00e1metros para los \u00e1tomos, aqu\u00ed lo ideal deber\u00eda ser, tener objetos para pasar los valores a cada \u00e1tomo y encapsular estos en dos objetos a pasar como valor a la mol\u00e9cula, puesto que as\u00ed podemos ir de arriba hacia abajo pasando mensajes al construir una plantilla u organismo. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Widget build(BuildContext context) {<br>  \/\/ <em>TODO: implement build<br><\/em><em>  <\/em>return Column(<br>    children: &lt;Widget&gt;[<br>      TextFieldStandard1(<br>          hintText: \"Correo\",<br>          prefixIcon: Icons.<em>mail<\/em>,<br>          controller: _emailController,<br>          onTab: _onTap,<br>          textColor: _emailColor,<br>          focusNode: focusNodeEmail),<br>      SizedBox(height: 15),<br>      TextFieldStandard1(<br>          hintText: \"Contrase\u00f1a\",<br>          prefixIcon: Icons.<em>lock<\/em>,<br>          controller: _passwordController,<br>          onTab: () {},<br>          obscureText: true)<br>    ],<br>  );<br>}<\/pre>\n\n\n\n<p>Esta mol\u00e9cula es de tipo <em>StatefulWidget<\/em> debido a que el campo de correo cambia de color a rojo cuando van a presionar el bot\u00f3n y a blanco cuando tocan el campo mismo, de los dos \u00e1tomos es el \u00fanico que se recrea cuando cambia el estado de la mol\u00e9cula.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Organismo<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Login<\/h4>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" src=\"http:\/\/80bits.blog\/wp-content\/uploads\/2020\/04\/login_example_atomic_design.jpg\" alt=\"Ejemplo Login\" class=\"wp-image-88\" width=\"240\" height=\"427\" title=\"\"\/><\/figure>\n\n\n\n<p>Teniendo todo lo anterior es como se construye el organismo compuesto de un \u00e1tomo imagen, el cual no vi la necesidad de extender ya que el objeto de imagen tiene el mismo prop\u00f3sito para esto.<\/p>\n\n\n\n<p>El objeto es de tipo <em>StatefulWidget<\/em>, ya que este es el que controlara todo el flujo de cambios, con excepciones no todos los objetos internos se reconstruyen cuando el estado de este organismo cambia.<\/p>\n\n\n\n<p>Aqu\u00ed el \u00fanico widget que cambia y se reconstruye es el Circulo de progreso que pasa de estar oculto a mostrarse, todo lo dem\u00e1s se instancia una sola vez.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Widget build(BuildContext context) {<br>  double _marginlr = MediaQuery.<em>of<\/em>(context).size.width * 0.07;<br>  \/\/ <em>TODO: implement build<br><\/em><em>  <\/em>return Container(<br>    margin: EdgeInsets.only(left: _marginlr, right: _marginlr),<br>    child: Column(<br>      mainAxisAlignment: MainAxisAlignment.center,<br>      children: &lt;Widget&gt;[<br>        AspectRatio(<br>          aspectRatio: 1.7,<br>          child: Image(<br>            image: AssetImage(\"assets\/images\/80bitslogo.png\"),<br>          ),<br>        ),<br>        SizedBox(height: 60),<br>        this._emailPassword,<br>        SizedBox(height: 15),<br>        CPIStandard1(opacity: this._opacity),<br>        SizedBox(height: 15),<br>        _btn1<br>      ],<br>    ),<br>  );<br>}<\/pre>\n\n\n\n<p>Para esto ultimo me di la libertad de que el organismo ya estuviera totalmente construido, tanto a nivel dise\u00f1o como a nivel de instancia de los otros objetos colores, texto, etc, esto por la rapidez en que necesitaba programar.<\/p>\n\n\n\n<p>La pregunta es como se sube de nivel hacia una plantilla?, pues mi idea es que en flutter puesto que es POO, al menos desde mi perspectiva una plantilla puede ser un organismo como es mi caso o el conjunto de organismos con la diferencia es que si son dos o mas seria una instancia separada donde se unan los organismos, aqu\u00ed la cuesti\u00f3n radicara que habr\u00e1 que hacer modelos para pasar par\u00e1metros y construir todo lo que se tenga que mostrar, colores, texto, etc.<\/p>\n\n\n\n<p>As\u00ed que una plantilla en mi opini\u00f3n quedar\u00eda como un objeto flutter que recibe sus par\u00e1metros y este los comunica hasta los \u00e1tomos.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"800\" height=\"600\" src=\"http:\/\/80bits.blog\/wp-content\/uploads\/2020\/04\/dibujo_plantilla.png\" alt=\"dibujo plantilla by genitalico\" class=\"wp-image-118\"\/><figcaption>dibujo plantilla by genitalico<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Problemas<\/h2>\n\n\n\n<p>Debido a que llevo aproximadamente 20 d\u00edas aprendiendo flutter no estuve exento de problemas, uno de estos fue con la idea que tenia de que en mi mol\u00e9cula de campos solo se reconstruyera el campo de correo para obtener mejor performance y ahorrar memoria, <em>muy m\u00ednima pero hay ahorro<\/em>.<\/p>\n\n\n\n<p>La idea parte de que el campo contrase\u00f1a es un objeto constante que no necesita cambia durante todo el ciclo de la vista, por lo que en en tiempo de compilaci\u00f3n de hacen las optimizaciones necesarias para ahorrar memoria.<\/p>\n\n\n\n<p>Pues bien al existir dos o mas campos y uno de ellos va a cambiar su estado, flutter tiene un problema con el &#8220;foco&#8221; y falla al momento de un rebuild y truena toda la vista, el issue ya lo tienen en mente para ser resuelto, pueden ver la discusi\u00f3n <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/flutter\/flutter\/issues\/52221\" target=\"_blank\">aqu\u00ed<\/a> y una soluci\u00f3n <a rel=\"noreferrer noopener\" href=\"https:\/\/flutter.dev\/docs\/cookbook\/forms\/focus\" target=\"_blank\">aqu\u00ed<\/a>.<\/p>\n\n\n\n<p>Mi soluci\u00f3n y si no quieres usar lo que proponen en la web de flutter es que la mol\u00e9cula se recree cada vez eso genera que ambos \u00e1tomos se vuelvan a instanciar pero el de correo con un color distinto y para eso cambiar a un widget sin estado la mol\u00e9cula, claro que ah\u00ed se perder\u00eda el performance de solo instanciar uno y para ser honesto es indiferente en tel\u00e9fonos actuales que se construyan dos objetos nuevamente en lugar de uno, aparte que el GC actuara de manera eficiente liberando memoria.<\/p>\n\n\n\n<p>Finalmente la vista de login quedo de la siguiente manera.<\/p>\n\n\n\n<figure style=\"width:30%\" class=\"wp-block-video\"><video autoplay=\"\" loop=\"\" muted=\"\" src=\"http:\/\/80bits.blog\/wp-content\/uploads\/2020\/04\/loginds.mp4\"><\/video><\/figure>\n\n\n\n<p>Si llegaste hasta aqu\u00ed, toma el <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/genitalico\/atomic_design_example\" target=\"_blank\">c\u00f3digo!<\/a><\/p>\n\n\n\n<p>Se libre de dejar tus comentarios y hacer un full request.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Fuentes<\/h4>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/atomicdesign.bradfrost.com\/table-of-contents\/\" target=\"_blank\">Libro online Atomic Design<\/a><\/p>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/flutter-es.io\/\" target=\"_blank\">Flutter<\/a><\/p>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/dart.dev\/\" target=\"_blank\">Dart<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/es.wikipedia.org\/wiki\/Google_Fuchsia\" target=\"_blank\" rel=\"noreferrer noopener\">Fuchsia<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ejemplo de dise\u00f1o at\u00f3mico con el framework flutter.Dise\u00f1o de \u00e1tomos, mol\u00e9culas, y plantillas. Atomic design es una metologia de dise\u00f1o<\/p>\n","protected":false},"author":1,"featured_media":87,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[10,7,21,13,12,23,22,11,20,1],"tags":[8,6,27,25,24,9],"class_list":["post-81","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android","category-apps","category-dart","category-dev","category-escritorio","category-flutter","category-frameworks","category-ios","category-lenguajes-de-programacion","category-sin-categoria","tag-android","tag-apps","tag-atomic-design","tag-dart","tag-flutter","tag-ios"],"jetpack_featured_media_url":"https:\/\/80bits.blog\/wp-content\/uploads\/2020\/04\/heather-gill-Ub2JHFkIXWc-unsplash.jpg","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/posts\/81","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/comments?post=81"}],"version-history":[{"count":34,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/posts\/81\/revisions"}],"predecessor-version":[{"id":139,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/posts\/81\/revisions\/139"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/media\/87"}],"wp:attachment":[{"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/media?parent=81"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/categories?post=81"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/tags?post=81"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}