Refactoring to Patterns em Java 8 Eder Ignatowicz Sr. Software - - PowerPoint PPT Presentation

refactoring to patterns em java 8
SMART_READER_LITE
LIVE PREVIEW

Refactoring to Patterns em Java 8 Eder Ignatowicz Sr. Software - - PowerPoint PPT Presentation

Refactoring to Patterns em Java 8 Eder Ignatowicz Sr. Software Engineer JBoss by Red Hat Design Patterns + Java + Programao Funcional <3 Antes uma histria :) Me tornar um World Class Developer Como virar um World Class


slide-1
SLIDE 1

Refactoring to Patterns em Java 8

Eder Ignatowicz

  • Sr. Software Engineer

JBoss by Red Hat

slide-2
SLIDE 2

Design Patterns + Java + Programação Funcional <3

slide-3
SLIDE 3

Antes uma história :)

slide-4
SLIDE 4
slide-5
SLIDE 5
slide-6
SLIDE 6
slide-7
SLIDE 7
slide-8
SLIDE 8

Me tornar um World Class Developer

slide-9
SLIDE 9

Como virar um World Class Developer?

slide-10
SLIDE 10
slide-11
SLIDE 11

:(

slide-12
SLIDE 12

?

slide-13
SLIDE 13

:)

slide-14
SLIDE 14

Refactoring to Patterns em Java 8

slide-15
SLIDE 15

Refactoring Loops to Collection Pipelines

slide-16
SLIDE 16

public class Client { private String name; private String email; private Company company; public Client( String name, String email, Company company ) { this.name = name; this.email = email; this.company = company; } public Client( String name ) { this.name = name; } public Client( String name, String email ) { this.name = name; this.email = email; } … }

slide-17
SLIDE 17

public class ClientRepositoryTest { private ClientRepository repo; @Before public void setup() { Company empresa = new Company( "RedHat" ); Client completo1 = new Client( "Completo1", "completo1@redhat.com", empresa ); Client completo2 = new Client( "Completo2", "completo2@redhat.com", empresa ); Client semEmpresa = new Client( "SemEmpresa", "semEmpresa@ederign.me" ); Client somenteNome = new Client( "SomenteNome" ); repo = new ClientRepository( Arrays.asList( completo1, semEmpresa, completo2, somenteNome ) ); } @Test public void getClientEmailsWithCompanyTest() { List<String> clientMails = repo.getClientMails(); assertEquals( 2, clientMails.size() ); assertTrue( clientMails.contains( "completo1@redhat.com" ) ); assertTrue( clientMails.contains( "completo2@redhat.com" ) ); assertTrue( !clientMails.contains( "semEmpresa@ederign.me" ) ); } }

slide-18
SLIDE 18

public List<String> getClientMails() { ArrayList<String> emails = new ArrayList<>(); for ( Client client : clients ) { if ( client.getCompany() != null ) { String email = client.getEmail(); if ( email != null ){ emails.add( email ); } } } return emails; }

slide-19
SLIDE 19

public List<String> getClientMails() { ArrayList<String> emails = new ArrayList<>(); List<Client> pipeline = clients; for ( Client client : pipeline ) { if ( client.getCompany() != null ) { String email = client.getEmail(); if ( email != null ){ emails.add( email ); } } } return emails; } }

Extract Variable

slide-20
SLIDE 20

public List<String> getClientMails() { ArrayList<String> emails = new ArrayList<>(); List<Client> pipeline = clients .stream() .filter( c -> c.getCompany() != null ) .collect( Collectors.toList() ); for ( Client client : pipeline ) { if ( client.getCompany() != null ) { String email = client.getEmail(); if ( email != null ) { emails.add( email ); } } } return emails; } }

Filter Operation

slide-21
SLIDE 21

Map Operation

public List<String> getClientMails() { ArrayList<String> emails = new ArrayList<>(); List<String> pipeline = clients .stream() .filter( c -> c.getCompany() != null ) .map( c -> c.getEmail() ) .collect( Collectors.toList() ); for ( String mail : pipeline ) { String email = client.getEmail(); if ( mail != null ) { emails.add( mail ); } } return emails; }

slide-22
SLIDE 22

Filter Operation

public List<String> getClientMails() { ArrayList<String> emails = new ArrayList<>(); List<String> pipeline = clients .stream() .filter( c -> c.getCompany() != null ) .map( c -> c.getEmail() ) .filter( m -> m != null ) .collect( Collectors.toList() ); for ( String mail : pipeline ) { if ( mail != null ) { emails.add( mail ); } } return emails; }

slide-23
SLIDE 23

Pipeline

public List<String> getClientMails() { ArrayList<String> emails = new ArrayList<>(); return clients .stream() .filter( c -> c.getCompany() != null ) .map( c -> c.getEmail() ) .filter( m -> m != null ) .collect( Collectors.toList() ); for ( String mail : pipeline ) { if ( mail != null ) { emails.add( mail ); } } return emails; }

slide-24
SLIDE 24

public List<String> getClientMails() { return clients .stream() .filter( c -> c.getCompany() != null ) .map( c -> c.getEmail() ) .filter( m -> m != null ) .collect( Collectors.toList() ); }

slide-25
SLIDE 25

Strategy

“Definir uma família de algoritmos, encapsular cada uma delas e torná-las intercambiáveis. Strategy permite que o algoritmo varie independentemente dos clientes que o utilizam” GAMMA, Erich et al.

slide-26
SLIDE 26

public class ShoppingCartTest { ShoppingCart cart; @Before public void setup() { Item item1 = new Item( 10 ); Item item2 = new Item( 20 ); cart = new ShoppingCart( Arrays.asList( item1, item2 ) ); } @Test public void totalTest() { cart.pay( ShoppingCart.PaymentMethod.CREDIT ) ); } }

slide-27
SLIDE 27

public class ShoppingCart { private List<Item> items; public ShoppingCart( List<Item> items ) { this.items = items; } public void pay( PaymentMethod method ) { int total = cartTotal(); if ( method == PaymentMethod.CREDIT ) { System.out.println( “Pay with credit “ + total); } else if ( method == PaymentMethod.MONEY ) { System.out.println( “Pay with money “ + total ); } } private int cartTotal() { return items .stream() .mapToInt( Item::getValue ) .sum(); } … }

slide-28
SLIDE 28

public class ShoppingCart { private List<Item> items; public ShoppingCart( List<Item> items ) { this.items = items; } public void pay( PaymentMethod method ) {

int total = cartTotal(); if ( method == PaymentMethod.CREDIT ) { System.out.println( “Pay with credit “ + total ); } else if ( method == PaymentMethod.MONEY ) { System.out.println( “Pay with money “ + total ); } }

private int cartTotal() { return items .stream() .mapToInt( Item::getValue ) .sum(); } … }

slide-29
SLIDE 29

public interface Payment { public void pay(int amount); } public class CreditCard implements Payment { @Override public void pay( int amount ) { System.out.println( "Pay with Credit: “ + amount); } } public class Money implements Payment { @Override public void pay( int amount ) { System.out.println( "Pay with Money: “ + amount); }

slide-30
SLIDE 30

public class ShoppingCart { … public void pay( Payment method ) { int total = cartTotal(); method.pay( total ); } private int cartTotal() { return items .stream() .mapToInt( Item::getValue ) .sum(); } }

Strategy

slide-31
SLIDE 31

public interface Payment { public void pay(int amount); }

public class CreditCard implements Payment { @Override public void pay( int amount ) { System.out.println( "make credit payment logic" ); } } public class Money implements Payment { @Override public void pay( int amount ) { System.out.println( "make money payment logic" ); } } public class DebitCard implements Payment { @Override public void pay( int amount ) { System.out.println( "make debit payment logic" ); } }

public void totalTest() { assertEquals( 30, cart.pay( new CreditCard() ) ); assertEquals( 30, cart.pay( new Money() ) ); assertEquals( 30, cart.pay( new DebitCard() ) ); } }

slide-32
SLIDE 32
slide-33
SLIDE 33

public class ShoppingCart { … public void pay( Consumer<Integer> method ) { int total = cartTotal(); method.accept( total ); } … }

public void pay( Payment method ) { int total = cartTotal(); method.pay( total ); }

slide-34
SLIDE 34

public class ShoppingCart { … public void pay( Consumer<Integer> method ) { int total = cartTotal(); method.accept( total ); } … }

public void totalTest() { cart.pay( amount -> System.out.println( "Pay with Credit: " + amount ) ); cart.pay( amount -> System.out.println( "Pay with Money: " + amount ) ); cart.pay( amount -> System.out.println( "Pay with Debit: " + amount ) ); }

slide-35
SLIDE 35

public class PaymentTypes { public static void money( int amount ) { System.out.println( "Pay with Money: " + amount ); } public static void debit( int amount ) { System.out.println( "Pay with Debit: " + amount ); } public static void credit( int amount ) { System.out.println( "Pay with Credit: " + amount ); } } public void totalTest() { cart.pay( PaymentTypes::credit ); cart.pay( PaymentTypes::debit ); cart.pay( PaymentTypes::money ); }

slide-36
SLIDE 36

public class ShoppingCart { … public void pay( Consumer<Integer> method ) { int total = cartTotal(); method.accept( total ); } private int cartTotal() { return items .stream() .mapToInt( Item::getValue ) .sum(); } }

Strategy

slide-37
SLIDE 37

Decorator

“Dinamicamente, agregar responsabilidades adicionais a objetos. Os Decorators fornecem uma alternativa flexível ao uso de subclasses para extensão de funcionalidades.” GAMMA, Erich et al.

slide-38
SLIDE 38

new BufferedReader(new FileReader(new File("some.file")));

slide-39
SLIDE 39

public class Item { private int price; public Item( int price ) { this.price = price; } public int getPrice() { return price; } }

Extras

Envio Impostos Embalagem

slide-40
SLIDE 40

public interface Item { int getPrice(); } public class Book implements Item { private int price; public Book( int price ) { this.price = price; } @Override public int getPrice() { return price; } }

slide-41
SLIDE 41

public abstract class ItemExtras implements Item { private Item item; public ItemExtras( Item item ) { this.item = item; } @Override public int getPrice() { return item.getPrice(); } }

slide-42
SLIDE 42

public class InternationalDelivery extends ItemExtras { public InternationalDelivery( Item item ) { super( item ); } @Override public int getPrice() { return 5 + super.getPrice(); } }

slide-43
SLIDE 43

public class GiftPacking extends ItemExtras { public GiftPacking( Item item ) { super( item ); } @Override public int getPrice() { return 15 + super.getPrice(); } }

slide-44
SLIDE 44

public static void main( String[] args ) { Item book = new Book( 10 ); book.getPrice(); //10 Item international = new InternationalDelivery( book ); international.getPrice(); //15 }

slide-45
SLIDE 45

public static void main( String[] args ) { Item book = new Book( 10 ); book.getPrice(); //10 Item internationalGift = new GiftPacking( new InternationalDelivery( book ) ); internationalGift.getPrice(); //30 }

slide-46
SLIDE 46

public static void main( String[] args ) { Item book = new Book( 10 ); book.getPrice(); //10 Item internationalGiftWithTaxes = new InternacionalTaxes( new GiftPacking( new InternationalDelivery( book ); internationalGiftWithTaxes.getPrice(); //80 } }

slide-47
SLIDE 47

public static void main( String[] args ) { Item book = new Item( 10 ); book.getPrice(); //10 Function<Integer, Integer> giftPacking = value -> value + 15; giftPacking.apply( book.getPrice() ); //25 }

slide-48
SLIDE 48

public static void main( String[] args ) { Item book = new Item( 10 ); book.getPrice(); //10 Function<Integer, Integer> giftPacking = value -> value + 15; giftPacking.apply( book.getPrice() ); //25 Function<Integer, Integer> intTaxes = value -> value + 50; intTaxes.apply( book.getPrice() ); //60 }

slide-49
SLIDE 49

public static void main( String[] args ) { Item book = new Item( 10 ); book.getPrice(); //10 Function<Integer, Integer> giftPacking = value -> value + 15; giftPacking.apply( book.getPrice() ); //25 Function<Integer, Integer> intTaxes = value -> value + 50; intTaxes.apply( book.getPrice() ); //60 giftPacking.andThen( intTaxes ).apply( book.getPrice() ); //75 }

slide-50
SLIDE 50

public class Item { private int price; private Function<Integer, Integer>[] itemExtras = new Function[]{}; public Item( int price ) { this.price = price; } public Item( int price, Function<Integer, Integer>... itemExtras) { this.price = price; this.itemExtras = itemExtras; } public int getPrice() { int priceWithExtras = price; for ( Function<Integer, Integer> itemExtra : itemExtras ) { priceWithExtras = itemExtra.apply( priceWithExtras ); } return priceWithExtras; } public void setItemExtras( Function<Integer, Integer>... itemExtras ) { this.itemExtras = itemExtras; } }

slide-51
SLIDE 51

public static void main( String[] args ) { Item book = new Item( 10 ); Function<Integer, Integer> giftPacking = value -> value + 15; Function<Integer, Integer> intTaxes = value -> value + 50; book.setItemExtras( giftPacking, intTaxes ); book.getPrice(); //75 }

slide-52
SLIDE 52

public static void main( String[] args ) { Item book = new Item( 10 ); Function<Integer, Integer> giftPacking = value -> value + 15; Function<Integer, Integer> intTaxes = value -> value + 50; book.setItemExtras( giftPacking, intTaxes ); book.getPrice(); //75 }

slide-53
SLIDE 53

public class Packing { public static Integer giftPacking( Integer value ) { return value + 15; } //other packing options here } public class Taxes { public static Integer internacional( Integer value ) { return value + 50; } //other taxes here }

slide-54
SLIDE 54

public static void main( String[] args ) { Item book = new Item( 10, Packing::giftPacking,

Taxes::internacional );

book.getPrice(); //75 }

slide-55
SLIDE 55

public class Item { private int price; private Function<Integer, Integer>[] itemExtras = new Function[]{}; public Item( int price ) { this.price = price; } public Item( int price, Function<Integer, Integer>... itemExtras) { this.price = price; this.itemExtras = itemExtras; } public int getPrice() { int priceWithExtras = price; for ( Function<Integer, Integer> itemExtra : itemExtras ) { priceWithExtras = itemExtra.apply( priceWithExtras ); } return priceWithExtras; } public void setItemExtras( Function<Integer, Integer>... itemExtras ) { this.itemExtras = itemExtras; } }

slide-56
SLIDE 56

public class Item { private int price;

private Function<Integer, Integer>[] itemExtras = new Function[]{}; public Item( int price ) { this.price = price; } public Item( int price, Function<Integer, Integer>... itemExtras ) { this.price = price; this.itemExtras = itemExtras; }

public int getPrice() { Function<Integer, Integer> extras = Stream.of( itemExtras ) .reduce( Function.identity(), Function::andThen ); return extras.apply( price ); }

public void setItemExtras( Function<Integer, Integer>... itemExtras ) { this.itemExtras = itemExtras; }

}

slide-57
SLIDE 57

Template

“Definir o esqueleto de um algoritmo em uma operação, postergando alguns passos para as subclasses. Template Method permite que subclasses redefinam certos passo de um algoritmo sem mudar a estrutura do mesmo.” GAMMA, Erich et al.

slide-58
SLIDE 58

public abstract class Banking { public void processOperation( Operation op ) { preProcessing( op ); process( op ); postProcessing( op ); } protected abstract void postProcessing( Operation op ); protected abstract void preProcessing( Operation op ); private void process( Operation op ) { //logic

  • p.process( op );

} }

slide-59
SLIDE 59

public class VIPBanking extends Banking { @Override protected void preProcessing( Operation op ) { //pre processing vip logic } @Override protected void postProcessing( Operation op ) { //post processing vip logic } } public class OnlineBanking extends Banking { @Override protected void preProcessing( Operation op ) { //pre processing online logic } @Override protected void postProcessing( Operation op ) { //post processing online logic } }

slide-60
SLIDE 60

public class Banking { public void processOperation( Operation op ) { process( op ); } public void processOperation( Operation op, Consumer<Operation> preProcessing, Consumer<Operation> postProcessing ) { preProcessing.accept( op ); process( op ); postProcessing.accept( op ); } private void process( Operation op ) { //logic

  • p.process( op );

} }

slide-61
SLIDE 61

Execute Around

slide-62
SLIDE 62

public static void main( String[] args ) throws IOException { BufferedReader br = new BufferedReader( new FileReader( "dora.txt" ) ); try { br.readLine(); } finally { br.close(); } }

slide-63
SLIDE 63

Init / Código de preparação Task Cleanup/finalização

slide-64
SLIDE 64

public static void main( String[] args ) throws IOException { BufferedReader br = new BufferedReader( new FileReader( "dora.txt" ) ); try { br.readLine(); } finally { br.close(); } }

slide-65
SLIDE 65

try ( BufferedReader br = new BufferedReader( new FileReader( "dora.txt" ) ) ) { br.readLine(); }

slide-66
SLIDE 66

@Override public ServerTemplate store( final ServerTemplate serverTemplate, final final List<ServerTemplateKey> keys) { final Path path = buildPath( serverTemplate.getId() ); try { ioService.startBatch(path.getFileSystem()); ioService.write(path, serverTemplate); ioService.write(path, keys); } finally {

ioService.endBatch(); }

return serverTemplate; }

slide-67
SLIDE 67

public void store( final ServerTemplate serverTemplate, final List<ServerTemplateKeys> keys ) { try { ioService.startBatch( path.getFileSystem() ); ioService.write( path, serverTemplate ); ioService.write( path, keys ); } finally { ioService.endBatch(); } }

slide-68
SLIDE 68

public class IOService { … public void processInBatch( Path path, Consumer<Path> batchOp ) { try { startBatch( path.getFileSystem() ); batchOp.accept( path ); } finally { endBatch(); } } }

slide-69
SLIDE 69

public void store( final ServerTemplate serverTemplate, final List<ServerTemplateKeys> keys ) { try { ioService.startBatch( path.getFileSystem() ); ioService.write( path, serverTemplate ); ioService.write( path, keys ); } finally { ioService.endBatch(); } }

slide-70
SLIDE 70

public void store( final ServerTemplate serverTemplate, final List<ServerTemplateKeys> keys ) { ioService.processInBatch( path, ( path ) -> { ioService.write( path, serverTemplate ); ioService.write( path, keys ); } ); }

slide-71
SLIDE 71

public void delete( final ServerTemplate serverTemplate, final List<ServerTemplateKeys> keys ) { ioService.processInBatch( path, ( path ) -> { ioService.delete( path, serverTemplate );

ioService.delete( path, keys );

} ); }

slide-72
SLIDE 72

Chain of Responsibilities

“Evitar o acoplamento do remetente de uma solicitação ao seu receptor, ao dar a mais de um objeto a oportunidade de tratar a solicitação. Encadear os objetos receptores, passando a solicitação ao longo da cadeia até que um objeto a trate.” GAMMA, Erich et al.

slide-73
SLIDE 73

Client Handler 1 Request Handler 2 Request

Handler N

Chain of Responsibilities

slide-74
SLIDE 74

Client Payment Processor 1 Payment Payment

Payment Processor 2 Payment Processor n

slide-75
SLIDE 75

public static void main( String[] args ) { PaymentProcessor paymentProcessor = getPaymentProcessor(); paymentProcessor.process( new Payment( 10 ) ); } private static PaymentProcessor getPaymentProcessor() { PaymentProcessor g = new PaymentProcessorA(); g.setNext( new PaymentProcessorB() ); g.setNext( new PaymentProcessorC() ); return g; }

slide-76
SLIDE 76

public abstract class PaymentProcessor { private PaymentProcessor next; public void setNext( PaymentProcessor processors ) { if ( next == null ) { next = processors; } else { next.setNext( processors ); } } public Payment process( Payment p ) { handle( p ); if ( next != null ) { return next.process( p ); } else { return p; } } protected abstract void handle( Payment p ); }

slide-77
SLIDE 77

public class PaymentProcessorA extends PaymentProcessor { @Override protected void handle( Payment p ) { System.out.println( "PaymentProcessorA for payment: " + p.getAmount() ); } } public class PaymentProcessorB extends PaymentProcessor { @Override protected void handle( Payment p ) { System.out.println( "PaymentProcessorB for payment: " + p.getAmount() ); } }

slide-78
SLIDE 78

public static void main( String[] args ) { PaymentProcessor paymentProcessor = getPaymentProcessor(); paymentProcessor.process( new Payment( 10 ) ); //PaymentProcessorA for payment: 10 //PaymentProcessorB for payment: 10 //PaymentProcessorC for payment: 10 } private static PaymentProcessor getPaymentProcessor() { PaymentProcessor g = new PaymentProcessorA(); g.setNext( new PaymentProcessorB() ); g.setNext( new PaymentProcessorC() ); return g; }

slide-79
SLIDE 79

Function<Payment, Payment> processorA = p -> { System.out.println( "Processor A " + p.getAmount() ); return p; }; Function<Payment, Payment> processorB = p -> { System.out.println( "Processor B " + p.getAmount() ); return p; }; Function<Payment, Payment> processorC = p -> { System.out.println( "Processor C " + p.getAmount() ); return p; };

slide-80
SLIDE 80

Function<Payment, Payment> processorA =

p -> { System.out.println( "Processor A " + p.getAmount() ); return p; }; Function<Payment, Payment> processorB = p -> { System.out.println( "Processor B " + p.getAmount() ); return p; }; Function<Payment, Payment> processorC = p -> { System.out.println( "Processor C " + p.getAmount() ); return p; };

Function<Payment, Payment> chain = processorA.andThen( processorB ).andThen( processorC ); chain.apply( new Payment( 10 ) ); //Processor A 10 //Processor B 10 //Processor C 10

slide-81
SLIDE 81

Observer

"Define uma dependência um-para-muitos entre objetos de modo que quando um objeto muda o estado, todos seus dependentes são notificados e atualizados automaticamente. Permite que

  • bjetos interessados sejam avisados da mudança de estado ou
  • utros eventos ocorrendo num outro objeto."

GAMMA, Erich et al.

slide-82
SLIDE 82

Servidor de Cotação Banco

Casa de Câmbio Investidor register() notify() notify() notify()

slide-83
SLIDE 83

public interface Subject { void registerObserver( Observer observer ); } public interface Observer { void notify( Cotacao lance ); }

slide-84
SLIDE 84

public class Banco implements Observer { @Override public void notify( Cotacao cotacao ) { //some cool stuff here System.out.println( "Banco: " + cotacao ); } } public class Investidor implements Observer { @Override public void notify( Cotacao cotacao ) { //some cool stuff here System.out.println( "Investidor: " + cotacao ); } }

slide-85
SLIDE 85

public class ServidorCotacao implements Subject { private List<Observer> observers = new ArrayList<>(); public void novaCotacao( Cotacao cotacao ) { notifyObservers( cotacao ); } @Override public void registerObserver( Observer observer ) {

  • bservers.add( observer );

} private void notifyObservers( Cotacao lanceAtual ) {

  • bservers.forEach( o -> o.notify( lanceAtual ) );

} }

slide-86
SLIDE 86

public class Main { public static void main( String[] args ) { Banco banco = new Banco(); Investidor investidor = new Investidor(); ServidorCotacao servidorCotacao = new ServidorCotacao(); servidorCotacao.registerObserver( banco ); servidorCotacao.registerObserver( investidor ); servidorCotacao.novaCotacao( new Cotacao( "USD", 4 ) ); } } Banco: Cotacao{moeda='USD', valor=4} Investidor: Cotacao{moeda='USD', valor=4}

slide-87
SLIDE 87

@Override public void registerObserver( Observer observer ) {

  • bservers.add( observer );

} public class Banco implements Observer { @Override public void notify( Cotacao cotacao ) { //some cool stuff here System.out.println( "Banco: " + cotacao ); } }

slide-88
SLIDE 88

public class Main { public static void main( String[] args ) { ServidorCotacao servidorCotacao = new ServidorCotacao(); servidorCotacao.registerObserver( cotacao -> System.out.println( "Banco: " + cotacao ) ); servidorCotacao.registerObserver( cotacao -> { //some cool stuff here System.out.println( "Investidor: " + cotacao ) } ); servidorCotacao.novaCotacao( new Cotacao( "BRL", 1 ) ); } } Banco: Cotacao{moeda='BRL', valor=1} Investidor: Cotacao{moeda='BRL', valor=1}

slide-89
SLIDE 89

Currying

slide-90
SLIDE 90

f(x,y) = y/x

slide-91
SLIDE 91

f(2,3) f(x,y) = y/x

slide-92
SLIDE 92

f(2, y) = y / 2 g(y) = f(2,y) = y/2

slide-93
SLIDE 93

g(y) = f(2,y) = y/2 g(3) = f(2,3) = 3/2

slide-94
SLIDE 94

CtoF(x) = x * 9/5 + 32

slide-95
SLIDE 95

static double converter( double x, double f, double b ) { return x * f + b; } public static void main( String[] args ) { Double celsius = 15.0; Double fahrenheit = converter( celsius, 9.0 / 5, 32 ); //59 F }

slide-96
SLIDE 96

static double converter( double x, double f, double b ) { return x * f + b; }

static DoubleUnaryOperator curriedConverter( double f, double b ) { return x -> x * f + b; }

slide-97
SLIDE 97

static DoubleUnaryOperator curriedConverter( double f, double b ) { return x -> x * f + b; } public static void main( String[] args ) { DoubleUnaryOperator convertCtoF = curriedConverter( 9.0 / 5, 32 ); convertCtoF.applyAsDouble( 35 ); //95 F convertCtoF.applyAsDouble( 15 ); //59 F }

slide-98
SLIDE 98

static DoubleUnaryOperator curriedConverter( double f, double b ) { return x -> x * f + b; } public static void main( String[] args ) { DoubleUnaryOperator convertCtoF = curriedConverter( 9.0 / 5, 32 ); convertCtoF.applyAsDouble( 35 ); //95 F DoubleUnaryOperator convertKmToMi = curriedConverter( 0.6214, 0 ); convertKmToMi.applyAsDouble( 804.672 ); //500milhas }

slide-99
SLIDE 99

DoubleUnaryOperator convertBRLtoUSD = curriedConverter( 0.27, 0 ); double usd = convertBRLtoUSD.applyAsDouble( 100 );//27 USD DoubleUnaryOperator convertUSDtoEUR = curriedConverter( 0.89, 0 ); convertUSDtoEUR.applyAsDouble( usd ); //24.03 EUR convertBRLtoUSD.andThen( convertUSDtoEUR ).applyAsDouble( 100 ); //24.03 EUR

slide-100
SLIDE 100

Design Patterns + Java + Programação Funcional <3

slide-101
SLIDE 101

Obrigado

Eder Ignatowicz @ederign