Um modelo para implementar métodos \| TreinaWeb               Promoção no ar   Matricule-se agora e garanta **54% de desconto**  

  Termina em   Tempo restante da oferta: 07 Horas 

 18 Min 

 58 Seg 

   Tempo restante da oferta: 07 18 58 

  [Assinar →](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26) 

   [                ](https://www.treinaweb.com.br)  Explorar  

 [ Quanto custa? ](#assinatura) [ FAQ ](https://www.treinaweb.com.br#faq) [Matricule-se](#assinatura) [ Entrar ](https://www.treinaweb.com.br/login) 

     [ Início ](https://www.treinaweb.com.br) [ Artigos ](https://www.treinaweb.com.br/blog) Um modelo para implementar métodos  [ Desenvolvimento ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento) 

# Um modelo para implementar métodos

 Veja nesse artigo um modelo sugerido para a implementação de um método, com a definição de algumas etapas para a melhor previsibilidade dele.

 [ Kennedy Tedesco ](https://www.treinaweb.com.br/blog/autor/kennedy-tedesco) 8 anos atrás

  ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/03/14203850/method-template.jpg)  

Em seu livro “*Style Guide for Object Design*”, *[Matthias Noback](https://matthiasnoback.nl/)* propõe um template muito interessante (mesmo que trivial, em certa perspectiva) para a implementação de métodos, que é:

[  ![PHP - Orientação a Objetos - Parte 2](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/php.svg)   Curso PHP - Orientação a Objetos - Parte 2 Conhecer o curso ](https://www.treinaweb.com.br/curso/php-orientacao-a-objetos-parte-2)

```php
[scope] function methodName(type name, ...): void|[return-type]
{
    1) [pre-conditions checks]

    2) [failure scenarios]

    3) [happy path]

    4) [post-condition checks]

    5) [return void|specific-return-type]
}

```

Apesar de os exemplos aqui serem escritos em [PHP](https://www.treinaweb.com.br/blog/o-que-e-php/ "O que é PHP?") (usando a sintaxe do PHP 7.4), não importa qual linguagem você utiliza, esse modelo e os insights que ele pode gerar são aplicáveis de forma genérica em qualquer linguagem que suporte [orientação a objetos](https://www.treinaweb.com.br/blog/os-pilares-da-orientacao-a-objetos/ "Os pilares da orientação a objetos").

Na etapa de “**Pre-condition checks**” devemos verificar se os argumentos recebidos estão corretos, se chegou o que se espera receber. É uma etapa essencial, principalmente quando estamos lidando com dados primitivos (o que é bastante comum em linguagens dinâmicas). É nela que realizamos verificações óbvias e simples, por exemplo, se o valor inteiro a ser recebido tem que ser maior que zero, se o array recebido só possui instâncias de uma determinada classe etc.

Supondo que temos um *command method* de um *service object* para disparar o envio de um e-mail. Ele precisa receber o e-mail para o qual se dará o envio. Seguindo a recomendação de pre-condition check faríamos assim:

```php
public function sendEmail(string $email) : void
{
    if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
        throw new InvalidArgumentException('E-mail inválido.');
    }
}

```

Podemos simplificar essa verificação usando alguma assertion library. Por exemplo, usando a [assert](https://github.com/beberlei/assert):

```php
public function sendEmail(string $email) : void
{
    Assertion::email($email, 'E-mail inválido.');
}

```

Não passando, uma exceção do tipo *InvalidArgumentException* é lançada. O legal desse tipo de library é que já possuem diversas validações e deixam nossas classes menos verbosas (ademais, tais validações também são comuns e úteis nos construtores das classes).

Outro exemplo muito interessante, principalmente no caso do PHP que não implementa uma forma de receber num argumento uma lista de objetos de uma determinada classe:

```php
public function fromEvents(array $events) : void
{
  Assertion::allIsInstanceOf($events, EventInterface::class);
}

```

Essa validação visa garantir que todos os itens do array sejam instâncias de *EventInterface*. Sem a facilidade da library, o método ficaria mais verboso:

```php
public function fromEvents(array $events) : void
{
  foreach ($events as $event) {
    if ( ! $event instanceof EventInterface) {
      throw new InvalidArgumentException('Class X was expected to be instanceof of Y but is not.');
    }
  }
}

```

Voltando ao exemplo do método `sendEmail()`, se você implementa algum *Value Object* em seu projeto, essa etapa de validação do dado estará no construtor dele, não precisando ser feita no método que irá recebê-lo como argumento. Então, vamos supor que no nosso projeto ao invés de recebermos o e-mail como um tipo primitivo, passássemos a recebê-lo como um *Value Object*:

```php
final class EmailAddress
{
    private string $email;

    public function __construct(string $email)
    {
        Assertion::email($email);

        $this->email = $email;
    }

    // ...
}

class SomeService
{
    public function sendEmail(EmailAddress $email) : void
    {
        // ...
    }
}

$service = new SomeService();
$service->sendEmail(new EmailAddress('user@domain.com'));

```

Note que, nesse modelo, nem precisamos fazer a checagem do que estamos recebendo, pois temos a garantia de que estamos recebendo um endereço de e-mail válido.

[  ![Drupal - Criação de Sites Avançado](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/drupal-sites.svg)   Curso Drupal - Criação de Sites Avançado Conhecer o curso ](https://www.treinaweb.com.br/curso/drupal-criacao-de-sites-avancado)

Mesmo que o dado recebido tenha passado na primeira checagem, o uso dele pode nos levar à condições de falha. No caso do exemplo acima, só validar o e-mail não garante que o envio dele se dará com sucesso. Alguma condição externa pode influenciar no insucesso da operação. É aqui que entra a etapa de “**Failure scenarios**”. E alguns métodos costumam fazer muito mais o uso dessa etapa mais que todas as outras.

Supondo que temos um *Repository* que precisa retornar os dados de um usuário a partir do ID dele:

```php
class UserRepository
{
    public function findById(int $id) : array
    {
        Assertion::greaterThan($id, 0, 'O ID precisa ser maior que zero.');

        $row = $this->database->where('id', $id)->first();

        if (null === $row) {
            throw new RuntimeException("Não foi possível encontrar o usuário de id {$id}");
        }

        return $row;
    }
}

```

Primeiro, o método verifica se recebeu um inteiro positivo maior que zero, caso contrário uma *InvalidArgumentException* é lançada. Posteriormente, ele verifica se o registro foi encontrado na base de dados e, não sendo, uma exceção do tipo *RuntimeException* é lançada (ademais, o problema agora não é relacionado à validez do argumento recebido, uma condição externa ao método que nos levou a ela).

Outro hipotético exemplo:

```php
public function sendEmail(string $email) : void
{
  Assertion::email($email, 'E-mail inválido.');

  $mail = new Mailer();
  $mail->setHtml('body');

  $result = $email->send($email);

  if ($result === false) {
    throw new RuntimeException('Houve um erro ao enviar o e-mail');
  }
}

```

Ao chegar na etapa “**happy path**”, sabemos que está tudo ocorrendo bem na execução do método. O argumento é válido e nenhuma condição externa nos levou à exceções. É nessa parte que podemos desenvolver alguma operação ou, na maioria das vezes, nem se faz muita coisa nela. É muito comum os métodos de consulta (*query methods*) serem simples o suficiente ao ponto de já retornarem o que se propõem a retornar e no caso dos métodos de comando (*command methods*) grande parte do corpo deles se passam nas verificações dos cenários de falhas (*failure scenarios*).

Na etapa de “**Post-condition checks**” podemos verificar se o método realmente concluiu o seu propósito. Se for um método de consulta, o valor a ser retornado primeiro pode ser avaliado, por exemplo. Na prática, a maioria dos métodos nem precisam desse tipo de verificação, testes unitários conseguem suprir a previsibilidade do retorno da execução de um método e o tipo retornado (principalmente se você usa *strict types* para argumentos e retornos).

Um exemplo genérico e prototipado:

```php
public function someMethod(int $someValue) : int
{
  // 1) [pre-conditions checks]

  // 2) [failure scenarios]

  $result = 0; // 3) [happy path]

  Assertion::greaterThan(0, $result); // 4) [post-condition checks]

  return $result; // 5) [return]
}

```

Em linhas gerais, as recomendações na construção de métodos são um equilíbrio entre: se você encontrou um cenário falho, lance uma exceção o mais rápido possível. Se você já tem o valor a ser retornado, retorne-o o mais rápido possível, para evitar o aumento da complexidade do método ou até mesmo para não dar chance de alterar erroneamente esse valor antes de retorná-lo.

Se o modelo acima deve ser seguido fielmente? Não, na maioria dos casos 1, 2 ou 3 etapas acima são suficientes para se construir um método. Em vários outros cenários você pode decidir primeiro focar em fazer o retorno o mais rápido possível e lançar uma exceção em caso contrário. Por exemplo:

```php
class ValidateSignature
{
    public function handle(Request $request, Closure $next) : Response
    {
        if ($request->hasValidSignature()) {
            return $next($request);
        }

        throw new InvalidSignatureException;
    }
}

```

Vai depender da sua sensibilidade. O ideal é um equilíbrio entre um método bem desenvolvido, que cheque bem as informações que recebe, que lance exceções o mais rápido quando as coisas claramente não estão indo bem, mas que também não fique enorme e difícil de ser lido. Muitas vezes sacrificar a legibilidade por etapas desnecessárias pode não ser tão frutífero.

Até a próxima!

[  ![Desenvolvedor PHP Sênior](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/php.svg)   Formação Desenvolvedor PHP Sênior Conhecer a formação ](https://www.treinaweb.com.br/formacao/desenvolvedor-php-senior)

Autor

 ![Kennedy Tedesco](//secure.gravatar.com/avatar/236c86e9469327ba7a9250ff15fef424?d=mm)

## Kennedy Tedesco

 Head de desenvolvimento. Vasta experiência em desenvolvimento Web com foco em PHP. Graduado em Sistemas de Informação. Pós-graduando em Arquitetura de Software Distribuído pela PUC Minas. Zend Certified Engineer (ZCE) e Coffee Addicted Person (CAP). [@KennedyTedesco](https://twitter.com/KennedyTedesco) 

 [Todos os artigos](https://www.treinaweb.com.br/blog/autor/kennedy-tedesco)  

## Continue estudando

 Transforme leitura em prática com os cursos e formações da TreinaWeb.

 [Ver cursos](https://www.treinaweb.com.br/cursos)   

  Continue lendo

## Artigos relacionados

- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/05/como-instalar-o-csharp-e-nosso-primeiro-exemplo-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     4 anos atrás

    ##  [ Orientação a objetos no C# ](https://www.treinaweb.com.br/blog/orientacao-a-objetos-no-csharp) 

     Aprenda como trabalhar com classes, atributos, métodos e objetos no C# e aumente seus conhecimentos nessa linguagem incrível!

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/03/o-que-e-fastapi-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     4 anos atrás

    ##  [ Criando o primeiro CRUD com FastAPI ](https://www.treinaweb.com.br/blog/criando-o-primeiro-crud-com-fastapi) 

     Neste artigo nós iremos aprender um pouco mais sobre o FastAPI durante o desenvolvimento de uma API com todas as operações de CRUD.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/05/spring-framework-400x280.png)  [ Java ](https://www.treinaweb.com.br/blog/categoria/java) 

     6 anos atrás

    ##  [ O que é Spring Framework? ](https://www.treinaweb.com.br/blog/o-que-e-spring-framework) 

     Confira neste artigo o Spring framework: um ecossistema de desenvolvimento para facilitar a criação de aplicações Java.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/07/ASD-400x280.png)  [ Engenharia de Software ](https://www.treinaweb.com.br/blog/categoria/engenharia-de-software) 

     6 anos atrás

    ##  [ O que é ASD - Adaptative Software Development? ](https://www.treinaweb.com.br/blog/o-que-e-asd-adaptative-software-development) 

     Confira neste artigo o ASD - Adaptive Software Development e como esta metodologia procura facilitar o desenvolvimento de softwares.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/05/01125223/react-php-imagem-400x280.png)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     8 anos atrás

    ##  [ Introdução à programação assíncrona em PHP usando o ReactPHP ](https://www.treinaweb.com.br/blog/introducao-a-programacao-assincrona-em-php-usando-o-reactphp) 

     Uma introdução à programação assíncrona com PHP e uso básico dos componentes do ReactPHP.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2017/06/utilizando-o-firebase-authentication-em-uma-aplicacao-android-400x280.png)  [ Android ](https://www.treinaweb.com.br/blog/categoria/android) 

     10 anos atrás

    ##  [ Utilizando o Firebase Authentication em uma aplicação Android ](https://www.treinaweb.com.br/blog/utilizando-o-firebase-authentication-em-uma-aplicacao-android) 

     Veja como implementar o Firebase Authentication em uma aplicação Android, usando o Android Studio.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/05/background-post-400x280.jpg)  [ Algoritmos ](https://www.treinaweb.com.br/blog/categoria/algoritmos) 

     10 anos atrás

    ##  [ Complexidade ciclomática, análise estática e refatoração ](https://www.treinaweb.com.br/blog/complexidade-ciclomatica-analise-estatica-e-refatoracao) 

     Veremos nesse artigo como se dá a mensuração da complexidade ciclomática; como os analisadores estáticos podem nos auxiliar e a importância da refatoração.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/11/12132017/introducao-swoole-400x280.png)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     7 anos atrás

    ##  [ Trabalhando com corrotinas, canais e explorando um pouco mais o scheduler de corrotinas do Swoole ](https://www.treinaweb.com.br/blog/trabalhando-com-corrotinas-canais-e-explorando-um-pouco-mais-o-scheduler-de-corrotinas-do-swoole) 

     Neste artigo trabalharemos com os conceitos fundamentais de corrotinas, canais, defer etc, também exploraremos algumas opções do scheduler como, por exemplo, fazê-lo operar de forma preemptiva.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/08/22125738/capa-impacto-software-organizacoes-modernas-400x280.png)  [ Tecnologia ](https://www.treinaweb.com.br/blog/categoria/tecnologia) 

     7 anos atrás

    ##  [ O impacto do software nas organizações modernas ](https://www.treinaweb.com.br/blog/o-impacto-do-software-nas-organizacoes-modernas) 

     Hoje, software tem o poder de definir o destino de organizações inteiras, ressaltando a importância de profissionais na área de desenvolvimento de software.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/05/linguagens-paradigmas-400x280.jpg)  [ Desenvolvimento ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento) 

     10 anos atrás

    ##  [ Linguagens e paradigmas de programação ](https://www.treinaweb.com.br/blog/linguagens-e-paradigmas-de-programacao) 

     Saiba um pouco mais sobre as linguagens de programação e seus principais paradigmas.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/01/06185133/corrotina-codigo-php-400x280.png)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     7 anos atrás

    ##  [ Corrotinas e código assíncrono em PHP usando Generators ](https://www.treinaweb.com.br/blog/corrotinas-e-codigo-assincrono-em-php-usando-generators) 

     Veja como generators podem ser utilizados para criar um simples scheduler e trabalhar com corrotinas no PHP.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/09/04112944/DJANGO-PROJETOS-PYCHARM-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     3 anos atrás

    ##  [ Como criar comandos customizados no Django ](https://www.treinaweb.com.br/blog/como-criar-comandos-customizados-no-django) 

     Aprenda a criar comandos customizados no Django para automatizar tarefas, personalizar funcionalidades e integrar sistemas externos!

     Ler artigo

## Um ano de acesso total para você viver de programação.

 Todos os cursos e formações da TreinaWeb numa única assinatura, com professores que atuam no mercado, suporte direto e certificados. Do primeiro `console.log` ao mercado de trabalho.

- **1 ano** de acesso a **todos os cursos**
- Cursos novos **toda semana**
- Suporte **direto com professores**
- Plano de carreira **personalizado**
- **Certificados digitais** inclusos
- **Aplicativos** para Android e iOS, com **acesso offline**

    **Garantia incondicional de satisfação** 

 Teste por 7 dias e, se não fizer sentido para você, devolvemos seu dinheiro.

### Acesso completo a todos os cursos e dezenas de Formações.

 12 meses 

  Economize R$ 840,00  54% OFF 

 de 12x R$ 129,00 por apenas

 12x  R$ 59,00

 sem juros no cartão de crédito ou R$ 599,00 à vista

  Oferta termina em  **07h 18min 58s**

- Acesso imediato e ilimitado durante 1 ano.
- Plano de carreira personalizado.
- Suporte direto com professores.
- E muito mais!

 [Matricule-se agora](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26)

     [                ](https://www.treinaweb.com.br)

 Escola online de programação, tecnologia e IA.

- [  ](https://www.facebook.com/TreinaWeb/)
- [  ](https://www.instagram.com/treinaweb/)
- [  ](https://www.youtube.com/user/TreinaWeb)
- [  ](https://twitter.com/treinaweb)
- [  ](https://www.linkedin.com/company/treinaweb)
- [  ](https://github.com/treinaweb)

## Inscreva-se em nossa newsletter

Receba lançamentos, promoções e novidades.

   Seu nome     Seu WhatsApp     Seu melhor e-mail   Inscrever-se 

## Cursos

- [ Base para Devs ](https://www.treinaweb.com.br/categoria/base-para-devs)
- [ Front-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-front-end)
- [ Back-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-back-end)
- [ Mobile ](https://www.treinaweb.com.br/categoria/desenvolvimento-mobile)
- [ Bancos de Dados ](https://www.treinaweb.com.br/categoria/bancos-de-dados)
- [ Cloud ](https://www.treinaweb.com.br/categoria/cloud-computing)
- [ IA ](https://www.treinaweb.com.br/categoria/ia)
- [ E mais ](https://www.treinaweb.com.br/categoria/e-mais)
- [ Ver todos os cursos ](https://www.treinaweb.com.br/cursos)

## Conteúdo

- [ Formações ](https://www.treinaweb.com.br/formacoes)
- [ Projetos práticos ](https://www.treinaweb.com.br/projetos-praticos)
- [ Direto ao ponto ](https://www.treinaweb.com.br/direto-ao-ponto)
- [ Planos ](https://www.treinaweb.com.br#assinatura)
- [ Depoimentos ](https://www.treinaweb.com.br#depoimentos)
- [ Comunidade ](https://www.treinaweb.com.br#comunidade)
- [ Corpo docente ](https://www.treinaweb.com.br#docente)

## A empresa

- [ Sobre a TreinaWeb ](https://www.treinaweb.com.br#sobre)
- [ Perguntas frequentes ](https://www.treinaweb.com.br#faq)
- [ Vantagens de estudar na TreinaWeb ](https://www.treinaweb.com.br/vantagens-de-estudar-na-treinaweb)
- [ Cursos para empresas ](https://www.treinaweb.com.br/empresas)
- [ Sugira um novo curso ](https://www.treinaweb.com.br/sugerir-curso)
- [ Trabalhe conosco ](https://www.treinaweb.com.br/trabalhe-conosco)
- [ Artigos ](https://www.treinaweb.com.br/blog)
- [ Desenvolvedores e agentes ](https://www.treinaweb.com.br/developers)
- [ Contato ](https://www.treinaweb.com.br/contato)
- [ Política de privacidade ](https://www.treinaweb.com.br/politica-de-privacidade)
- [ Termos de uso ](https://www.treinaweb.com.br/termos-de-uso)

## Baixe nosso aplicativo

 [   Disponível na **App Store**  ](https://apps.apple.com/us/app/treinaweb/id1322729447) [   Disponível no **Google Play**  ](https://play.google.com/store/apps/details?id=br.com.treinaweb.mobile) 

  Av. Paulista, 1765, Conj 71 e 72 · Bela Vista · São Paulo · SP · 01311-200   © 2004 – 2026 TreinaWeb Tecnologia LTDA · CNPJ 06.156.637/0001-58
