Slide 1

Slide 1 text

Marcel Gonçalves dos Santos @marcelgsantos paradigmas de programação uma visão geral sobre orientação a objetos e programação funcional

Slide 2

Slide 2 text

pensandonaweb.com.br desenvolvedor web full-stack Marcel Gonçalves dos Santos @marcelgsantos

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

@femugsp sp.femug.com

Slide 5

Slide 5 text

@phpsp phpsp.org.br

Slide 6

Slide 6 text

Interaja nas mídias sociais!
 
 - fale sobre o evento, palestrantes e conteúdo - tire fotos do evento e publique
 - interaja com outros participantes do evento - tire dúvidas ou dê feedbacks para os palestrantes

Slide 7

Slide 7 text

1. seguir @marcelgsantos no Twitter
 2. tuitar utilizando as hashtags #TheDevConf,
 #TrilhaJavaScript e #JavaScript
 3. não vale tuíte em branco e retuíte
 4. ler e preencher este simples formulário
 bit.ly/sorteio-tdc-4 Concorra a um livro da Casa do Código!

Slide 8

Slide 8 text

O que é paradigma de programação?

Slide 9

Slide 9 text

são modelos ou estilos de programação suportados por linguagens que agrupam certas características comuns

Slide 10

Slide 10 text

os paradigmas de programação definem como os códigos são estruturados…

Slide 11

Slide 11 text

principais paradigmas de programação
 os dois principais paradigmas são o imperativo e o declarativo

Slide 12

Slide 12 text

paradigma imperativo
 descreve a resolução de um problema através de comandos que o computador pode compreender e executar

Slide 13

Slide 13 text

paradigma imperativo
 os paradigmas procedural e orientado a objetos são exemplos de paradigmas imperativos

Slide 14

Slide 14 text

let result = 0; !// Imperative code to sum 1 to 10 for (let i = 0; i !<= 10; i!++) { result += i; } console.log(result); !// 55

Slide 15

Slide 15 text

paradigma declarativo
 permite especificar o que deve ser computado e não como deve ser computado

Slide 16

Slide 16 text

paradigma declarativo
 os paradigmas funcional e lógico são exemplos de paradigmas declarativos

Slide 17

Slide 17 text

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; !// Declarative code to sum 1 to 10 const sum = (a, b) !=> a + b; const result = numbers.reduce(sum); console.log(result);

Slide 18

Slide 18 text

paradigmas de linguagens de programação
 
 imperativo
 procedural - C e Pascal orientado a objetos - C++, Java, JavaScript, PHP, Python e Ruby
 
 declarativo
 lógico - Prolog funcional - Clojure, Elixir, Elm, Erlang, F#, Haskell, Lisp, OCaml e Scala

Slide 19

Slide 19 text

Programação Orientada a Objetos

Slide 20

Slide 20 text

trata da comunicação entre objetos através da troca de mensagens

Slide 21

Slide 21 text

um objeto é uma representação concreta de uma abstração…

Slide 22

Slide 22 text

…que possui características, comportamentos e estado atual

Slide 23

Slide 23 text

a orientação a objetos pode ser baseada em classes ou baseada em protótipos

Slide 24

Slide 24 text

em programação orientada a objetos baseada em classes as classes são definidas de antemão e objetos são instanciados baseados em classes

Slide 25

Slide 25 text

!// class to create a Person object class Person { constructor(name, age) { this.name = name; this.age = age; } sayName() { console.log(`Hi, my name is ${this.name}!`); } } !// create an instance of Person let person = new Person('John', 32); person.sayName(); !// Hi, my name is John!

Slide 26

Slide 26 text

em programação orientada a objetos baseada em protótipos os objetos são as entidades primárias e não existe nenhuma classe

Slide 27

Slide 27 text

!// constructor function to create a Person object function Person(name, age) { this.name = name; this.age = age; } !// sayName method is added to the prototype of Person Person.prototype.sayName = function() { console.log('Hi, my name is ' + this.name + '!'); }; !// create an instance of Person let person = new Person('John', 32); person.sayName(); !// Hi, my name is John!

Slide 28

Slide 28 text

em JavaScript, as classes são açúcar sintático para funções construtoras

Slide 29

Slide 29 text

class Person { constructor(name, age) { this.name = name; this.age = age; } sayName() { console.log(`Hi, my name is ${this.name}!`); } } !// add sayAge method to the Person prototype Person.prototype.sayAge = function() { console.log('I\'m ' + this.age + ' years old!'); }; let person = new Person('John', 32); person.sayName(); !// Hi, my name is John! person.sayAge(); !// I'm 32 years old!

Slide 30

Slide 30 text

o protótipo de um objeto é apenas outro objeto que o objeto é ligado

Slide 31

Slide 31 text

todo objeto possui uma ligação com o protótipo (e apenas uma)

Slide 32

Slide 32 text

novos objetos são criados baseados em objetos já existentes escolhidos como seu protótipo

Slide 33

Slide 33 text

Pilares da Orientação a Objetos

Slide 34

Slide 34 text

abstração
 trata da representação de um objeto da vida real dentro do sistema

Slide 35

Slide 35 text

!// class to create a Person object class Person { constructor(name, age) { this.name = name; this.age = age; } sayName() { console.log(`Hi, my name is ${this.name}!`); } } !// create an instance of Person let person = new Person('John', 32); person.sayName(); !// Hi, my name is John!

Slide 36

Slide 36 text

herança
 permite o reaproveitamento de código em que uma classe herda características e atributos de uma classe base

Slide 37

Slide 37 text

encapsulamento
 permite ocultar a implementação interna de um objeto

Slide 38

Slide 38 text

!// hiding data through convention class Person { constructor(name, age) { this._name = name; this._age = age; } sayName() { console.log(`Hi, my name is ${this._name}!`); } } let person = new Person('John', 'Doe', 32); !// accessing hidden data console.log(person._name); !// John

Slide 39

Slide 39 text

class Person { #name; #age; constructor(name, age) { this.#name = name; this.#age = age; } sayName() { console.log(`Hi, my name is ${this.#name}!`); } } let person = new Person('John', 'Doe', 32); console.log(person.sayName()); !// Hi, my name is John! console.log(person.name); !// undefined console.log(person.#name); !// Uncaught SyntaxError: Undefined private field #name: must be declared in an…

Slide 40

Slide 40 text

polimorfismo
 consiste na alteração do funcionamento interno de um método herdado do pai

Slide 41

Slide 41 text

Princípios da Orientação a Objetos

Slide 42

Slide 42 text

os princípios de design ajudam a projetar códigos melhores

Slide 43

Slide 43 text

coesão
 indica o grau de relação entre os membros de um módulo

Slide 44

Slide 44 text

!// not cohesive class class Cart { constructor() { this._items = []; } numberOfItems() { return this._length; } calculateDeliveryPrice() { !// calculates the delivery price } }

Slide 45

Slide 45 text

acoplamento
 indica o grau de dependência entre módulos

Slide 46

Slide 46 text

o acoplamento ocorre quando o código de um módulo utiliza código de outro módulo, seja ao chamar uma função ou acessar algum dado

Slide 47

Slide 47 text

class Engine { start() { console.log('Starting the engine'); } }
 
 class Car { constructor() { this.engine = new Engine; } start() { this.engine.start(); } } let toyota = new Car(); toyota.start(); !// Starting the engine

Slide 48

Slide 48 text

ao controlar o acoplamento, o software torna-se mais flexível e fácil de manter

Slide 49

Slide 49 text

pode-se reduzir o acoplamento através da injeção de dependências

Slide 50

Slide 50 text

class Engine { !// engine implementation }
 class Car { constructor(engine) { this.engine = engine; } start() { this.engine.start(); } } !// inject an engine dependency into the car let engine = new Engine(); let toyota = new Car(engine); toyota.start(); !// Starting the engine

Slide 51

Slide 51 text

utilizar injeção de dependências auxilia nos testes unitários pois tornam os módulos fracamente acoplados, altamente coesos e facilita o mocking de objetos

Slide 52

Slide 52 text

“prefira classes com alta coesão e baixo acoplamento”

Slide 53

Slide 53 text

Programação Funcional λ

Slide 54

Slide 54 text

paradigma de programação que utiliza funções puras e foca na transformação do estado

Slide 55

Slide 55 text

baseado no cálculo lambda proposto por Alonzo Church na década de 30

Slide 56

Slide 56 text

na programação funcional as funções são tratadas como conceito principal

Slide 57

Slide 57 text

Uma função matemática trata-se de um simples mapeamento entre o domínio e o contra-domínio. 1 2 3 D B A C X Y

Slide 58

Slide 58 text

Estado λ

Slide 59

Slide 59 text

o estado de um programa é representado pelos valores dos dados armazenados na memória…

Slide 60

Slide 60 text

…em qualquer ponto de execução do programa

Slide 61

Slide 61 text

o estado de uma aplicação é alterado a cada interação feita pelo usuário ou pelo próprio sistema…

Slide 62

Slide 62 text

…e pode ser representado por uma estrutura de dados

Slide 63

Slide 63 text

a maioria dos bugs são relacionados ao controle de estado

Slide 64

Slide 64 text

Funções Puras λ

Slide 65

Slide 65 text

funções puras
 
 1. ter parâmetros de entrada 
 2. não depender do estado externo 
 3. retorno baseado nos valores de entrada 
 4. não devem causar efeitos colaterais

Slide 66

Slide 66 text

!// pure or impure function? let counter = 0; function increment() { counter!++; return counter; } console.log(increment()); !// 1

Slide 67

Slide 67 text

!// pure function (ES5 syntax) function add(x, y) { return x + y; } console.log(add(2, 3)); !// 5

Slide 68

Slide 68 text

!// pure function (ES6 syntax) const add = (x, y) !=> x + y; console.log(add(2, 3)); !// 5

Slide 69

Slide 69 text

por que utilizar funções puras?
 são reutilizáveis, componíveis, fáceis de testar, fáceis de cachear e paralelizáveis

Slide 70

Slide 70 text

transparência referencial
 propriedade que garante que a saída de uma função pura sempre será a mesma dado um mesmo conjunto de argumentos

Slide 71

Slide 71 text

!// referential transparency const add = (x, y) !=> x + y; console.log(add(2, 3) !!=== 5); !// true console.log(5 !!=== 5); !// true

Slide 72

Slide 72 text

pode não ser fácil criar funções puras

Slide 73

Slide 73 text

porém, a restritividade ajuda a melhorar o foco

Slide 74

Slide 74 text

Mais sobre Funções λ

Slide 75

Slide 75 text

funções de alta ordem e 
 funções de primeira classe
 são funções que podem ser atribuídas a variáveis, passadas como argumentos e retornadas de uma função

Slide 76

Slide 76 text

!// high-order function const add = (x, y) !=> x + y; const numbers = [1, 2, 3, 4, 5]; const sum = numbers.reduce(add); const sum10 = numbers.reduce(add, 10); console.log(sum); !// 15 console.log(sum10); !// 25

Slide 77

Slide 77 text

funções anônimas
 funções que não possuem nome e que, geralmente, são passadas como argumento ou atribuídas

Slide 78

Slide 78 text

!// anonymous function const numbers = [1, 2, 3, 4, 5]; const sum = numbers.reduce((x, y) !=> x + y); console.log(sum); !// 15

Slide 79

Slide 79 text

closures
 funções que possuem acesso à valores do escopo externo

Slide 80

Slide 80 text

!// closure function function greet(greeting) { return function (name) { return `${greeting} ${name}!`; }; } const greet2 = greeting !=> name !=> `${greeting} ${name}!`; console.log(greet('Hello')('Mary')); !// Hello Mary! console.log(greet2('Hello')('John')); !// Hello John!

Slide 81

Slide 81 text

recursão
 é quando uma função é definida em termos de si própria, ou seja, quando a função chama ela mesma

Slide 82

Slide 82 text

diferença entre função e procedimento (procedure)
 uma função recebe um valor e retorna um resultado; um procedimento é um conjunto de comandos executados numa ordem

Slide 83

Slide 83 text

“Don't think of functions as a collection of instructions. Think of them as non-destructive operations on input `double = n => n * 2;`” Eric Elliott, 2016. https:/ /twitter.com/_ericelliott/status/685172918784004097

Slide 84

Slide 84 text

memoize
 técnica que permite que funções custosas sejam cacheadas para execuções posteriores mais rápidas

Slide 85

Slide 85 text

Imutabilidade λ

Slide 86

Slide 86 text

a imutabilidade diz que um dado não pode ser alterado após a sua criação

Slide 87

Slide 87 text

a imutabilidade permite maior confiança e evita que erros ocorram

Slide 88

Slide 88 text

o JavaScript não possui suporte a dados imutáveis de forma nativa

Slide 89

Slide 89 text

porém, pode-se trabalhar com dados imutáveis em JavaScript utilizando algumas técnicas

Slide 90

Slide 90 text

Currying e aplicação parcial λ

Slide 91

Slide 91 text

o currying é a técnica que permite transformar uma função que recebe múltiplos argumentos…

Slide 92

Slide 92 text

…em uma função que recebe apenas um argumento e que retorna uma função que aceita os argumentos restantes

Slide 93

Slide 93 text

a aplicação parcial é quando se executa uma função e passa apenas parte de seus argumentos

Slide 94

Slide 94 text

a aplicação parcial permite fazer a especialização de uma função mais genérica

Slide 95

Slide 95 text

!// specialization from a curried function !// using partial application const greet = R.curry((greeting, name) !=> `${greeting} ${name}`); const greetMorning = greet('Good Morning'); console.log(greetMorning('Alice')); !// Good Morning Alice

Slide 96

Slide 96 text

currying e aplicação parcial são recursos muito utilizados em programação funcional

Slide 97

Slide 97 text

na programação funcional deve-se levar em consideração a ordem dos parâmetros

Slide 98

Slide 98 text

os parâmetros mais genéricos devem vir mais para o início e os parâmetros mais específicos devem vir mais para o final

Slide 99

Slide 99 text

o JavaScript não possui suporte nativo para currying como nas linguagens puramente funcionais Elm ou Haskell

Slide 100

Slide 100 text

Composição de Funções λ

Slide 101

Slide 101 text

a composição é o processo de combinar uma ou mais funções para criar uma nova função

Slide 102

Slide 102 text

!// creating a new function from others by composition const sentence = 'estava à toa na vida o meu amor me 
 chamou pra ver a banda passar cantando coisas de amor'; const wordCount = R.length(R.split(' ', sentence)); console.log(wordCount); !// 19

Slide 103

Slide 103 text

é uma solução elegante e legível e ajuda a evitar a utilização do aninhamento de funções

Slide 104

Slide 104 text

o Ramda possui uma função que permite criar uma nova função a partir da composição de funções

Slide 105

Slide 105 text

!// create a function using composition const sentence = 'estava à toa na vida o meu amor me 
 chamou pra ver a banda passar cantando coisas de amor’; const countWords = R.compose(R.length, R.split); console.log(countWords(' ', sentence)); !// 19

Slide 106

Slide 106 text

Biblioteca
 Ramda λ

Slide 107

Slide 107 text

uma biblioteca construída para o estilo de programação funcional que facilita a utilização de pipelines e dados imutáveis

Slide 108

Slide 108 text

possui foco no estilo puramente funcional

Slide 109

Slide 109 text

todas as funções do Ramda são auto-curried

Slide 110

Slide 110 text

os argumentos das funções do Ramda são organizados de forma a facilitar a utilização de currying

Slide 111

Slide 111 text

Caso de Uso 1 somar os preços dos produtos de um carrinho de compras

Slide 112

Slide 112 text

!// shopping cart const cart = [ {id: 1, product: 'iPhone', price: 499}, {id: 2, product: 'Kindle', price: 179}, {id: 3, product: 'Macbook Pro', price: 1199}, ]; !// get prices from shopping cart and sum them
 !// using intermediate values const cartPrices = R.map(item !=> item.price, cart); const cartSum = R.sum(cartPrices); console.log(cartSum); !// 1877 realiza o mapeamento da lista de produtos (objetos) para uma lista de preços (números) faz a somatória da lista de números e retorna o total Passo 1

Slide 113

Slide 113 text

!// shopping cart const cart = [ {id: 1, product: 'iPhone', price: 499}, {id: 2, product: 'Kindle', price: 179}, {id: 3, product: 'Macbook Pro', price: 1199}, ]; !// get prices from shopping cart and sum them
 !// using function composition const totalCart = R.compose( R.sum, R.map(item !=> item.price), ); console.log(totalCart(cart)); !// 1877 cria uma nova função a partir da composição de funções e elimina valores intermediários aplicação parcial da função map a composição é feita da direita para a esquerda Passo 2

Slide 114

Slide 114 text

!// shopping cart const cart = [ {id: 1, product: 'iPhone', price: 499}, {id: 2, product: 'Kindle', price: 179}, {id: 3, product: 'Macbook Pro', price: 1199}, ]; !// get prices from shopping cart and sum them !// using function composition with pipe const totalCart = R.pipe( R.map(item !=> item.price), R.sum, ); console.log(totalCart(cart)); !// 1877 o pipe de funções é feito da esquerda para a direita e facilita a leitura do código Passo 3

Slide 115

Slide 115 text

Caso de Uso 2 limpar dados vindo de um formulário e realizar um cálculo

Slide 116

Slide 116 text

!// cleaning data from an input const price = '100'; const discount = (perc, value) !=> perc * value; let priceInt = parseInt(price); let priceDiscount = discount(0.2, priceInt); console.log(priceDiscount); !// 20 Passo 1

Slide 117

Slide 117 text

!// cleaning data from an input const price = '100'; const discount = (perc, value) !=> perc * value; !// using partial application const discount20 = R.partial(discount, [0.2]); let priceInt = parseInt(price); let priceDiscount = discount20(priceInt); console.log(priceDiscount); !// 20 cria uma nova função a partir da aplicação parcial de uma existente Passo 2

Slide 118

Slide 118 text

!// cleaning data from an input const price = '100'; const discount = (perc, value) !=> perc * value; !// using function composition const priceDiscount = R.pipe( parseInt, R.partial(discount, [0.2]), ); console.log(priceDiscount(price)); !// 20 cria uma nova função a partir da composição de funções utilizando a função pipe e elimina valores intermediários Passo 3

Slide 119

Slide 119 text

!// cleaning data from an input const price = 'lambda!'; const discount = (perc, value) !=> perc * value; !// using function composition const priceDiscount = R.pipe( parseInt, R.partial(discount, [0.2]), ); console.log(priceDiscount(price)); !// null erro ao receber um valor não numérico Passo 4

Slide 120

Slide 120 text

!// cleaning data from an input const price = 'lambda!'; const discount = (perc, value) !=> perc * value; !// using function composition const priceDiscount = R.pipe( parseInt, R.defaultTo(0), R.partial(discount, [0.2]), ); console.log(priceDiscount(price)); !// 0 retorna o valor padrão para o caso de um valor não truthy Passo 5

Slide 121

Slide 121 text

existem inúmeros conceitos relacionados a programação funcional como functors, monads, lazy evaluation, tail call optimization…

Slide 122

Slide 122 text

Conclusão

Slide 123

Slide 123 text

os princípios de design ajudam a projetar códigos melhores

Slide 124

Slide 124 text

um código mau projetado é um código difícil de mudar

Slide 125

Slide 125 text

prefira módulos com alta coesão e baixo acoplamento

Slide 126

Slide 126 text

a programação funcional não é sobre não ter estado…

Slide 127

Slide 127 text

…e sim sobre eliminar estado e efeito colateral sempre que possível e controlar efeitos colaterais quando necessário

Slide 128

Slide 128 text

foque na transformação do estado e evite efeitos colaterais

Slide 129

Slide 129 text

conhecer bem os paradigmas de programação te permite escolher a melhor ferramenta para cada problema

Slide 130

Slide 130 text

vá em frente e divirta-se!

Slide 131

Slide 131 text

Referências

Slide 132

Slide 132 text

bit.ly/referencias-palestra-paradigmas

Slide 133

Slide 133 text

Avalie!

Slide 134

Slide 134 text

bit.ly/avalie-palestra-paradigmas

Slide 135

Slide 135 text

@marcelgsantos speakerdeck.com/marcelgsantos Obrigado. Perguntas?