The Ifless Principle: Designing APIs Without Hidden Decisions

Introduction

One of the most dangerous lines of code isn’t the one that throws an exception — it’s the one that hides a decision.

As engineers, we often celebrate flexible methods: a single save() that “magically” knows when to insert or update, a send() that picks the right channel, or an approveOrReject() that decides the outcome. At first, it feels convenient. But hidden behind that convenience lives complexity, ambiguity, and a growing army of if-statements.

The problem with too many ifs is not only code readability. It’s that each of the multiple scenarios your team must design, test, and maintain. What looks like “just one more condition” can easily become exponential in cost.

Over time, I’ve adopted a design approach I call the ifless principle: instead of burying decisions in code, we make them explicit in the design of the API and in the domain itself.


The Ifless Principle

The idea is simple:

  • Don’t let your service decide what the user already knows.
  • Express different operations as different methods, commands, or entities, even if they initially share behavior.
  • Move intelligence into rich domain entities (following Domain-Driven Design), so that rules live where they belong.

In short: ifless is not about eliminating ifs, but about putting decisions in the right place.

Example 1: Save vs Insert/Update

❌ If-full version:

public void save(Order order) {
    if (order.getId() == null) {
        insert(order);
    } else {
        update(order);
    }
}

✅ Ifless version:

public void insert(Order order) { ... }
public void update(Order order) { ... }

Even if both methods are identical today, the design already anticipates that inserts and updates will evolve differently. More importantly, the caller knows the intent, so the service doesn’t have to guess.

Example 2: Approvals

If hidden in the service:

public void approveOrReject(Transaction tx, boolean approve) {
    if (approve) { ... } else { ... }
}

✅ Ifless API:

public void approve(Transaction tx) { ... }
public void reject(Transaction tx) { ... }

Each operation has its own lifecycle, rules, and evolution. Tests become more focused, and the API expresses intention clearly.

Example 3: Notifications

❌ Conditional channel selection:

notificationService.send(user, message, channel);

✅ Ifless separation:

emailNotification.send(user, message);
smsNotification.send(user, message);
pushNotification.send(user, message);

Instead of one method with multiple branching conditions, each channel implements its own rules. Adding a new channel doesn’t mean touching a giant switch-case.

Connection with Domain-Driven Design

In Domain-Driven Design (DDD), the domain model encapsulates the core logic. That means invariants (like “an order can only ship if it is paid”) should live inside the entity itself:

public class Order {
    public void ship() {
        if (!this.isPaid()) {
            throw new BusinessException("Order must be paid before shipping");
        }
        // proceed with shipping...
    }
}

Notice: there’s still an if — but it’s not scattered across services. It’s encapsulated in the place where the rule truly belongs: the Order entity.

This is ifless in spirit: decisions are modeled explicitly in the domain, not left to a god-service to decide.

Benefits of the Ifless Principle

    1. Clarity of API

    The method name tells you exactly what it does. No hidden branching.

    2. Reduced Test Explosion

    Each if doubles the number of possible execution paths. Removing ifs from services simplifies test design.

    Example: save() with insert/update needs at least 2 test suites; insert and update each need only 1.

    3. Evolution without Risk

    As requirements diverge, methods evolve independently. You don’t risk breaking insert logic while changing update.

    4. Alignment with SRP (Single Responsibility Principle)

    One method = one reason to change.

    5. Cleaner Architecture

    Services stay thin. Entities stay rich. Decisions are explicit.

    Trade-offs and Counterpoints

    No principle is universal. Ifless comes with its own costs:

    • Verbosity: You might end up with more methods or services, even when differences are minimal.
    • Client Burden: Sometimes, callers just want a convenient save(). Exposing too much detail can reduce ergonomics.
    • Breaking conventions: Frameworks like Hibernate and Spring Data already assume methods like save() or merge(). Going against the grain might surprise new developers.

    That’s why I see ifless not as a dogma, but as a compass. Use it when clarity, testability, and explicit design outweigh the convenience of a single method.

    Related Ideas and References


    Conclusion

    Every if has a cost. Not just in code complexity, but in testing, maintenance, and evolution.

    The ifless principle is about making decisions explicit in the design of your API and your domain. It’s about contracts that express intent without ambiguity.

    It doesn’t mean you’ll never write an if. It means your architecture won’t hide them in the wrong places.

    In the age of scaling startups with fewer resources, clarity in design is not a luxury — it’s survival.

    Nine Women Can’t Make One Baby: Why Smaller Software Teams Deliver More

    In software engineering, scaling a project doesn’t work the same way as scaling manufacturing. While hiring more developers can increase overall capacity, it doesn’t proportionally accelerate the delivery of a single feature or project. This insight was famously captured by Fred Brooks in The Mythical Man‑Month, where he observed that “adding manpower to a late software project makes it later” . Brooks illustrated the problem with an analogy: one woman can produce a baby in nine months, but nine women working together cannot produce a baby in one month . This law isn’t about biology — it’s about the inherent constraints of complex work.

    Why throwing people at a project often backfires

    Brooks’s law identifies three fundamental reasons why adding more people to a software project can actually slow it down:

    1. Ramp‑up time. New team members need time to learn the codebase and context. Experienced developers must stop what they’re doing to train newcomers, temporarily reducing productivity . In some cases, new hires even introduce bugs while still ramping up, pushing the project further from completion .
    2. Communication overhead. Coordination paths grow exponentially as the team grows. Each person must keep others informed, creating more meetings, emails and stand‑ups . The Nuclino blog visualizes this: a three‑person team has three communication links, but adding three more members increases the links to fifteen .
    3. Limited divisibility of tasks. Not all work can be partitioned into smaller pieces. Some tasks demand sequential design and integration. Brooks points out that many software tasks are inherently indivisible . The two‑pizza‑team article expands this: you can’t simply split a complex design problem into tiny independent tickets and expect the result to emerge organically .

    These forces mean that there is an upper limit to the productivity gains you can achieve by simply adding developers. At some point, coordination costs and integration complexity outweigh the benefit of having more hands on deck.

    The case for small, focused teams

    For decades, agile practitioners have advocated small, cross‑functional teams. Jeff Bezos famously framed Amazon’s two‑pizza team rule: if a team cannot be fed with two pizzas, it is too big . The rationale is that small teams minimize communication overhead, allow rapid decision‑making, and foster accountability. Harvard psychologist J. Richard Hackman also warned that larger groups suffer from process problems and dysfunctional dynamics.

    Research backs this up. Mike Cohn cites a study in which teams were asked whether their group was too large to achieve the best result. Nearly everyone agreed that teams become inefficient above five members . Analysing over 1,000 software projects, Kate Armel found that projects delivered by teams of four or fewer developers were far more cost‑efficient and had fewer defects than those built by larger teams . The data suggests that four to five people is a sweet spot for most agile projects.

    My own “magic number”: three developers

    After years of experimenting with different team compositions working as CTO at eits.com.br, I’ve discovered a pragmatic variation on this theme: three developers can deliver remarkable results during a two‑week sprint. With trios, communication paths are minimal (three links), the team can self‑organize without excessive coordination, and everyone has a clear sense of ownership. It’s easier to maintain shared context, perform peer reviews, and collaborate closely on design decisions. If you add more people, you inevitably introduce hand‑offs and waiting, and the time spent aligning increases faster than the productive time gained.

    This isn’t just about efficiency — it’s about creativity. Complex problem‑solving often benefits from deep focus and uninterrupted thought. When more developers are involved, everyone gravitates toward smaller sub‑tasks, and the holistic view of the solution can get fragmented. A trio can tackle architecture, coding and testing collaboratively while still preserving big‑picture coherence.

    Constraints outside the team

    Adding developers doesn’t just create internal coordination issues; it also assumes that there is enough parallelizable work to keep everyone busy. In practice, business requirements, product design and stakeholder input often limit throughput. If there aren’t enough well‑defined tasks, additional engineers either wait idle or start working on poorly defined work, increasing rework later. Similarly, creativity and solution design don’t scale linearly. Some problems require brainstorming and iterative design cycles that don’t benefit from extra hands.

    Mitigating the urge to scale up

    How can leaders resist the instinct to “manpower their way” out of a schedule slip? Here are some strategies:

    • Invest early. Brooks noted that adding developers late in a project is particularly harmful . If you anticipate needing more people, bring them in early when ramp‑up costs are easier to absorb.
    • Focus on talent, not headcount. Adding one highly experienced developer may yield more benefit than hiring several junior engineers. Good programmers require less ramp‑up and introduce fewer defects .
    • Prioritize architecture and requirements. Many delays stem from unclear requirements or architectural flaws. Spend time up front clarifying what needs to be built and how pieces will fit together. This reduces integration challenges later.
    • Keep teams autonomous. When multiple small teams work in parallel, ensure their interfaces are well-defined to minimize cross-team dependencies. Jeff Bezos’ decentralization mantra and the two‑pizza rule were born from this philosophy.

    Conclusion

    The baby metaphor endures because it cuts to the core of software project dynamics: you can’t compress all tasks simply by adding more people. There is a natural limit to how much work can be parallelized; beyond that, communication overhead, ramp‑up time and cognitive load drag the project down. Research suggests that small teams — typically four to five people — are optimal , and my own experience shows that three developers often deliver the best trade‑off between speed, quality and creativity.

    Before you attempt to “scale up” your team to meet a deadline, ask whether the extra hands will actually move the delivery forward or whether they’ll simply add more complexity. Sometimes the most effective strategy is to empower a small, focused team, give them clear goals, and trust them to deliver.

    Artigo "Integrando Flex com Java utilizando o BlazeDS" na Java Magazine 72

    Java Magazine 72

    Já está nas bancas o meu mais novo artigo sobre Java e Flex na revista Java Magazine!

    O nome do artigo é Integrando Flex com Java utilizando o BlazeDS, e como o título já diz, este artigo é para quem quer aprender integrar o Flex com Java.

    Foi escrito de forma bem detalhada com vários exemplos, incluindo a utilização dos serviços de mensageria do BlazeDS.

    Artigo "Interfaces de qualidade com Flex" na Java Magazine 68

    Java Magazine 68.

    Já está nas bancas meu artigo sobre Java e Flex na revista Java Magazine!

    O nome do artigo é Interfaces de qualidade com Adobe Flex. Ele é voltado para quem não conhece nada, ou está começando à aprender Flex e conhece um pouco de Java.

    No artigo Faço uma analogia entre a Linguagem ActionScript 3.0 e Java 5, apresento algumas formas de consumir dados e também como fazer que um código feito para executar na Web com o Flash Player, possa ser executado no Desktop sem alterar uma linha de código funcional.

    Estou por finalizar um próximo artigo, nesse o foco está em apresentar como utilizar o Flex em aplicações corporativas, integrando com SpringFramework e EJBs utilizando o JBoss.

    Sem mais, por favor deixe o seu feedback!

    Abraços.

    o/

    Flex: Um chat simples em menos de 20 linhas.

    Uma coisas mais excepcionais que o design do framework do Adobe Flex traz, é a facilidade de trabalhar com os serviços de mensageria. Toda a complexidade que existe nas soluções de mensageria como a do JMS do Java, no Flex, basicamente foi resumido ao <mx:Producer/> e <mx:Consumer/> (ver a documentação).

    Assim como os outros meios de comunicação do Flex ( HttpService, WebService, RemoteObject ) o Consumer e Producer precisam de uma funcionalidade no back-end, em específico o DataService que está usando. Como por exemplo, no Java o DataService mais comum que contém essa funcionalidade é o Live Cycle Data Services e o BlazeDS, este OpenSource. No PHP, tem o WebOrb for PHP.

    Como o título deste tópico informa, para provar que é muito simples trabalhar com mensageria no Flex, vamos criar um chat com nem 20 linhas (um total de linhas programadas e não de configuração) no Flex. Para tal façanha, primeiro escolha qual linguagem e DataService que irá utilizar no back-end. Eu estarei utilizando Java + BlazeDS.

    Partindo do princípio que o BlazeDS já está integrado ao Java e com as configurações básicas:

    1. O primeiro passo é criar um canal de comunicação para trafegar as mensagens. Para isso, no arquivo services-config.xml do BlazeDS, adicione o seguinte canal:

      [xml]

      [/xml]

      Esse é um canal de Streaming, e só irá funcionar se for executado em Http 1.1. Outra forma de utilizar os serviços de menssageria, é criar um canal AMF normal (AMFChannel) e ativar o polling, como no exemplo abaixo:

      [xml]

      true

      [/xml]

    2. Criado o canal, vamos criar o destination na qual irá utilizar o canal. Para isso, crie se não existir um arquivo no mesmo diretório do services-config.xml com o nome de messaging-config.xml, nele coloque o seguinte conteúdo:
    3. [xml]

      [/xml]

      Com o messaging-config.xml criado, é preciso informar ao services-config.xml que existem destinations de mensageria. Para isso adicione as linhas abaixo no services-config.xml:

      [xml]

      [/xml]

    4. Adicionado o destination (chatMessage), a configuração já está completa. Vamos agora criar a Interface do Chat junto com o Producer e Consumer (menos de 20 linhas):

      [xml]

      [/xml]

    Pronto! agora basta startar seu Container Web (no meu caso o TomCat) e abrir 2 browsers distintos e enviar as menssagens.
    Atenção com o Firefox, pois ele armazena a mesma session para abas diferentes, e por default, o BlazeDS suporta uma conexão por cliente.

    Para todo e qualquer erro, verifique sempre o console do Tomcat, ele sempre traz informações úteis para identificar os erros.

    [Download do Fonte]

    ChatApp

    Manifesto Flex Brasil

    [Saiba o que é o Manifesto Flex Brasil]

    Minhas principais contribuições para a comunidade:

    Post: Configurando Ambiente com Flex 2 e HelloWorld.
    Por que ele é relevante: Aprenda a montar um ambiente de desenvolvimento com Flex 2 e um HelloWorld.
    A quem ele se destina: Desenvolvedores inexperientes com Flex.

    Post: Simples Leitor de RSS
    Por que ele é relevante: Veja como em poucas linhas de código é possível fazer um leitor de RSS com Flex usando HttpService.
    A quem ele se destina: Desenvolvedores Flex em geral.

    Post: Adobe Flex – Brincando com Efeitos
    Por que ele é relevante: Veja como é fácil adicionar efeitos aos componentes Flex.
    A quem ele se destina: Desenvolvedores Flex em geral.

    Post: Trocando objetos entre Flex e PHP
    Por que ele é relevante: Faça uso de uma boa prática trocando objetos do tipo VO/DTO/TO entre Flex e PHP via RemoteObject.
    A quem ele se destina: Desenvolvedores Flex que usam PHP no back-end.

    Post: Censo Adobe Flex Developer
    Por que ele é relevante: Um pequena aplicação em Flex que armazena dados de desenvolvedores Flex.
    A quem ele se destina: Desenvolvedores Flex em geral.

    Post: Trabalhando com CSS no FlexBuilder 3
    Por que ele é relevante: Aprenda como criar estilos no Flex através de .css usando o FlexBuilder 3.
    A quem ele se destina: Desenvolvedores Flex que tem foco em design.

    Post: Proposta de Arquitetura com Adobe Flex e PHP usando Zend Framework
    Por que ele é relevante: Disponibilizo a comunidade uma proposta de desenvolvimento com Flex e PHP, para que possa padronizar, arquitetar o código usando boas práticas.
    A quem ele se destina: Desenvolvedores Flex que usam PHP no back-end.

    Post: Fórum FlexBrasil
    Por que ele é relevante: Uma alternativa a listas Flex-Brasil e FlexDev, e armazenamento de tópicos com intenção de ajudar novos desenvolvedores Flex.
    A quem ele se destina:
    Desenvolvedores Flex em geral.

    Post: Integrando Adobe Flex + BlazeDS + SpringFramework + Hibernate. [Parte1]  [Parte2]
    Por que ele é relevante: Mostro com detalhes como integrar frameworks de mercado mais famosos no mundo Java com Flex usando RemoteObjects.
    A quem ele se destina: Desenvolvedores Flex que usam Java no back-end.

    E agora eu passo a bola para o Eberton Consolim

    Integrando Adobe Flex + BlazeDS + SpringFramework + Hibernate – Uma Solução OpenSource para Sistemas Web. (Parte 2 – Final)

    Olá Pessoal!

    Primeiro lugar, quero agradecer a todos pelo feedback do post anterior, isto é motivante e me dá ânimo em concluir este, e outros que virão.

    Hoje o foco deste artigo é que você termine ele sabendo:

    Configurar os Beans do Spring através de annotations;

    Integrar o esquema de Beans do Spring com os services do Flex através de uma Factory;

    Configurar o Spring para usar o Hibernate para abstrair nosso banco de dados;

    Para isso vamos a uma breve introdução a estes poderosos frameworks

    Breve Introdução ao Spring

    spring

    Como não sou fã de ficar re-escrevendo a roda, vou tentar dar a você leigo em Spring, um caminho para estudar.

    Primeiro de tudo, leia este artigo feito pelo Phillip Calçado (Shoes)
    apostila-spring.pdf 
    Valeu
    Ebertom pela hospedagem! =)

    Uma Introdução ao que o  SpringFramework pode oferecer:
    http://blog.fragmental.com.br/2005/08/31/spring-em-acao/
    http://www.ime.usp.br/~reverbel/SMA/Slides/seminarios/spring.pdf
    http://imasters.uol.com.br/artigo/4497/java/spring_framework_introducao/

    Outros Tutoriais
    http://www.javafree.org/content/view.jf?idContent=46

    http://www.devmedia.com.br/articles/viewcomp.asp?comp=6627
    http://www.devmedia.com.br/articles/viewcomp.asp?comp=6628
    http://www.devmedia.com.br/articles/viewcomp.asp?comp=6653

    Spring Annotations
    http://blog.interface21.com/main/2006/11/28/a-java-configuration-option-for-spring/
    http://weblogs.java.net/blog/seemarich/archive/2007/11/annotation_base_1.html

    Exemplos de códigos
    http://paulojeronimo.com/arquivos/tutoriais/tutorial-spring-framework.zip
    http://www.java2s.com/Code/Java/Spring/CatalogSpring.htm

    Documentação
    The Spring Framework – Reference Documentation

    Bom acredito que se você que está afim de conhecer o SpringFramewok, com esses Link’s já é possível entender quase tudo o que ele pode oferecer a sua arquitetura. Lembrando que não é recomendável seguir com este artigo, sem antes entender como funciona  IoC, AOP, DAO, com o SpringFramework.

    *Nota A abordagem aqui é sobre o SpringFramework, (Framework de Negócio) e não sobre o SpringMVC, uma vez que o Flex pode se trocar objetos através do protocolo AMF3, é totalmente dispensável o uso de Frameworks MVC’s.

    Breve Introdução ao Hibernate

    Como eu já disse, uma vez que já existe um bom conteúdo sobre Hibernate na Internet, não há a necessidade de re-escrever, por isso vou lhe dar a você leigo em Hibernate uma sequência de Link que irá te ajudar a entender este poderoso Framework.

    Uma Introdução ao que o  Hibernate pode oferecer:
    http://www.students.ic.unicamp.br/~ra007271/docs/white-papers/hibernate-uma_introducao_dirigida.pdf
    http://www.guj.com.br/java.tutorial.artigo.125.1.guj
    http://www.jeebrasil.com.br/mostrar/4
    http://www.devmedia.com.br/articles/viewcomp.asp?comp=4149

    Outros Tutoriais
    http://simundi.blogspot.com/2007/09/criar-uma-aplicao-com-hibernate.html
    http://www.hibernate.org/hib_docs/v3/reference/en/html/queryhql.html
    http://www.hibernate.org/hib_docs/tools/reference/en/html/plugins.html
    http://www.guj.com.br/posts/list/7249.java

    Pacotão de PDF’s
    http://br.groups.yahoo.com/group/java-br/files/Hibernate/

    Exemplos de código
    http://www.java2s.com/Code/Java/Hibernate/CatalogHibernate.htm

    Documentação
    http://www.hibernate.org/hib_docs/v3/reference/en/html/

    Ok, partindo do princípio que você já entendeu como funciona o Hibernate, e o Spring, vamos ao código! +)

    Continue reading

    Integrando Adobe Flex + BlazeDS + SpringFramework + Hibernate – Uma Solução OpenSource para Sistemas Web. (Parte 1)

    Olá Pessoal,

    Hoje vou começar algo que estou prometendo há um bom tempo! A integração dos seguintes frameworks:

    Adobe Flex;

    Adobe BlazeDS;

    Spring Framework;

    Hibernate;

    Introdução

    No mundo de desenvolvimento WEB principalmente com Java, temos problemas quanto ao desenvolvimento de interfaces, como incompatibilidade entre browsers, desenvolviemento lento, e outros detalhes que muitos vivenciam diariamente.

    Existem soluções que prometem como o JSF por exemplo, mas como dizem “A primeira experiência em Flex o programador Java nunca esquece.” logo quero convidar você que vem do mundo do Java, para conhecer uma solução de desenvolvimento de interfaces com o AdobeFlex.

    Apresentando Adobe Flex e Adobe BlazeDS

    Adobe Flex

    Do Flex não vou falar muito, também por que neste blog você pode encontrar muito conteúdo explicativo como por exemplo este link: http://23.20.48.222/?p=32 algumas abordagens ali já estão desatualizadas, porém a essência é a mesma como por exemplo algumas vantagens de se usar Flex:

    O Flex é executado a partir de uma máquina virtual, logo o programador apenas se preocupa em desenvolver a interface não em programar compatibilidade entre browsers.

    Você programa sua interface totalmente orientada a objetos, isso visa reuso de componentes, desenvolvimento de módulos e afins.

    Há várias maneiras de comunicar o Java com o Flex, mas em destaque é que você pode trocar objetos Java/Flex por um protocolo que provê compactação e tranferência binária, este é o AMF.

    Adobe BlazeDS

    O BlazeDS é um produto OpenSource (Licença LGPL v3) que corresponde à tecnologia JAVA server-side que dá suporte tanto para o Remoting assim como ao Messaging de objetos trocados entre o Java e o Flex/Flash.

    Com o BlazeDS você pode gerar vários tipos de canais de conexão, um destaque muito importante para toda a comunidade Flex/Flash mundial, é que o serviço de data-push também foi disponibilizado de graça!, para quem não conhece, é algo semelhante ao Pattern Observer.

    Integrando o Adobe Flex com o BlazeDS

    Requerimentos:

    Eclipse 3.3;

    Adobe Flex Builder 3 Plugin;
    *No título apresento como solução OpenSource, e o FlexBuilder 3 é pago, mas irei fazer uso apenas para facilitar o entendimento, caso seja estudante, baixe o FlexBuilder 2 é de graça para estudantes ou afins, caso não, baixe o Flex SDK e compile com Ant ou com o FlashDeveloper que é de graça.

    Adobe BlazeDS;
    *É recomendável que baixe a documentação do BlazeDS, para futuros estudos.

    Tomcat 6.0;

    Ok, Vamos começar!

    Extraia o Eclipse 3.3 em algum lugar, por exemplo C:/Desenvolvimento/Eclipse 3.3/

    Instale o Plugin do Flex no Eclipse, quando pedir o local aonde instalar o flex sdk, você pode selecionar em C:/Desenvolvimento/Frameworks/Adobe/

    Após baixado o BlazeDS, perceba que ele vem vários arquivos, o que importa agora são os seguintes:

    blazeds-samples.war

    blazeds.war

    No blazeds-samples.war como o próprio nome diz, contém aplicações de exemplo, como implementação do data-push, um chat, e etc…

    O blazeds.war contém tudo o que é necessário para podermos configurar nossa aplicação.

    Você deve ter percebido que no arquivo que você baixou o BlazeDS, contém um Tomcat já com todas as libs necessárias e etc.. Algumas libs ali tem reelevância como a flex-tomcat-common.jar e flex-tomcat-server.jar mas vamos deixar isso para outro artigo =)

    Apesar do BlazeDS já vir com um Tomcat, eu estarei usando meu próprio Tomcat 6.0.

    Abra seu Eclipse, e faça como no screencast abaixo que mostra como criar seu projeto no Eclipse 3.3:

    Link Externo

    *Se na aba “Problems” estiver com o erro “Cannot create HTML wrapper. Right-click here to recreate folder html-template.” clique com o botão direito, e clique em Recreate HTML Templates. Considero isso um bug do FlexBuilder.

    Continue reading

    Forum sobre AdobeFlex!

    Olá Pessoal!!

    =)

    É com muito prazer que divulgo a todos que o forum sobre AdobeFlex ficou pronto! Está bem bacana, utilizamos o PhpBB3 que veio com um layout muito mais atrativo.

    http://forum.flexbrasil.com.br/

    O forum tem a intenção de unir mais a comunidade, e está voltado para aqueles:

    1. Que não conhece a tecnlogia;
    2. Que estão começando a aprender;
    3. Que já estão em um nível avançado;

     

    Acredito que ficou muito bom, pesso que entre e confira!! e também divulguem para que a comunidade cresça  o mais rápido o possível!

    Abraços e até mais!

    o/