Objekt-orienterat vs funktionellt Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Relevanta dokument
Objekt-orienterat vs funktionellt Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2017

Objekt-orienterat vs funktionellt Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

Lambdas. (och fler design patterns) Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2017

Generics och polymorfism. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Generics och polymorfism. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

Static vs Dynamic binding Polymorfism. Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

Generic type declarations. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Classes och Interfaces, Objects och References, Initialization

Classes och Interfaces, Objects och References Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Subtyping, co- och contra-variance. Objekt-orienterad programmering och design Alex Gerdes, 2016

Static vs Dynamic binding Polymorfism. Objekt-orienterad programmering och design Alex Gerdes, 2016

Subtyping, co- och contra-variance. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016 Johannes Åman Pohjola, 2017

Arv. Fundamental objekt-orienterad teknik. arv i Java modifieraren protected Lägga till och modifiera metoder med hjälp av arv Klass hierarkier

Mutability och State. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

Modulär design. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

DAT043 - Föreläsning 7

Principles of subclasses. Objekt-orienterad programmering och design Alex Gerdes, 2018

Observer Pattern och MVC. Objekt-orienterad programmering och design Alex Gerdes, 2016

UML. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Laboration 1: Figurer i hierarki

Föreläsning 8 - del 2: Objektorienterad programmering - avancerat

Modulär design Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Kopiering av objekt i Java

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 11 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Observer Pattern och MVC. Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Erik Nilsson, Institutionen för Datavetenskap, LiU

Principles of subclasses Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

F8 - Arv. ID1004 Objektorienterad programmering Fredrik Kilander

Idag. statiska metoder och variabler. private/public/protected. final, abstrakta klasser, gränssnitt, delegering. wrapper classes

"Är en"-relation. "Har en"-relation. Arv. Seminarium 2 Relevanta uppgifter. I exemplet Boll från förra föreläsningen gällde

Objektorienterad Programkonstruktion. Föreläsning 4 8 nov 2016

Static vs Dynamic binding Override vs Overload. Objekt-orienterad programmering och design Alex Gerdes och Sólrún Halla Einarsdóttir, 2018

Tentamen. DD2385 Programutvecklingsteknik vt 2014 Måndagen den 2 juni 2014 kl Hjälpmedel: penna, suddgummi, linjal

UML. Översikt UML. Relationer mellan klasser. A är ett aggregerat av B:n. Kontor aggregat av Enheter. 12 olika diagramtyper, bl.a.

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

Objektorienterad Programmering DAT043. Föreläsning 9 12/2-18 Moa Johansson (delvis baserat på Fredrik Lindblads material)

Subtyping och variance. Objekt-orienterad programmering och design Alex Gerdes, 2018

Vad kännetecknar en god klass. Vad kännetecknar en god klass. F12 Nested & Inner Classes

Ett problem. Kontrollstrukturer och arrayer. Arrayer. Lösningen. Arrayer och hakparanteser. Exempel int[] results; results = new int[10]; // 0..

Exempel. Arrayer. Lösningen. Ett problem. Arrayer och hakparanteser. Arrayer

Mer OOP. Variation i typ. Medlen repetition. Generiska klasser. Gränssnitt - Interface. Mer om klasser Några exempel UML

Objektorienterad Programkonstruktion. Föreläsning 2 2 nov 2016

Föreläsning 3: Booleans, if, switch

TENTAMEN I DATAVETENSKAP

DAT043 - föreläsning 8

Sätt att skriva ut binärträd

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

Abstrakt datatyp. -Algoritmer och Datastrukturer- För utveckling av verksamhet, produkter och livskvalitet.

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 2 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Arrayer. results

Design Patterns. Objekt-orienterad programmering och design Alex Gerdes, 2016

Föreläsning 8. Arv. Arv (forts) Arv och abstrakta klasser

Idag. Javas datatyper, arrayer, referenssemantik. Arv, polymorfi, typregler, typkonvertering. Tänker inte säga nåt om det som är likadant som i C.

Separation of Concern. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

2I1049 Föreläsning 5. Objektorientering. Objektorientering. Klasserna ordnas i en hierarki som motsvarar deras inbördes ordning

Tentamen. DD2385 Programutvecklingsteknik vt 2015 Fredagen den 5 juni 2015 kl Hjälpmedel: penna, suddgummi, linjal

Laboration 2: Designmönster

Kort om klasser och objekt En introduktion till GUI-programmering i Java

Subklasser och arv Inledning till grafik (JFrame och JPanel). Något om interface. Objektorienterad programvaruutveckling GU (DIT011) Subklasser

Objektorienterad programmering

Klassdeklaration. Metoddeklaration. Parameteröverföring

Repetition av OOP- och Javabegrepp

Arv: Fordonsexempel. Arv. Arv: fordonsexempel (forts) Arv: Ett exempel. En klassdefinition class A extends B {... }

Objekt-orienterad programmering och design. DIT953 Niklas Broberg, 2018

Inkapsling (encapsulation)

Sammanfattning och Tentamensinfo Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

Föreläsning 15: Repetition DVGA02

OOP Objekt-orienterad programmering

Repetition av OOP- och Javabegrepp

TDDC74 Programmering: Abstraktion och modellering Tenta, kl 14 18, 11 juni 2014

Objektorienterade programmeringsspråk. Objektorienterade språk. Den objekt-orienterade modellen. Jämför med icke-oo

Innehåll. dynamisk bindning. och programmering CRC) u Arv, polymorfi och

Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Grundläggande programmering, STS 1, VT Sven Sandberg. Föreläsning 14

Principer, Patterns och Tekniker. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

I STONE. I Variabler, datatyper, typkonvertering. I Logiska och matematiska uttryck. I Metoder-returvärde och parametrar. I Villkorssatser if/else

F9 - Polymorfism. ID1004 Objektorienterad programmering Fredrik Kilander

TDDC74 FÖRELÄSNING 9 ANDERS MÄRAK LEFFLER IDA/HCS

Föreläsning 4 Innehåll. Abstrakta datatypen lista. Implementering av listor. Abstrakt datatypen lista. Abstrakt datatyp

Principer, Patterns och Tekniker. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Omtentamen för TDA540 Objektorienterad Programmering. Institutionen för Datavetenskap CTH HT-17, TDA540. Dag: , Tid:

TDDC74 Programmering: Abstraktion och modellering Tentamen, lördag 29 augusti 2015, kl 8 12

Outline. Objektorienterad Programmering (TDDC77) Åsidosättning. Signatur. Åsidosättning. Abstrakta klasser. Ahmed Rezine.

Föreläsning 3. Stack

Objektorienterad Programkonstruktion. Föreläsning 9 30 nov 2016

Objektorienterad programmering E. Telefonboken, än en gång. Gränssnitt. Telefonboken med gränssnitt specificerat, del 1.

Tentamen ID1004 Objektorienterad programmering October 29, 2013

Java, klasser, objekt (Skansholm: Kapitel 2)

ADT Kö. Seminarium 4 Köer och Stackar Innehåll. Operationer. ADT Stack. Definition. Definition

Länkade strukturer. (del 2)

Tentamen i Objektorienterad modellering och diskreta strukturer

Arv innebär att man skapar en ny klass (subklass) utifrån en redan existerande klass (superklass, basklass).

Typhierarkier del 1 Gränssnitt, ärvning mellan gränssnitt, ärvning mellan klasser

F4 Klasser och Metoder. ID1004 Objektorienterad programmering Fredrik Kilander

Tentamen i Objektorienterad modellering och design Helsingborg

Föreläsning 10. ADT:er och datastrukturer

Laboration 2: Designmönster

Objektorienterad Programkonstruktion

Objektsamlingar i Java

Transkript:

Objekt-orienterat vs funktionellt Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Quiz Vad skiljer objekt-orienterade språk från funktionella språk? Funktionella språk har first-class functions, dvs funktioner som värden. Funktionella språk har algebraiska datatyper (ADTs) Objekt-orienterade språk har klasser och objekt med metoder och attribut. Objekt-orienterade språk har arv. Ett språk kan vara både objekt-orienterat och funktionellt. E.g. Scala.

Funktioner En funktion (i programmeringstermer) är en operation som tar ett eller flera argument, och ger ett resultat. Quiz: Vad skiljer en funktion från en metod? En statisk metod i Java är en funktion med annat namn. En instansmetod i Java är en funktion med särskild syntax, där instansen på vilken metoden anropas är ett implicit argument till funktionen. Ibland används distinktionen att en funktion ska vara deterministisk, eller till och med pure, men oftast inte.

Funktionella språk Ett programspråk sägs vara funktionellt om det tillåter oss att använda funktioner som om de vore värden ( first-class functions ): Deklarera variabler som representerar funktioner: f = show Applicera funktionsvariabler på argument:. x = f 5 Skicka funktioner som argument till andra funktioner (metoder). map f [1,2,3,4,5] Skapa anonyma funktioner som värden: map (\x -> x+5) [1,2,3,4,5] Exemplen givna med Haskell-syntax

Lambda expression Termen lambda expression ( lambda-uttryck ) beskriver just en funktion som används anonymt. Ursprunget är Alonzo Church s Lambda calculus. (\x -> x+5) = λx.x+5 Ta ett argument, som vi kallar x, och gör så här

Lambdas och Java I senaste versionen av Java (Java 8, 2014) har vi fått stöd för lambda expressions i Java. Vad vi kan göra med dessa är dock lite begränsat, jämfört med ett riktigt funktionellt språk. Problemet ligger i hur vi kan deklarera en funktions-typ. Java är ett statiskt typat språk, så allt måste ges en typ. I språk som (e.g.) Haskell finns enkel syntax för funktionstyper: f :: Int -> Int Java har historiskt inget sätt att skriva ut funktionstyper, och de som designade Java 8 ville inte göra för stora avsteg från Java s kärna.

Funktioner som objekt Det klassiska sättet, i Java innan version 8, att representera (något som liknar) funktioner var att gömma dem inuti ett objekt: public interface MyFunctionType { public int apply(int x); } public class MyAddFive implements MyFunctionType { public int apply(int x) { return x+5; } }; MyFunctionType f = new MyAddFive(); int y = f.apply(5); int[] xs = { 1,2,3,4,5 }; int[] ys = new int[xs.length]; for (int i = 0; i < xs.length; i++) { ys[i] = f.apply(xs[i]); }

Anonymous classes Ett lite smidigare sätt, som fungerade även innan Java 8, var att skapa instanser av så kallade anonyma klasser. public interface MyFunctionType { public int apply(int x); } MyFunctionType f = new MyFunctionType() { public int apply(int x) { return x+5; } }; int y = f.apply(5); Vi definierar klassen samtidigt som vi skapar instansen. Klassen har inget namn, därav anonymous. Allt vi vet om den är att den implementerar MyFunctionType.

Lambdas Med hjälp av lambdas blir koden ännu lättare: public interface MyFunctionType { public int apply(int x); } MyFunctionType f = x -> x+5; int y = f.apply(5); Vi definierar den anonyma klassen med hjälp av förenklad lambda-syntax.

Functional Interface Ett functional interface i Java är ett interface som deklarerar exakt en metod: @FunctionalInterface public interface MyFunction { public int apply(int x); } Vi kan använda lambda expressions som short-hand för objekt som implementerar ett sådant functional interface, e.g. MyFunction f = x -> x+5; int y = f.apply(5); Annotationen @FunctionalInterface är bara en hjälp ger felmeddelande om interfacet inte uppfyller kriteriet.

Lambda syntax Ett lambda expression i Java har följande syntax: En lista av parametrar, e.g. (x,y,z) Om vi bara har en parameter kan vi utelämna parenteserna. Om vi inte tar något argument alls skriver vi () (Lustigt nog har vi inget lambda först.) En pil: -> En method body: { return x+5; } Om vår body består av bara ett expression vars resultat ska returneras behöver vi varken {} eller return, vi skriver bara uttrycket: x+5 (x,y) -> x+y; x -> x+5; s -> { System.out.println(s); }; () -> 42; Exempel på giltiga lambda expressions i Java.

Live code Macro.addTransform

Command Pattern Encapsulate the information needed to perform an action at a later time. Invoke the action from external clients without depending on the object the action belongs to. Lägg information som behövs för att utföra ett visst anrop i ett objekt, som kan användas av klienter utan att de behöver veta vad anropet gör internt. Syftet med Command Pattern kan dels vara att undvika beroenden mellan klienter och utförare; dels att få makron som kan sekvensieras, skickas mellan objekt, aggregeras, ibland även ges extra funktionalitet (e.g. räkna hur många gånger anropet utförts).

Command Pattern Command <<Interface>> + execute() : void Invoker - commands : List<Command> + addcommand(command) : void invoke() : void Beroendena från Client kan skilja lite mellan olika varianter och användningar. Client ConcreteCommand - state : + execute() : void Receiver + action() : void public void execute() { receiver.action( ); } Argument- och retur-typer kan skilja mellan olika användningar; jag har visat den enklast tänkbara uppsättningen här.

Inte lambdas Lambda expressions är ett smidigt sätt att förkorta kod. Vi kan dock göra mer med anonyma klasser än vad lambdas klarar: En anonym klass kan användas även när interfacet i fråga inte är functional, dvs har fler (eller färre) än exakt en metod. Skriver vi ut hela klassen kan vi även inkludera attribut, och t ex få state: MyFunctionType f = new MyFunctionType() { public int counter = 0; public int apply(int x) { counter++; return x+5; } }; Självklart borde vi använda en getter istället för att göra counter public... int y = f.apply(5); int n = f.counter;

Quiz Java 8 har lambdas är Java funktionellt nu? Svar: Nej. Lambdas är inte first-class functions, av flera skäl: Det är inte funktionen som lagras i f i koden nedan; det är objektet som funktionen bor i. MyFunction f = x -> x+5; int y = f.apply(5); Vi kan inte applicera e.g. f(5) f har typen MyFunction, inte int -> int. Vi kan alltså inte använda f i situationer där vi förväntar oss något som implementerar ett annat functional interface, även om detta andra interface också specificerar en metod som tar en int och returnerar en int. och first-class functions är inte allt som definierar det funktionella paradigmet.

Objekt vs ADTs I funktionella språk används algebraiska datatyper, e.g.: data MyIntTree = Leaf Int Node MyIntTree MyIntTree En ADT består av olika konstruktorer (inte samma sak som constructors i Java), som kan ta argument. En ADT kan plockas isär med hjälp av pattern matching, e.g.: sumtree (Leaf n) = n sumtree (Node l r) = sumtree l + sumtree r

Enums Javas Enum-klasser ger oss en väldigt rudimentär form av ADTer: Enums kan specificera en lista av olika varianter. Varianterna i en enum kan inte ta argument. Varianterna i en enum kan inte vara rekursiva (följer av att de inte kan ta argument). public enum SignalStatus { RED, TOGREEN, GREEN, TORED; } Vi skulle inte kunna implementera e.g. MyIntTree som en enum.

Quiz Vad är det för skillnad på objekt och algebraiska datatyper? Svar: De är (i någon mening) varandras transponering. (Obs: Min användning av termen transponering här är inte formell, eller vedertagen. Jag använder den för att göra en liknelse.)

Transponering När vi arbetar med objekt grupperar vi data tillsammans med de grundläggande metoder som arbetar över datan. Olika uppsättningar data, även om de är relaterade, läggs separat. E.g. Vi definierar en Triangle och dess metoder, e.g. move och getcenterpoint, tillsammans, men separat från en Rectangle och dess metoder. När vi arbetar med ADTs grupperar vi alla uppsättningar data som är relaterade i en gemensam datatyp. Olika funktioner över denna datatyp läggs separat. E.g. Vi definierar en datatyp med varianterna (konstruktorerna) Triangle och Rectangle. Metoderna för dessa, e.g. move eller getcenterpoint, definieras var och en för sig för alla varianter samtidigt.

Quiz Tänk extensibility: På vilka sätt kan vi utöka funktionaliteten, utan att ändra existerande kod när vi arbetar med ADTer? när vi arbetar med (hierarkier av) objekt? På vilket sätt kan vi inte utöka funktionaliteten utan att ändra kod? Svar: Med ADTer kan vi lägga till metoder, men inte varianter. Med objekt kan vi lägga till varianter, men inte metoder.

The Expression Problem Phil Wadler (FP/Haskell guru) myntade uttrycket som en utmaning: The expression problem is a new name for an old problem. The goal is to define a datatype by cases, where one can add new cases to the datatype and new functions over the datatype, without recompiling existing code, and while retaining static type safety (e.g., no casts). Än så länge har vi ingen bra lösning på detta problem, i något språk. Konsekvens: Vi behöver välja vilken sorts extensibility vi vill kunna tillhandahålla.

Live code Visitor

Visitor Pattern Separate an algorithm from the object structure it operates over, allowing new algorithms to be added without the objects knowing about them, by introducing methods that allow object type pattern matching. Gör det möjligt att (i efterhand) definiera algoritmer som kan operera över ett antal olika klasser, utan att dessa klasser behöver känna till dem. Ger extensibility i form av att vi kan lägga till fler metoder/beteenden. Den riktiga styrkan i Visitor är att den låter oss skriva metoder som fungerar över annars helt olika element, av helt olika klasser: E.g. en Car, dess Engine samt den World den befinner sig i.

Visitor Pattern IVisitor <<Interface>> + visit(concreteelement1) : void + visit(concreteelement2) : void IVisitable <<Interface>> + accept(ivisitor) : void Notera att olika konkreta element som tillåter visitors kan vara av helt orelaterade typer. ConcreteVisitor +visit(concreteelement1) : void +visit(concreteelement2) : void ConcreteElement1 + accept(ivisitor) : void ConcreteElement2 + accept(ivisitor) : void public void accept(ivisitor v) { v.visit(this); }

Sidbyte Med Visitor Pattern byter vi i någon mening sida: Vi gör det möjligt att lägga till nya algoritmer (metoder) i efterhand. Vi har dock låst objekt-strukturen, och eventuella nya klasser vi lägger till kan inte använda sig av de algoritmer vi Visitor Pattern kräver också att Visitor-objektet känner till (och därför beror på) alla olika klasser den kan besöka. Slutsats: Visitor Pattern låter oss behandla (grupper av) klasser som om de vore ADTs (typ, nästan).

Servant Pattern Define extra behavior (methods) for a group of classes separate from the classes themselves. Definiera hjälp-funktioner för klasser separat från klasserna själva. Dvs kombinera dessa klassers publikt användbara metoder för att tillhandahålla mer avancerade beteenden och beräkningar. En sådan hjälp-funktion kommer typiskt vara static, och ta som första argument det objekt den ska utföra beräkningen eller beteendet på. Dvs gör det implicita argumentet explicit precis som i e.g. Haskell! Funkar ofta bra tillsammans med Visitor Pattern, men kan också användas enskilt.

Servant Pattern Servant Pattern innebär att vi lägger till funktioner som vi skulle gjort i funktionella språk genom att definiera dem separat, med hjälp av redan existerande funktioner. Av vissa kallat ett anti-pattern (dvs dålig design). Sådana funktioner kan lika gärna läggas som default-metoder i det interface de arbetar över, eller som template methods i en abstrakt superklass. Dock inte i efterhand utan att ändra i kod kräver tanke före. Kan dock ha sina användningar: Som en del i en Facade, som ska tillhandahålla förenklad funktionalitet. När vi vill definiera nya funktioner över klasser som ligger i ett bibliotek vi inte kan ändra på.

Visitors och Interface Segregation Interface Segregation Principle säger att vi vill ha små, väldefinierade gränssnitt. Detta är mycket relevant att tänka på när vi implementerar Visitor Pattern. Om vi definierar ett enda gränssnitt Visitor som specificerar ett antal olika element att besöka, då måste en Visitor definiera kod för att hantera alla dessa olika. Men vi kanske bara vill besöka en eller två av dem? ISP to the rescue: Definiera små gränssnitt, och sätt ihop dem till större vid behov.

Sammanfattning Java lambdas = poor functions (men användbara). Java enums = broke ADTs (men användbara). OO har metoder på insidan, FP har metoder externt. Visitor Pattern låter oss byta sida och definiera metoder externt, men till kostnaden att vi inte längre enkelt kan lägga till fler varianter Vi byter en sorts extensibility mot en annan.

What s next Block 8-1: Tentamensinfo!!!