• ARQUITETURA

  • MVC

  • DDD

  • SERVIÇOS VS ACTIONS

O que pretendemos

Arquitetura

* Arquitetura Orientada à Eventos,
* Microserviços e
* Monolitos

MVC (Model, views e controllers)

* Model
* Views
* Controllers

DDD (Model, views e controllers)

* Domínio e Modelagem do Domínio
* Linguagem Ubíqua
* Entidades, Value Objects e Aggregates
* Repositórios e Serviços
* Contextos Delimitados

Services vs Actions

* DRY - Don't Repeat Yourself (Não Se Repita)
* KISS - Keep It Simple, Stupid (Mantenha Simples, Estúpido)
* YAGNI - You Aren't Gonna Need It (Você Não Vai Precisar Disso)
* TDA - Tell, Don't Ask (Diga, Não Pergunte)

KISS

O acrônimo "Keep It Simple, Stupid" foi posteriormente adotado pela Marinha dos EUA em 1960. O conceito rapidamente transcendeu o contexto militar e encontrou aplicação em diversas áreas, incluindo o desenvolvimento de software.

– DEV.TO

 importância do KISS no desenvolvimento de software é multifacetada:

 

  • Manutenibilidade: Código simples é mais fácil de entender e modificar.
  • Depuração: Soluções simples apresentam menor superfície para bugs potenciais.
  • Integração de novos desenvolvedores: Profissionais recém-chegados ao projeto conseguem compreender e contribuir para o código mais rapidamente.
  • Desempenho: Soluções simples frequentemente apresentam melhor desempenho que alternativas complexas.
  • Adaptabilidade: Sistemas simples geralmente respondem melhor a novos requisitos.

Por que é importante?

  •  Subjetividade da simplicidade: O que é "simples" para um desenvolvedor pode ser complexo para outro. Essa subjetividade dificulta a aplicação consistente do princípio.
  • Simplificação excessiva: Em sistemas intrinsecamente complexos, soluções excessivamente simplificadas podem não abordar adequadamente a complexidade inerente do domínio.
  • Compromisso com desempenho: Soluções mais simples podem não oferecer o desempenho ideal. Em sistemas com requisitos rigorosos de performance, o KISS pode conduzir a soluções subótimas.

Críticas ao KISS

Estes quatro princípios (DRY, KISS, YAGNI e TDA) não existem isoladamente - eles se complementam e, quando aplicados com discernimento, criam uma abordagem holística para o desenvolvimento de software de qualidade.

 

  1. DRY + KISS: A eliminação de duplicação (DRY) frequentemente resulta em soluções mais simples (KISS).
  2. KISS + YAGNI: Manter a simplicidade (KISS) muitas vezes envolve evitar adicionar funcionalidades desnecessárias (YAGNI).

Integrando os Princípios em seu Desenvolvimento

Comece com KISS: Ao iniciar qualquer componente, busque a solução mais simples e direta possível.

– DICA MAROTA

  • Prado, L. P. (2017). O princípio Tell, Don't Ask. [Blog]. Disponível em: https://luizpauloprado.com.br/2017/01/04/o-principio-tell-dont-ask/

  • Fonseca Chaves, G. (2020). Conceito Tell, Don't Ask. LinkedIn. Disponível em: https://pt.linkedin.com/pulse/conceito-tell-dont-ask-guilherme-fonseca-chaves

  • Silva, R. (2019). Princípio Tell, Don't Ask. [Blog]. Disponível em: https://ramonsilva.net/post/princípio-tell-don-t-ask

  • Castilho, R. (2014). Tell, don't ask. [Blog]. Disponível em: https://robsoncastilho.com.br/2014/05/11/conceitos-tell-dont-ask/

  • Souza, U. (2022). KISS, YAGNI, DRY – três princípios que todo desenvolvedor deveria conhecer! DEV Community. Disponível em: https://dev.to/urielsouza29/kiss-yagni-dry-tres-principios-que-todo-desenvolvedor-deveria-conhecer-47gg

  • Thiagomr. (2020). Desvendando o mundo mágico dos acrônimos: SOLID, KISS, YAGNI, DRY, DDD, TDD. DEV Community. Disponível em: https://dev.to/thiagomr/desvendando-o-mundo-magico-dos-acronimos-solid-kiss-yagni-dry-ddd-tdd-2onp

BIOGRAFIA

exemplode kiss

kiss

ACTIONS VS/E SERVICES

Classe com um único método público (ex: CreateUser), ideal para comandos específicos.

ACTIONS






// app/Actions/CreateUser.php
class CreateUser {
    public function execute(array $data) {
        return User::create($data);
    }
}




// No Controller
public function store(Request $request, CreateUser $createUser) {
    $user = $createUser->execute($request->validated());
    return response()->json($user);
}


Classe com múltiplos métodos relacionados (ex: UserService com create, update, delete).

SERVICES

namespace App\Services;

use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class UserService
{
    // Método para criar um usuário com regras específicas
    public function createUser(array $data): User
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
            'api_token' => Str::random(60),
        ]);
    }

    // Método para atualizar perfil
    public function updateProfile(User $user, array $data): bool
    {
        // Lógica de negócio: validar se o e-mail já existe, etc.
        return $user->update($data);
    }
}

Uso: 

Actions são ótimas para tarefas complexas e orquestração.

Services são melhores para agrupar lógica de um domínio.

– Google IA

  • Testabilidade: Facilita o teste unitário de regras de negócio.
  • Limpeza: Controllers ficam finos (thin controllers).
  • Reutilização: Actions/Services podem ser chamados em Jobs, Controllers ou Artisan Commands.

benefícios

vamos aplicar na prática.

 

Aplicamos o princípio Keep It Simple, Stupid (KISS) combinando duas abordagens modernas de arquitetura Laravel — Actions (operações únicas e focadas) e Services (orquestração de regras de negócio) — dentro de um mesmo módulo. Essa estratégia híbrida permite granularidade onde necessário (Actions) e abstração onde conveniente (Services), resultando em código mais limpo, testável e adaptável às necessidades do domínio.

Primeiros passos

Criar o projeto laravel

migrations

configurar o MVC

Criar os Actions/Services

Erros

<?php


function funcao1() {
    echo "Entrando na função 1" . PHP_EOL;
    funcao2();
    echo "Saindo da função 1" . PHP_EOL;
}

function funcao2() {
    echo "Entrando na função 2" . PHP_EOL;
    for($i = 0; $i < 5; $i++) {
        echo $i . PHP_EOL;
    }
    echo "Saindo da função 2" . PHP_EOL;
}

echo "Iniciando o programa" . PHP_EOL;
funcao1();
echo "Finalizando o programa" . PHP_EOL;

* Resultado do programa

Porque um código tão simplório?

o que  está acontecendo

“Quote or citation”

<?php


function funcao1() {
    echo "Entrando na função 1" . PHP_EOL;
    funcao2();
    echo "Saindo da função 1" . PHP_EOL;
}

function funcao2() {
    echo "Entrando na função 2" . PHP_EOL;
    for($i = 0; $i < 5; $i++) {
        echo $i . PHP_EOL;
    }
    echo "Saindo da função 2" . PHP_EOL;
}

echo "Iniciando o programa" . PHP_EOL;
funcao1();
echo "Finalizando o programa" . PHP_EOL;

main

stack (pilha)

“Quote or citation”

<?php


function funcao1() {
    echo "Entrando na função 1" . PHP_EOL;
    funcao2();
    echo "Saindo da função 1" . PHP_EOL;
}

function funcao2() {
    echo "Entrando na função 2" . PHP_EOL;
    for($i = 0; $i < 5; $i++) {
        echo $i . PHP_EOL;
    }
    echo "Saindo da função 2" . PHP_EOL;
}

echo "Iniciando o programa" . PHP_EOL;
funcao1();
echo "Finalizando o programa" . PHP_EOL;

main

stack (pilha)

“Quote or citation”

<?php


function funcao1() {
    echo "Entrando na função 1" . PHP_EOL;
    funcao2();
    echo "Saindo da função 1" . PHP_EOL;
}

function funcao2() {
    echo "Entrando na função 2" . PHP_EOL;
    for($i = 0; $i < 5; $i++) {
        echo $i . PHP_EOL;
    }
    echo "Saindo da função 2" . PHP_EOL;
}

echo "Iniciando o programa" . PHP_EOL;
funcao1();
echo "Finalizando o programa" . PHP_EOL;

main

funcao1

stack (pilha)

“Quote or citation”

<?php


function funcao1() {
    echo "Entrando na função 1" . PHP_EOL;
    funcao2();
    echo "Saindo da função 1" . PHP_EOL;
}

function funcao2() {
    echo "Entrando na função 2" . PHP_EOL;
    for($i = 0; $i < 5; $i++) {
        echo $i . PHP_EOL;
    }
    echo "Saindo da função 2" . PHP_EOL;
}

echo "Iniciando o programa" . PHP_EOL;
funcao1();
echo "Finalizando o programa" . PHP_EOL;

main

funcao1

stack (pilha)

“Quote or citation”

<?php


function funcao1() {
    echo "Entrando na função 1" . PHP_EOL;
    funcao2();
    echo "Saindo da função 1" . PHP_EOL;
}

function funcao2() {
    echo "Entrando na função 2" . PHP_EOL;
    for($i = 0; $i < 5; $i++) {
        echo $i . PHP_EOL;
    }
    echo "Saindo da função 2" . PHP_EOL;
}

echo "Iniciando o programa" . PHP_EOL;
funcao1();
echo "Finalizando o programa" . PHP_EOL;

main

funcao1

funcao2

stack (pilha)

“Quote or citation”

<?php


function funcao1() {
    echo "Entrando na função 1" . PHP_EOL;
    funcao2();
    echo "Saindo da função 1" . PHP_EOL;
}

function funcao2() {
    echo "Entrando na função 2" . PHP_EOL;
    for($i = 0; $i < 5; $i++) {
        echo $i . PHP_EOL;
    }
    echo "Saindo da função 2" . PHP_EOL;
}

echo "Iniciando o programa" . PHP_EOL;
funcao1();
echo "Finalizando o programa" . PHP_EOL;

main

funcao1

funcao2

$i

stack (pilha)

“Quote or citation”

<?php


function funcao1() {
    echo "Entrando na função 1" . PHP_EOL;
    funcao2();
    echo "Saindo da função 1" . PHP_EOL;
}

function funcao2() {
    echo "Entrando na função 2" . PHP_EOL;
    for($i = 0; $i < 5; $i++) {
        echo $i . PHP_EOL;
    }
    echo "Saindo da função 2" . PHP_EOL;
}

echo "Iniciando o programa" . PHP_EOL;
funcao1();
echo "Finalizando o programa" . PHP_EOL;

main

funcao1

funcao2

$i

stack (pilha)

“Quote or citation”

<?php


function funcao1() {
    echo "Entrando na função 1" . PHP_EOL;
    funcao2();
    echo "Saindo da função 1" . PHP_EOL;
}

function funcao2() {
    echo "Entrando na função 2" . PHP_EOL;
    for($i = 0; $i < 5; $i++) {
        echo $i . PHP_EOL;
    }
    echo "Saindo da função 2" . PHP_EOL;
}

echo "Iniciando o programa" . PHP_EOL;
funcao1();
echo "Finalizando o programa" . PHP_EOL;

main

funcao1

stack (pilha)

“Quote or citation”

<?php


function funcao1() {
    echo "Entrando na função 1" . PHP_EOL;
    funcao2();
    echo "Saindo da função 1" . PHP_EOL;
}

function funcao2() {
    echo "Entrando na função 2" . PHP_EOL;
    for($i = 0; $i < 5; $i++) {
        echo $i . PHP_EOL;
    }
    echo "Saindo da função 2" . PHP_EOL;
}

echo "Iniciando o programa" . PHP_EOL;
funcao1();
echo "Finalizando o programa" . PHP_EOL;

main

stack (pilha)

“Quote or citation”

<?php


function funcao1() {
    echo "Entrando na função 1" . PHP_EOL;
    funcao2();
    echo "Saindo da função 1" . PHP_EOL;
}

function funcao2() {
    echo "Entrando na função 2" . PHP_EOL;
    for($i = 0; $i < 5; $i++) {
        echo $i . PHP_EOL;
    }
    echo "Saindo da função 2" . PHP_EOL;
}

echo "Iniciando o programa" . PHP_EOL;
funcao1();
echo "Finalizando o programa" . PHP_EOL;

stack (pilha)

pra que aprender pilha?

nós entendemos o que é e como funciona a pilha de execução do PHP.

Fonte: Alura

usando

 

try ... catch ... finally

como tratar esses erros?

Models

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Consultation extends Model
{
    //
    protected $fillable = [
        'data_horario',
        'valor',
        'paciente',
        'medico',
        'status'
    ];
}

O atributo $fillable dentro de um Model no Laravel serve para definir quais colunas da tabela do banco de dados podem ser preenchidas em massa (mass assignment). Ele é uma medida de segurança essencial para proteger sua aplicação contra a inserção indevida ou maliciosa de dados, garantindo que apenas campos específicos definidos no array sejam populados ao usar métodos como create() ou update(). 

# fillable

Às vezes pode ser difícil determinar todos os atributos e relacionamentos disponíveis de um modelo apenas examinando rapidamente seu código. Em vez disso, experimente o comando model:show Artisan, que fornece uma visão geral conveniente de todos os atributos e relações do modelo:

# Inspecionando Modelos


php artisan model:show Consultation

controllers

# controllers


php artisan make:controller

ConsultationsControllers

# Resource

O padrão CRUD representa as quatro operações fundamentais de armazenamento persistente em sistemas de informação: Create (Criar), Read (Ler/Consultar), Update (Atualizar) e Delete (Excluir). Ele organiza logicamente as interações entre o usuário e o banco de dados, sendo essencial para desenvolver funcionalidades de cadastro e manipulação de dados.

Escolha um models relacional

<?php

namespace App\Http\Controllers;

use App\Models\Consultation;
use Illuminate\Http\Request;

class ConsultationsController extends Controller
{
    
    public function index()
    {
        //
    }

    
    public function create()
    {
        //
    }

    
    public function store(Request $request)
    {
        //
    }

    
    public function show(Consultation $consultation)
    {
        //
    }

    
    public function edit(Consultation $consultation)
    {
        //
    }

    
    public function update(Request $request, Consultation $consultation)
    {
        //
    }

    
    public function destroy(Consultation $consultation)
    {
        //
    }
}
<?php

namespace App\Http\Controllers;

use App\Models\Consultation;
use Illuminate\Http\Request;

class ConsultationsController extends Controller
{
    
    public function index()
    {
        $consultations = Consultation::get();
        
        return $consultations;
    }

    
    public function create()
    {
        //
    }

    
    public function store(Request $request)
    {
        //
    }

    
    public function show(Consultation $consultation)
    {
        //
    }

    
    public function edit(Consultation $consultation)
    {
        //
    }

    
    public function update(Request $request, Consultation $consultation)
    {
        //
    }

    
    public function destroy(Consultation $consultation)
    {
        //
    }
}

Captura os dados a partir do modelo que tem relação da entidade DB.

Como eu posso visualizar o que o controllers está disponibilizando?

ROUTES

# routes


php artisan route:list

Descrição das rotas do sistema.

# resource (restfull)

<?php

use App\Http\Controllers\ConsultationsController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});

Route::resource('consultations', ConsultationsController::class);

Sempre fazer o apontamento da class

tentem fazer o view (visão)

services


php artisan make:class ConsultationsServices 

# services


php artisan make:class Services\\ConsultationsServices 

E agora?

VocÊ deve incorporar no controller caso necessite do serviço!

actions

O princípio SRP (Single Responsibility Principle - Princípio da Responsabilidade Única), que é o primeiro dos cinco princípios do SOLID.

 

"Cada classe deve ter um, e somente um, motivo para mudar."


php artisan make:class ConsultationsAction 

# Actions


php artisan make:class Actions\\ConsultationsAction

qual a diferença entre services e actions?

Actions não tem estado

logo a class pode ser static

Criar consulta com os principios:

 

* migrate

* models (attributes)

* controllers (actions/services)

* views

Desafio