Slide 1

Slide 1 text

BOAS PRÁTICAS COM PHP novidades e como melhorar a escrita de código

Slide 2

Slide 2 text

Sou Junior Grossi twitter.com/junior_grossi github.com/jgrossi

Slide 3

Slide 3 text

Paciência!

Slide 4

Slide 4 text

https://github.com/corcel/corcel

Slide 5

Slide 5 text

http://conf.phpmg.com

Slide 6

Slide 6 text

https://glofox.com/careers

Slide 7

Slide 7 text

◽ 2004 php ◽ 2016 ◽

Slide 8

Slide 8 text

QUALIDADE DE CÓDIGO Facilita manutenção Aumenta a velocidade de desenvolvimento Menos retrabalho

Slide 9

Slide 9 text

PARTE 1 PHP ANTES E DEPOIS Os últimos 10 anos da linguagem mais usada na Web!

Slide 10

Slide 10 text

PHP ARCHITECT Nov/2018 | Volume 17 | Issue 11

Slide 11

Slide 11 text

PHP EM 2019 Linguagem mais usada na Web (~80%) Só o WordPress é responsável por ~34% Muito problema pra resolver (mais empregos)

Slide 12

Slide 12 text

BOOM DE FW: ~2005-2007 O PHP já aprendeu e ainda aprende com os erros Muita coisa já veio e já foi Qualquer semelhança com JS é mera coincidência

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

PHP 5.3 (2009) O DIVISOR DE ÁGUAS NAMESPACES + LAMBDA FUNCTIONS/CLOSURES (Mudanças no processo interno de releases do PHP)

Slide 15

Slide 15 text

REQUEST FOR COMMENTS (RFC) https://wiki.php.net/rfc

Slide 16

Slide 16 text

NAMESPACES Classes não podiam ter o mesmo nome HtmlPrinter, Zend_HtmlPrinter class Zend_HtmlPrinter { public function print(); }

Slide 17

Slide 17 text

namespace DevStarter\Talks; use Foo\Exporter\Exporter; use Zend\Html\Exporter as ZendExporter; class PhpTalk { public function export() { $fooExporter = new Exporter(); $zendExporter = new ZendExporter(); // ... } } https://wiki.php.net/rfc/namespacecurlies

Slide 18

Slide 18 text

LAMBDA FUNCTIONS/CLOSURES Antes do PHP 5.3 A partir do PHP 5.3 $array = array_map('append_x', $array); function append_x($item) { return $item . 'x'; } $array = array_map(function ($item) { return $item . 'x'; }, $array);

Slide 19

Slide 19 text

Nova geração de frameworks (surgimento dos primeiros micro-frameworks) (execução tardia) $router­>get('/users/{id}', function ($id) { return User::find($id); }); $function = function ($word) { echo $word . ' World!'; } $function('Hello'); // "Hello World!"

Slide 20

Slide 20 text

2012 PHP 5.4 + COMPOSER ANO DAS MAIORES MUDANÇAS (Mudou de vez a comunidade PHP)

Slide 21

Slide 21 text

PHP 5.4 Traits Shortened array syntax Melhoria de performance + menos consumo de memória Built-in Web Server

Slide 22

Slide 22 text

TRAITS trait Flyable { public function fly() { // Go, fly! } } trait Walkable { public function walk() { // Go, walk! } } class Bird { use Flyable, Walkable; } class Chicken { use Walkable; } $bird = new Bird(); $chicken = new Chicken(); $bird­>walk(); $bird­>fly(); $chicken­>walk();

Slide 23

Slide 23 text

SHORTENED ARRAY SYNTAX Antes do PHP 5.4 Depois do PHP 5.4 $numbers = array(1, 2, 3); $associative = array('name' => 'Junior', 'age' => 34); $numbers = [1, 2, 3]; $associative = ['name' => 'Junior', 'age' => 34];

Slide 24

Slide 24 text

BUILT-IN WEB SERVER Não é necessário mais um Web server pra desenvolvimento > php ­S localhost:8000

Slide 25

Slide 25 text

COMPOSER Package Manager oficial do PHP http://getcomposer.org

Slide 26

Slide 26 text

COMPOSER Resolveu o problema do Ctr C + Ctr V + controle de versões

Slide 27

Slide 27 text

COMPOSER Resolveu o problema dos require > composer require cakephp/database require 'database.php'; require 'pdf.php'; require 'mail.php'; require 'mail­2.php'; require 'mail­98.php'; require 'mail­xp.php'; require 'mail­millenium.php'; $database = db_query('SELECT * FROM users');

Slide 28

Slide 28 text

/composer.json { "name": "jgrossi/corcel", "description": "Use WordPress backend with Laravel or any PHP framework", "homepage": "http://github.com/corcel/corcel", "authors": [ { "name": "Junior Grossi", "email": "juniorgro@gmail.com" } ], "require": { "php": ">=7.1.3", "illuminate/database": "5.7.*", "hautelook/phpass": "0.3.*", "thunderer/shortcode": "^0.6.2" }, "require­dev": { "phpunit/phpunit": "^7.0", "mockery/mockery": "^1.0" }, "autoload": { "psr­4": { "Corcel\\": "src/", "Corcel\\Tests\\": "tests/" } } }

Slide 29

Slide 29 text

PACKAGIST http://packagist.org

Slide 30

Slide 30 text

AUTOLOADING + NAMESPACES use Corcel\Model\Post;

Slide 31

Slide 31 text

PHP-FIG PSR (PHP STANDARD RECOMMENDATION) code style, autoload, interfaces padronizaram a toda

Slide 32

Slide 32 text

https://www.php-fig.org

Slide 33

Slide 33 text

PSR-7 PSR-11 namespace MyFramework\Http; use Psr\Http\Message\RequestInterface; class Request implements RequestInterface { } namespace MyFramework\Container; use Psr\Container\ContainerInterface; class Container implements ContainerInterface { }

Slide 34

Slide 34 text

PHP 5.5 E 5.6 ANTES DA GRANDE MUDANÇA (2013 e 2014) Adiciona scalar class name resolution via ::class Adiciona finally para exceptions Melhoria de performance (Zend OPcache) Outras mudanças...

Slide 35

Slide 35 text

PHP 7 TUDO NOVO, DE NOVO!

Slide 36

Slide 36 text

PERAÍ, E O PHP 6?

Slide 37

Slide 37 text

https://wiki.php.net/rfc/php6

Slide 38

Slide 38 text

PHP 7 (2015) Nova Zend Engine (v3) 2x mais rápido que PHP 5 50% menos de consumo de memória

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

PHP 7.0 UNIFORM VARIABLE SYNTAX // Before $foo = new Foo(); $baz = $foo­>bar(); // After $baz = (new Foo())­>bar(); // Before $foo = $foo­>bar(); echo $foo[0]; // After echo $foo­>bar()[0];

Slide 42

Slide 42 text

PHP 7.0 NULL COALESCE OPERATOR: ?? // Before $age = isset($data['age']) ? $data['age'] : 100; // After $age = $data['age'] ?? 100;

Slide 43

Slide 43 text

PHP 7.0 ⭐ RETURN TYPE DECLARATIONS ⭐ ⭐ SCALAR TYPE DECLARATIONS ⭐ (opcional) // Before public function create($sum, $title) { // your code here } // After public function create(float $sum, string $title): float { // your code here }

Slide 44

Slide 44 text

STRICT TYPES = 1 declare(strict_types=1); namespace Foo\Printer; class CsvPrinter implements PrinterInterface { public function __construct(string $foo, float $bar) { // ... } }

Slide 45

Slide 45 text

PHP 7.0 GROUP USE DECLARATIONS // Before use Package\Http\Request; use Package\Http\Response; use Package\Http\Middleware; use Package\Http\BaseController as Controller; // After use Package\Http\{ Request, Response, BaseController as Controller };

Slide 46

Slide 46 text

PHP 7.1, 7.2 E 7.3 void return type class constant visibility modifiers nullable types the object parameter and return type Libsodium extension abstract method overriding

Slide 47

Slide 47 text

class User { private const TYPE_ADMIN = 'admin'; protected const TYPE_MEMBER = 'member'; public const TYPE_GUEST = 'guest'; } public function save(object $object, ?int $age): void { // do something and return nothing }

Slide 48

Slide 48 text

NOVIDADES: PHP 7.4 NOV/2019 Preloading* Short closures Typed properties Improved type variance The null coalescing assignment operator muito mais!

Slide 49

Slide 49 text

PHP 7.4 SHORT CLOSURES array_map(function (User $user) use ($prefix) { return $prefix . $user­>id; }, $users) array_map(fn(User $user) => $prefix . $user­>id, $users)

Slide 50

Slide 50 text

PHP 7.4 TYPED PROPERTIES ANTES class Foo { /** @var int $bar */ private $bar; /** @var callable $bar */ private $function; /** @var string|null $bar */ protected $baz; /** @var array $bar */ public $list; }

Slide 51

Slide 51 text

PHP 7.4 TYPED PROPERTIES DEPOIS class Foo { private int $bar = 4; private callable $function; protected ?string $baz = null; public array $list = [1, 2, 3]; }

Slide 52

Slide 52 text

PHP 8 ❤ JIT (just in time) compiler (vídeo do Zeev)

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

CONSIDERAÇÕES FINAIS PHP é uma das linguagens mais maduras Excelente performance (e vai melhorar!) Desenvolvimento muito rápido!

Slide 55

Slide 55 text

PHP DO JEITO CERTO http://br.phptherightway.com/

Slide 56

Slide 56 text

PHP É FODA SIM!

Slide 57

Slide 57 text

PARTE 2 CLEAN CODE resumão pra quem comprou mas não leu o livro!

Slide 58

Slide 58 text

LIVRO Clean Code A Handbook of Agile So ware Cra smanship Robert C. Martin (Uncle Bob)

Slide 59

Slide 59 text

AGENDA Resumo dos principais tópicos Não dá pra cobrir tudo Focado em PHP quando possível! Alguns detalhes vão ser explicados mais à frente

Slide 60

Slide 60 text

CAPÍTULO 1 Clean Code "You are reading this book for two reasons. First, you are a programmer. Second, you want to be a better programmer. Good. We need better programmers."

Slide 61

Slide 61 text

(bootstrap time!)

Slide 62

Slide 62 text

"CODE-SENSE" "A programmer without "code-sense" can look at a messy module and recognize the mess but will have no idea what to do about it. A programmer with "code-sense" will look at a messy module and see options and variations." Uncle Bob

Slide 63

Slide 63 text

SEGUNDO UNCLE BOB: Escrever código limpo requer disciplina O "code-sense" é a chave! Alguns de nós nascem com o "code-sense" Outros só com a prática!

Slide 64

Slide 64 text

ALGUNS PONTOS Passamos mais tempo lendo código Sucesso relacionado com o entendimento (o entendimento diminui ao longo do tempo)

Slide 65

Slide 65 text

CAPÍTULO 2 Meaningful Names "Names are everywhere in so ware. We name our variables, our functions, our arguments, classes, and packages. We name our source files and the directories that contain them. We name and name and name."

Slide 66

Slide 66 text

EXPRESSE INTENÇÃO AO DAR NOMES Use nomes pronunciáveis / Evite abreviações

Slide 67

Slide 67 text

class DtaRcrd102 { private DateTime $genymdhsm; private DateTime $modymdhms; private string $pszqint = "102"; } class Customer { private DateTime $generationTimestamp; private DateTime $modificarionTimestamp; private string $recordId = "102"; }

Slide 68

Slide 68 text

NOMES "BUSCÁVEIS" / CONSTANTES for ($i = 0; $i < 5; $i++) { // ... } for ($i = 0; $i < WORK_DAYS_PER_WEEK; $i++) { // ... }

Slide 69

Slide 69 text

EVITE PREFIXOS/SUFIXOS DESNECESSÁRIOS (As pessoas geralmente "aprendem" a ignorar prefixos e sufixos muito rapidamente.) $txtFirstName = $controller­>request()­>get('txt_FirstName');

Slide 70

Slide 70 text

INTERFACES E IMPLEMENTAÇÕES Evitar informação demais pro usuário (dev) (estou passando uma interface ou classe concreta?) PSR Naming Conventions | Symfony UserInterface, AbstractResolver, ReusableTrait

Slide 71

Slide 71 text

EVITE O "MAPA MENTAL" Não obrigue o usuário a tentar entender o que está escrito Buscar entender pelo contexto é muito mais demorado!

Slide 72

Slide 72 text

NOMES DE CLASSES "Classes and objects should have noun or noun phrase names like Customer, WikiPage, Account, and AddressParser. Avoid words like Manager, Processor, Data, or Info in the name of a class. A class name should not be a verb." (resumindo: nome de classe = substantivo)

Slide 73

Slide 73 text

NOMES DE MÉTODOS Devem ser verbos Utilize Named Constructors (mais significado) Accessors (get), Mutators (set) e predicates (is)

Slide 74

Slide 74 text

UMA PALAVRA POR CONCEITO Nunca misture palavras de conceitos similares fetch, retrieve, get DeviceController, DeviceManager

Slide 75

Slide 75 text

USE NOMES PRESENTES EM PADRÕES Todo dev sabe (ou deveria) saber Design Patterns Facilita o entendimento sobre a solução implementada AccountVisitor, ConsoleDecorator, UserFactory

Slide 76

Slide 76 text

NÃO ADICIONE CONTEXTO DESNECESSÁRIO Contexto deve ficar no namespace Nome de classe deve resumir o que ela faz GSDAMailingAddress, GSDAAccountAddress

Slide 77

Slide 77 text

CAPÍTULO 3 Functions "In the early days of programming we composed our systems of routines and subroutines. Nowadays only the functions survives from those early days. Functions are the first line of organization in a any program."

Slide 78

Slide 78 text

FUNÇÕES/MÉTODOS PEQUENOS Máximo 20 linhas. Se possível menos. Máximo 120 caracteres por linha. Se possível 80.

Slide 79

Slide 79 text

BLOCOS E INDENTAÇÃO Cada bloco de uma linha (chamada de método) Métodos com 1 ou 2 níveis de indentação Muito mais fáceis de entender

Slide 80

Slide 80 text

FAÇA UMA COISA Devem fazer apenas uma coisa (e fazer bem) Nomes muito grande podem necessitar ser refatorados Palavras de alerta: And, Or, If

Slide 81

Slide 81 text

"STEPDOWN RULE" Leitura fluente como texto if (!$user = $this­>findUser()) { // ... } $this­>save($user); $user = $this­>findUser(); if (!$user) { // ... } $this­>save($user);

Slide 82

Slide 82 text

private function something(): bool { return !$this­>foo() || $this­>bar(); } private function something(): bool { if (!$this­>foo()) { return false; } if ($this­>bar()) { return true; } return false; }

Slide 83

Slide 83 text

switch Tolerados se aparecerem apenas uma vez Pensar em AbstractFactory se mais de uma vez Cuidado para não ferir SRP

Slide 84

Slide 84 text

USE NOMES DESCRITIVOS Word's principle: "You know you are working on clean code when each routine turns out to be pretty much what you expected." Não tenha medo de escrever nomes longos Escreva exatamente o que está sendo feito

Slide 85

Slide 85 text

ARGUMENTOS Nenhum é sempre melhor 1 ou 2 aceitáveis / 3 deve ser evitado (aumento do número de argumentos dificulta escrever testes)

Slide 86

Slide 86 text

"Flag Arguments" nunca (boolean) Deixa claro que faz mais de uma coisa Refatore para um método para cada coisa

Slide 87

Slide 87 text

Encapsule argumentos em objetos (dá mais significado ao argumento) private function makeCircle(float $x, float $y): Circle { // ... } private function makeCircle(Point $point): Circle { // ... }

Slide 88

Slide 88 text

Verbos e palavras-chave (dá mais significado ao argumento) public function find(Email $email): User { // ... } public function findUserByEmail(Email $email): User { // ... }

Slide 89

Slide 89 text

PREFIRA EXCEPTIONS São melhores que códigos de erros try/catch em método separado $user = $this­>getLoggedUser(); public function getLoggedUser(): ?User { try { return $this­>userResolver­>user(); } catch (EmptyTokenException $e) { return null; } }

Slide 90

Slide 90 text

CAPÍTULO 4 Comentários "Don't comment bad code - rewrite it." Brian W. Kernighan e P. J. Plaugher

Slide 91

Slide 91 text

"Truth can only be found in one place: the code. Only the code can truly tell you what it does."

Slide 92

Slide 92 text

No content

Slide 93

Slide 93 text

COMENTÁRIOS ACEITÁVEIS Legal Comments Clarification (formato de datas) Comentários TODO Referência a issues (ticket Jira)

Slide 94

Slide 94 text

CONSIDERAÇÕES Remova comentários que não adicionam nada (docblock) Referências internas Críticas ou sugestões

Slide 95

Slide 95 text

/** * Returns the day of the month. * * @return int the day of the month. */ public function getDayOfMonth(): int { return $this­>dayOfMonth; }

Slide 96

Slide 96 text

No content

Slide 97

Slide 97 text

/** The first name */ private string $firstName; /** The last name */ private string $lastName; /* Added by Junior */ $response = new InputStreamResponse(); $response­>setBody($formatter­>getResultStream()); // $resultStream = $formatter­>getResultStream(); // $reader = new StreamReader($resultStram);

Slide 98

Slide 98 text

CAPÍTULO 5 Formatação Visual importa sim!

Slide 99

Slide 99 text

Escolhe um code style e o siga Agrupe blocos de linhas no mesmo contexto Declare variáveis próximo da utilização Variáveis de instância sempre no topo da classe

Slide 100

Slide 100 text

Funções dependentes próximas Não alinhe horizontalmente class FitNesseExpediter implements ResponseSender { private Socket $socket; private InputStream $input; private OutputStream $output; private Request $request; private Response $response; private FitNesseContext $context; private float $requestParsingTimeLimit; protected float $requestProgress; }

Slide 101

Slide 101 text

Indentação. Nem precisa falar, né?

Slide 102

Slide 102 text

CAPÍTULO 6 Objetos e Estrutura de Dados "There is a reason that we keep our variables private. We don't want anyone else to depende on them. We want to keep the freedom to change their type or implementation on a whim or an impulse."

Slide 103

Slide 103 text

Esconder implementação expões abstrações Manipular a essência dos dados por abstrações OOP permite adicionar novas classes sem mudar as existentes

Slide 104

Slide 104 text

LEI DE DEMETER "Fale com amigos, não com estranhos." Encapsule o máximo possível. Exponha apenas o necessário.

Slide 105

Slide 105 text

DTO (DATA TRANSFER OBJECTS) Classes puras somente para transferir dados Imutável. Somente getters.

Slide 106

Slide 106 text

class Address implements ResponseSender { private string $street; private string $city; private Country $country; public function __construct( string $street, string $city, Country $country ) { $this­>street = $street; $this­>city = $city; $this­>country = $country; } // Only getters }

Slide 107

Slide 107 text

CAPÍTULO 7 Error Handling "...things can go wrong, and when they do, we as programmers are responsible for making sure that our code does what it needs to do."

Slide 108

Slide 108 text

Exceptions sempre. Código de erro nunca! Escreva o bloco try/catch primeiro (facilita pensar em todas as possíveis exceções)

Slide 109

Slide 109 text

Exceptions como primeira opção Trate a exceção na origem public function resolveUser(): User { $user = $this­>findInRequest(); if (!$user) { throw new UserNotFoundException(); } return $user; } try { $user = $resolver­>resolveUser(); } catch (UserNotFoundException $e) { return new Response(/**/); }

Slide 110

Slide 110 text

DEFINA CONTEXTO public static function byEmail(string $email): self { return new self( sprintf('User not found with the email %s', $email) ); } throw UserNotFoundException::byEmail($user­>getEmail());

Slide 111

Slide 111 text

NULL RETURN Evite retornar null Dispare exception e trate na origem Use Null Objects

Slide 112

Slide 112 text

NÃO PASSE NULL COMO PARÂMETRO Perde consistência Adiciona complexidade (mais ifs)

Slide 113

Slide 113 text

CAPÍTULO 9 Unit Tests "The Agile and TDD movements have encouraged many programmers to write automated unit tests, and more are joining their ranks every day. But in the mad rush to add testing to our discipline, many programmers have missed one of the more subtle, and important, points of writing good tests."

Slide 114

Slide 114 text

AS 3 LEIS DO TDD 1. Você não deve escrever código antes de ter escrito um teste pra ele que irá falhar. 2. Você não deve escrever mais de um teste unitário que seja suficiente para passar. 3. Você não deve escrever mais código do que o necessário para fazer o teste passar.

Slide 115

Slide 115 text

TESTES ANTES OU DEPOIS? Antes! Ciclo 1, 2, 3 que irá cobrir todos os casos possíveis, incluindo de falhas. Escreva um teste e o faça falhar! Adicione aquele if maroto e faça o teste passar!

Slide 116

Slide 116 text

CLEAN TESTS? Clean Code também para testes Crie "helpers" em forma de trait para adicionar funcionalidades extras trait JwtAuthenticationTrait { use HttpRequestsTrait; public function loginUser(User $user): void { $serializedToken = $this­>generateTokenForUser($user); $this­>request­>withHeader( 'HTTP_AUTHORIZATION', sprintf('Bearer %s', $serializedToken) ); } }

Slide 117

Slide 117 text

DICAS PARA CLEAN TESTS Apenas um assert por teste (customize!) (nomes de testes mais claros) Apenas um conceito por teste (cada caso possível é um novo teste)

Slide 118

Slide 118 text

Teste com usuário admin + teste com não admin public function test_only_admins_can_change_user_type(): void {} public function test_admin_users_can_change_user_type(): void {} public function test_non_admin_users_cannot_change_user_type(): void

Slide 119

Slide 119 text

"FIRST" RULE Fast: testes devem ser rápidos Independent: não devem compartilhar detalhes Repeatable: independentes de ambiente Self-Validating: ou passou ou não passou (boolean) Timely: escreva testes sempre antes (depois + difícil de testar)

Slide 120

Slide 120 text

BÔNUS! Regra dos 3As (Arrange, Act, Assert) public function test_admin_users_can_change_user_type(): void { // Arrange $admin = $this­>makeAdminUser(); $user = $this­>makeNormalUser(['type' => User::TYPE_MEMBER]); $this­>loginAsUser($admin); // Act $formatter = new Formatter(); $user = $formatter­>format($user); // Assert $this­>assertEquals(User::TYPE_MEMBER, $user­>getType()); }

Slide 121

Slide 121 text

CAPÍTULO 10 Classes "Let's talk about Clean Classes"

Slide 122

Slide 122 text

ENCAPSULAMENTO private por padrão protected quando necessário (herança ou testes) Foco sempre em encapsular primeiro! (use abstrações)

Slide 123

Slide 123 text

CLASSES PEQUENAS Evite "God Classes" (SRP) Tamanho é determinado pelo nome! (evite Manager ou Processor) Caso feliz: ter um único método público (SRP) (facilita muito abstração)

Slide 124

Slide 124 text

COESÃO Busque sempre alta coesão (alto relacionamento entre métodos e propriedades) Poucas variáveis de instância por classe (favorece SRP!)

Slide 125

Slide 125 text

COESÃO ENTRE CLASSES Use e abuse de Dependency Injection (favorece SRP!) Favorece DRY (Don't Repeat Yourself)

Slide 126

Slide 126 text

"COMPOSITION OVER INHERITANCE" Mais fácil com classes menores Nova funcionalidade? Nova classe + Dependency Injection da anterior!

Slide 127

Slide 127 text

Nada de TokenManager ou coisas do tipo! OCP - Open-close Principle final class JwtTokenGenerator implements TokenGeneratorInterface {} final class IntegrationTokenGenerator implements TokenGeneratorInterface { private TokenGeneratorInterface $tokenGenerator; public function __construct(TokenGeneratorInterface $tokenGenerator) { $this­>tokenGenerator = $tokenGenerator; } }

Slide 128

Slide 128 text

CAPÍTULO 12 Emergent Design "What if there were four simple rules that you could follow that would help you create good designs as you worked?"

Slide 129

Slide 129 text

4 REGRAS DO SIMPLE DESIGN RULE

Slide 130

Slide 130 text

REGRA 1 RODE TODOS OS TESTES Continuamente (Loop 1, 2, 3) Incrementalmente (Continuous Integration)

Slide 131

Slide 131 text

REGRA 2 A 4 REFATORE Remova código, não só adicione! "The fact that we have these tests eliminates the fear that cleaning up the code will break it!" TDD (testes ANTES! coverage!)

Slide 132

Slide 132 text

REGRA 2: ELIMINE DUPLICIDADE "Duplication is the primary enemy of a well-designed system!" Use e abuse de SRP!

Slide 133

Slide 133 text

REGRA 3: GARANTA EXPRESSIVIDADE Escolha de bons nomes Utilização de Design Patterns Facilite a vida do próximo dev! Ele pode ser você!

Slide 134

Slide 134 text

REGRA 4: MINIMIZE CLASSES E MÉTODOS Regra menos importante! Não exagere na SRP! Não tenha classes ou métodos demais

Slide 135

Slide 135 text

CONCLUSÕES Qualidade é um execício diário Comece a praticar (experiência) Melhoria de processos Diminuição de complexidade

Slide 136

Slide 136 text

OBRIGADO! SLIDES DO WORKSHOP DE HOJE ⭐ https://bit.ly/2MFwGin http://twitter.com/junior_grossi