{"id":10048,"date":"2023-12-12T11:10:40","date_gmt":"2023-12-12T14:10:40","guid":{"rendered":"https:\/\/elemarjr.com\/clube-de-estudos\/?post_type=artigos&#038;p=10048"},"modified":"2023-12-26T09:54:30","modified_gmt":"2023-12-26T12:54:30","slug":"o-modelo-de-dominio-deve-definir-mensagens-para-usuarios","status":"publish","type":"artigos","link":"https:\/\/elemarjr.com\/clube-de-estudos\/artigos\/o-modelo-de-dominio-deve-definir-mensagens-para-usuarios\/","title":{"rendered":"O Modelo de Dom\u00ednio Deve Definir Mensagens para Usu\u00e1rios?"},"content":{"rendered":"\n<p>No universo do desenvolvimento de software, especialmente quando discutimos <em>Domain-driven Design<\/em> (DDD), uma das quest\u00f5es que aparecem \u00e9: o modelo de dom\u00ednio deve incluir a responsabilidade de definir como as mensagens s\u00e3o apresentadas para o usu\u00e1rio? Esta quest\u00e3o \u00e9 mais profunda do que parece e toca na ess\u00eancia da arquitetura de software e do design centrado no dom\u00ednio.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Responsabilidade do Modelo de Dom\u00ednio<\/h2>\n\n\n\n<p><em>No Domain-driven Design<\/em>, o modelo de dom\u00ednio representa as regras de neg\u00f3cio e a l\u00f3gica fundamental do sistema que estamos construindo. Ele \u00e9 o cora\u00e7\u00e3o do neg\u00f3cio e deve ser preservado como tal. Mas considerem o seguinte cen\u00e1rio: uma viola\u00e7\u00e3o de regra de neg\u00f3cio ocorreu e uma mensagem de erro precisa ser comunicada. Onde e como essa defini\u00e7\u00e3o de mensagem deve ser feita?<\/p>\n\n\n\n<p>\u00c0 primeira vista, pode-se argumentar que o modelo de dom\u00ednio, sendo focado no neg\u00f3cio, n\u00e3o deve se preocupar com a interface do usu\u00e1rio (UI). Vamos ilustrar com um exemplo em C#:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" style=\"font-size:.875rem;line-height:1.25rem\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"public class Order\n{\n    public void AddProduct(Product product)\n    {\n        if (product == null) \n        {\n            throw new DomainException(&quot;Product cannot be null&quot;);\n        }\n\n        \/\/ Logic to add the product...\n    }\n}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\"><code><span class=\"line\"><span style=\"color: #81A1C1\">public<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">class<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #8FBCBB\">Order<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #81A1C1\">public<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">void<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">AddProduct<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">Product product<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">if<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">product<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">==<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">null<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #81A1C1\">throw<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">new<\/span><span style=\"color: #D8DEE9FF\"> DomainException<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">Product cannot be null<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">        <\/span><span style=\"color: #616E88\">\/\/ Logic to add the product...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>No exemplo acima, <code>DomainException<\/code> \u00e9 uma exce\u00e7\u00e3o espec\u00edfica do dom\u00ednio que carrega a mensagem sobre o que deu errado. A camada de apresenta\u00e7\u00e3o, por outro lado, capturaria essa exce\u00e7\u00e3o e decidiria como apresent\u00e1-la:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" style=\"font-size:.875rem;line-height:1.25rem\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"try\n{\n    order.AddProduct(null);\n}\ncatch (DomainException ex)\n{\n    userInterface.ShowError(ex.Message);\n}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\"><code><span class=\"line\"><span style=\"color: #81A1C1\">try<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">order<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">AddProduct<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #81A1C1\">null<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">catch<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">DomainException ex<\/span><span style=\"color: #ECEFF4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">userInterface<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">ShowError<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9\">ex<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">Message<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Aqui, a responsabilidade de mostrar a mensagem ao usu\u00e1rio est\u00e1 na camada de apresenta\u00e7\u00e3o, que pode variar conforme o dispositivo ou contexto, mantendo o modelo de dom\u00ednio intocado.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Interface de Usu\u00e1rio e Experi\u00eancia do Usu\u00e1rio<\/h2>\n\n\n\n<p>A experi\u00eancia do usu\u00e1rio (UX) \u00e9 moldada pela camada de apresenta\u00e7\u00e3o. Considere que um erro pode ser apresentado de maneira diferente num aplicativo web e num aplicativo m\u00f3vel. A camada de apresenta\u00e7\u00e3o deve ser adapt\u00e1vel para proporcionar a melhor experi\u00eancia poss\u00edvel, independentemente do ponto de contato com o usu\u00e1rio.<\/p>\n\n\n\n<p>Essa separa\u00e7\u00e3o de responsabilidades significa que, enquanto o modelo de dom\u00ednio prov\u00ea as regras e informa\u00e7\u00f5es necess\u00e1rias, a camada de apresenta\u00e7\u00e3o utiliza essas informa\u00e7\u00f5es para construir a UX.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Flexibilidade e Manutenibilidade<\/h2>\n\n\n\n<p>A ades\u00e3o a DDD e a segrega\u00e7\u00e3o entre dom\u00ednio e apresenta\u00e7\u00e3o resultam em uma arquitetura mais f\u00e1cil de manter e evoluir. Altera\u00e7\u00f5es na forma como as informa\u00e7\u00f5es s\u00e3o apresentadas n\u00e3o afetam o n\u00facleo de neg\u00f3cio, permitindo que melhorias e ajustes sejam feitos com menos esfor\u00e7o e custo.<\/p>\n\n\n\n<p>Para aprofundar o entendimento sobre DDD e design de UX, recomendo explorar obras como &#8220;Domain-Driven Design: Tackling Complexity in the Heart of Software&#8221; de Eric Evans e &#8220;Don&#8217;t Make Me Think&#8221; de Steve Krug, que abordam, respectivamente, os conceitos de design centrado no dom\u00ednio e as pr\u00e1ticas recomendadas para a experi\u00eancia do usu\u00e1rio.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclus\u00e3o<\/h2>\n\n\n\n<p>O modelo de dom\u00ednio em DDD deve focar em expressar as regras de neg\u00f3cio, enquanto a camada de apresenta\u00e7\u00e3o deve se responsabilizar pela experi\u00eancia do usu\u00e1rio. A comunica\u00e7\u00e3o entre essas camadas \u00e9 vital, mas cada uma possui suas responsabilidades espec\u00edficas. No design e desenvolvimento de software, \u00e9 crucial manter essa separa\u00e7\u00e3o para promover a flexibilidade, a manutenibilidade e, em \u00faltima an\u00e1lise, o sucesso do produto.<\/p>\n\n\n\n<p>Nos meus grupos de estudos e mentorias, estudamos esses conceitos detalhadamente e exploramos as melhores pr\u00e1ticas de DDD e UX para criar sistemas robustos e centrados no usu\u00e1rio.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">TL;DR<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>O modelo de dom\u00ednio em DDD foca nas regras e l\u00f3gicas de neg\u00f3cio e n\u00e3o deve se preocupar com a forma como as mensagens s\u00e3o apresentadas aos usu\u00e1rios.<\/li>\n\n\n\n<li>A experi\u00eancia do usu\u00e1rio \u00e9 responsabilidade da camada de apresenta\u00e7\u00e3o, que utiliza as informa\u00e7\u00f5es do modelo de dom\u00ednio para construir a interface de usu\u00e1rio.<\/li>\n\n\n\n<li>Segregar a l\u00f3gica de neg\u00f3cio da experi\u00eancia do usu\u00e1rio aumenta a manutenibilidade e a adaptabilidade do software, permitindo evolu\u00e7\u00f5es mais \u00e1geis e custos reduzidos de manuten\u00e7\u00e3o.<\/li>\n<\/ol>\n","protected":false},"featured_media":10037,"parent":0,"template":"","cursos":[12],"class_list":["post-10048","artigos","type-artigos","status-publish","has-post-thumbnail","hentry","cursos-ddd-do-jeito-certo"],"acf":[],"_links":{"self":[{"href":"https:\/\/elemarjr.com\/clube-de-estudos\/wp-json\/wp\/v2\/artigos\/10048","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/elemarjr.com\/clube-de-estudos\/wp-json\/wp\/v2\/artigos"}],"about":[{"href":"https:\/\/elemarjr.com\/clube-de-estudos\/wp-json\/wp\/v2\/types\/artigos"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/elemarjr.com\/clube-de-estudos\/wp-json\/wp\/v2\/media\/10037"}],"wp:attachment":[{"href":"https:\/\/elemarjr.com\/clube-de-estudos\/wp-json\/wp\/v2\/media?parent=10048"}],"wp:term":[{"taxonomy":"cursos","embeddable":true,"href":"https:\/\/elemarjr.com\/clube-de-estudos\/wp-json\/wp\/v2\/cursos?post=10048"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}