Vinícius Bail Alonso
Estamos contratando
vba321@hotmail.com
"Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer’s intent but rather is full of crisp abstractions and straightforward lines of control."
Grady Booch, autor do livro Object Oriented Analysis and Design with Applications
"You know you are working on clean code when each routine you read turns out to be pretty much what you expected. You can call it beautiful code when the code also makes it look like the language was made for the problem."
Ward Cunningham, co-inventor do eXtreme programming
Livro Clean Code
Robert C. Martin
"Uncle Bob"
$d = 10;
$cust_n = "Juca";
$brt = "1990-03-30 18:00:38";
Nomes abreviados e difíceis de pronunciar!
$workedDays = 10;
$customerName = "Juca";
$birthday = "1990-03-30 18:00:38";
function calc(x, y) {
return x / y;
}
O nome da função não expressa sua intenção!
function division(dividend, divider) {
return dividend / divider;
}
class ProgrammerFL {
private $h;
private $v;
public function __construct($h, $v) {
$this->h = $h;
$this->v = $v;
}
public function pay() {
return $this->h * $this->v;
}
}
A classe não expressa sua intenção e tem muita abreviação!
class ProgrammerFreeLancerPayment {
private $hoursWorked;
private $valuePerHour;
public function __construct($hoursWorked, $valuePerHour)
{
$this->hoursWorked = $hoursWorked;
$this->valuePerHour = $valuePerHour;
}
public function calculateTotalValueOfWork()
{
return $this->hoursWorked * $this->valuePerHour;
}
}
À seguir um exemplo da fórmula Bhaskara
function quadratic_equation($a,$b,$c) {
if($a === 0) {
echo "Para o cálculo de uma equação quadrática,
\"a\" não pode ser igual a zero.";
} else {
$delta = pow($b,2) - ((4*$a)*$c);
if($delta === 0) {
$raiz = -($b)/(2*$a);
echo "Delta igual a zero. A equação tem 1 raiz.
<br>Raiz da equação: ".$raiz;
} elseif($delta > 0) {
$x1 = (-$b + sqrt($delta))/(2*$a);
$x2 = (-$b - sqrt($delta))/(2*$a);
$raiz = array($x1, $x2);
echo "Delta maior que zero. A equação tem 2 raizes.
<br>Raizes da equação: " .$raiz[0]. "," .$raiz[1];
} else {
echo "Delta menor que zero: equação sem solução.";
}
}
}
function calculate_bhaskara($a,$b,$c) {
if(not_is_zero($a)) {
$delta = calculate_delta($a, $b, $c);
return calculate_root($a, $b, $delta);
}
}
function not_is_zero($param) {
return $param !== 0;
}
function calculate_delta($a, $b, $c) {
return pow($b,2) - ((4*$a)*$c);
}
function calculate_root($a, $b, $delta) {
if(is_zero($delta))
return calculate_simple_root($b, $a);
if(is_greater_than_zero($delta))
return calculate_double_root($b, $a, $delta);
return null;
}
# Primeira opção
if ($delta === 0)
return -($b)/(2*$a);
# Segunda opção
if(is_zero($a))
return calculate_simple_root($b, $a);
Use suas funções para tentar formar uma narrativa
function checkPassword($email, $password) {
$credentials = ['email' => $email,
'password' => $password];
$userExists = User::check($credentials);
if ($userExists) {
session_start();
}
return $userExists;
}
O que há de errado com esse código ?
function checkPassword($email, $password) {
$credentials = ['email' => $email,
'password' => $password];
$userExists = User::check($credentials);
if ($userExists) {
session_start();
}
return $userExists;
}
Cuidado com funções que fazem mais do que se propõe a fazer!
O código deve ser autoexplicativo
# Não pode ser vazio e nem nulo
if (!is_empty($name) && !is_null($name))
function notIsEmptyOrNull($param) {
return !is_empty($param) && !is_null($param);
}
if (notIsEmptyOrNull($name))
use Carbon\Carbon;
# Retorna a data atual
# Formato Y-m-d
Carbon::now();
O comentário é mentiroso!
use Carbon\Carbon;
# Retorna a data atual
# Formato Y-m-d
echo Carbon::now();
// 2016-06-24 15:18:34
/**
* @SWG\Post(
* path="/pets",
* operationId="addPet",
* description="Creates a new pet in the store. Duplicates are allowed",
* produces={"application/json"},
* @SWG\Parameter(
* name="pet",
* in="body",
* description="Pet to add to the store",
* required=true,
* @SWG\Schema(ref="#/definitions/NewPet"),
* ),
* @SWG\Response(
* response=200,
* description="pet response",
* @SWG\Schema(ref="#/definitions/Pet")
* ),
* @SWG\Response(
* response="default",
* description="unexpected error",
* @SWG\Schema(ref="#/definitions/ErrorModel")
* )
* )
*/
public function addPet()
{
}
São úteis para gerar documentação
/*
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| This URL is used by the console to properly generate URLs when using
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
*/
'url' => env('APP_URL', 'http://localhost'),
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'Africa/Windhoek',
São úteis em arquivos de configuração
Arquivo config/app.php gerado pelo Laravel Framework
private function updateListOrder($id, $listOrder, $parentId = 0)
{
//$token = token($this->email);
//if (self::where('confirmation_token', $token)->first()) {
// return $this->getUniqueConfirmationToken();
//}
$row = Testimonial::find($id);
$row->list_order = $listOrder;
$row->save();
return $row;
}
Não deixe trechos de código comentados
$hoursWorked = 30;
$valuePerHour = 50;
$programmerFreeLancer =
new ProgrammerFreeLancerPayment($hoursWorked, $valuePerHour);
$programmerFreeLancer->calculateTotalValueOfWork();
Cuidado para não deixar a linha muito grande
# ...
public function buildJson()
{
$this->getUsersData();
return $this->build();
}
private function getUsersData() {
# ...
}
private function build() {
# ...
}
Seu código deve ser lido de cima para baixo
class Person {
private $name;
private $age;
private $zipCode;
private $street;
private $number;
private $neighborhood;
private $state;
private $city;
private $cellphone;
private $phone;
private $agency;
private $accountNumber;
# ...
}
A classe não está coesa! God Class!
class Address {
private $zipCode;
private $street;
private $number;
private $neighborhood;
private $state;
private $city;
}
class Contact {
private $cellphone;
private $phone;
}
Agora temos classes mais coesas.
class CustomerAccount {
private $agency;
private $number;
}
class Person {
private $name;
private $age;
private $account;
private $contact;
private $address;
}
$address = new Address();
$contact = new Contact();
$account = new CustomerAccount();
$person = new Person('Juca', 20, $address, $contact, $account);
Favorecendo a composição :)
class Product {
private $value;
private $name;
public function __construct($name, $value) {
$this->name = $name;
$this->value = $value;
}
public function getValue() {
return $this->value;
}
}
class Item {
private $product;
private $quantity;
public function __construct($product, $quantity) {
$this->product = $product;
$this->quantity = $quantity;
}
public function getProduct() {
return $this->product;
}
public function getQuantity() {
return $this->quantity;
}
}
class Cart {
private $owner;
private $items;
public function __construct($owner, $items) {
$this->owner = $owner;
$this->items = $items;
}
public function getTotalValueOfItems() {
$total = 0;
foreach ($this->items as $item) {
$total += $item->getProduct()->getValue() * $item->getQuantity();
}
return $total;
}
}
O que há de errado nessa classe?
class Cart {
private $owner;
private $items;
public function __construct($owner, $items) {
$this->owner = $owner;
$this->items = $items;
}
public function getTotalValueOfItems() {
$total = 0;
foreach ($this->items as $item) {
$total += $item->getProduct()->getValue() * $item->getQuantity();
}
return $total;
}
}
Quem deve retornar o valor de cada produto é a classe Item
Para refatorar isso usamos a Lei de Demeter
class Item {
private $product;
private $quantity;
public function __construct($product, $quantity) {
$this->product = $product;
$this->quantity = $quantity;
}
public function getProduct() {
return $this->product;
}
public function getQuantity() {
return $this->quantity;
}
public function totalValue() {
return $this->product->getValue() * $this->quantity;
}
}
class Cart {
private $owner;
private $items;
public function __construct($owner, $items) {
$this->owner = $owner;
$this->items = $items;
}
public function getTotalValueOfItems() {
$total = 0;
foreach ($this->items as $item) {
$total += $item->totalValue();
}
return $total;
}
}
Devemos sempre conciliar coesão e acoplamento
Nosso foco deve estar na troca de mensagens entre objetos
"Any fool can write code that a computer can understand. Good programmers write
code that humans can understand."
Martin Fowler
vba321@hotmail.com