Entdecken Sie Millionen von E-Books, Hörbüchern und vieles mehr mit einer kostenlosen Testversion

Nur $11.99/Monat nach der Testphase. Jederzeit kündbar.

Durchstarten mit Scala: Tutorial für Einsteiger (2. Aufl.)
Durchstarten mit Scala: Tutorial für Einsteiger (2. Aufl.)
Durchstarten mit Scala: Tutorial für Einsteiger (2. Aufl.)
eBook313 Seiten2 Stunden

Durchstarten mit Scala: Tutorial für Einsteiger (2. Aufl.)

Bewertung: 0 von 5 Sternen

()

Vorschau lesen

Über dieses E-Book

Kaum eine andere Programmiersprache kombiniert derart elegant wie Scala die Vorzüge verschiedener Programmierparadigmen und ermöglicht gleichzeitig die vollständige Integrationsfähigkeit mit Java. Scala bringt nicht nur objektorientiertes und funktionales Programmieren zusammen, sondern erlaubt trotz statischer Typisierung das Schreiben von leichtgewichtigem und leicht verständlichem Code. Das Ergebnis ist eine Programmiersprache, mit der einfache Aufgaben auf einfache Weise bewerkstelligt werden können und die für komplexe Herausforderungen maßgeschneiderte Lösungen ermöglicht. Dieses Buch bietet allen Scala-Interessierten und Einsteigern einen praxisnahen und zielgerichteten Weg, Scala zu lernen. Dabei legt der Autor den Fokus bewusst auf die Praxis der Softwareentwicklung, um dem Leser die Vorteile von Scala möglichst direkt näher zu bringen. Im Rahmen eines durchgängigen Fallbeispiels wird der gesamte Zyklus der Softwareentwicklung abgedeckt: vom Einrichten der Entwicklungsumgebung über Experimentieren mit dem interaktiven Interpreter (REPL) und testgetriebene Entwicklung unter Verwendung von Testbibliotheken bis hin zur Verwendung von Bibliotheken wie Scalactic und Akka HTTP. Selbstverständlich wird der Leser dabei Schritt für Schritt mit allen Grundlagen von Scala vertraut gemacht.
SpracheDeutsch
Herausgeberentwickler.press
Erscheinungsdatum2. Nov. 2015
ISBN9783868026795
Durchstarten mit Scala: Tutorial für Einsteiger (2. Aufl.)

Ähnlich wie Durchstarten mit Scala

Ähnliche E-Books

Programmieren für Sie

Mehr anzeigen

Ähnliche Artikel

Rezensionen für Durchstarten mit Scala

Bewertung: 0 von 5 Sternen
0 Bewertungen

0 Bewertungen0 Rezensionen

Wie hat es Ihnen gefallen?

Zum Bewerten, tippen

Die Rezension muss mindestens 10 Wörter umfassen

    Buchvorschau

    Durchstarten mit Scala - Heiko Seeberger

    2015

    1 Warum Scala?

    Ja, warum sollten wir uns eigentlich mit Scala beschäftigen? Mit Blick auf die schiere Vielzahl an Programmiersprachen eine berechtigte Frage. Wir können diese auch anders formulieren, und zwar: Welche Vorteile bringt Scala gegenüber anderen Programmiersprachen?

    Mit der Antwort wollen wir es uns hier ein bisschen einfacher machen, indem wir ausschließlich die Java-Plattform betrachten. Das bedeutet, dass wir nur solche Programmiersprachen unter die Lupe nehmen, die auf der Java Virtual Machine (JVM) laufen. Diese Einschränkung halten wir deswegen für legitim, weil die Java-Plattform sehr weit verbreitet ist und gerade im Bereich der Unternehmensanwendungen eine durchaus dominante Stellung innehat. Gute Gründe hierfür sind – ohne Anspruch auf Vollständigkeit – das Write-once-run-everywhere-Prinzip¹ sowie die große Menge an verfügbaren Bibliotheken für nahezu alle denkbaren Anwendungsfälle.

    1.1 Was ist Scala?

    Vor der Frage nach dem Warum steht erst einmal diejenige nach dem Was. Auf einen Satz kondensiert lautet unsere Antwort: Scala ist eine moderne und dennoch reife, objektfunktionale, praxisorientierte, statisch typisierte und trotzdem leichtgewichtige Sprache für die JVM, die vollständig kompatibel zu Java ist. Wir wollen im Folgenden kurz ein paar dieser Eigenschaften herauspicken und genauer erläutern. Alles Weitere bzw. sich ein Bild von Scala zu machen, überlassen wir dann dem Leser für den weiteren Verlauf dieses Buchs.

    Scala wurde von Martin Odersky, Professor an der Schweizer Hochschule EPFL², erfunden, der zuvor bereits an wichtigen konzeptionellen Neuerungen für Java gearbeitet hatte, zum Beispiel an den Generics³. Die erste Version wurde bereits 2004⁴ veröffentlicht, sodass wir bereits auf über ein Jahrzehnt mit Scala zurückblicken können.

    Anfangs, als die Nutzerbasis noch nicht so groß war, leistete sich Scala bei neuen Versionen – auch bei so genannten Minor-Releases – immer wieder binäre Inkompatibilitäten zu vorherigen Versionen. Aber spätestens seit der Version 2.9, die zeitlich ungefähr mit der Gründung der Firma Typesafe⁵, die kommerziell hinter Scala und anderen Technologien wie Akka⁶ und Play steht, zusammenfällt, ist das Geschichte: Seitdem sind alle Minor-Releases mit derselben Major-Release-Nummer binär kompatibel, also z. B. 2.9.1 und 2.9.2. Nur bei Major-Releases, die 18 Monate oder länger auseinanderliegen, wird es notwendig, ein gesamtes Projekt einschließlich aller Bibliotheken auf die neue Version zu heben. Aber auch das ist in der Regel ein Einfaches, weil dank der Community Builds⁷ die meisten populären Bibliotheken quasi gleichzeitig mit einem Major-Release von Scala für genau dieses veröffentlicht werden.

    Scala kann also getrost als reife Sprache betrachtet werden. Zur weiteren Charakterisierung ist vermutlich der hybride Charakter der Sprache das hervorstechendste Merkmal: Scala ist einerseits objektorientiert⁸, und das sogar viel stringenter als Java. Andererseits ermöglicht Scala funktionale Programmierung⁹, also „so etwas mit Lambdas", die ja spätestens seit Java 8 auch unter Java-Entwicklern steigende Bekanntheit genießen. Scala bietet nicht nur das Beste aus beiden Welten, sondern vereinigt die zwei Paradigmen weitreichend zu einer objektfunktionalen Sprache aus einem Guss.

    Abschließend noch das aus unserer Sicht wichtigste Kriterium für den großen Erfolg von Scala: Wir können aus Scala heraus jeglichen Java-Code nutzen, egal ob unsere liebgewonnenen Bibliotheken für Logging, Persistenz etc. oder unsere eigenen Java-Projekte. Durch diese Abwärtskompatibilität müssen wir nicht bei Null anfangen, sondern können unsere bestehenden Java-Aktiva ver- und aufwerten.

    1.2 Warum Scala statt Java?

    Das führt uns direkt zur Frage, warum wir uns mit Scala beschäftigen sollten, wo es doch Java gibt. Die Antwort fällt uns sehr leicht, und wir können sie sehr deutlich formulieren: Im Vergleich zu Java können wir mit Scala sowohl produktiver arbeiten, als auch die Qualität steigern. Abgesehen davon macht das Programmieren mit Scala einfach mehr Spaß, wobei das natürlich eine subjektive Einschätzung aus unserer Sicht ist.

    Zugegebenermaßen benötigen wir zunächst ein wenig Zeit, um mit Scala durchzustarten, aber die langfristigen Vorteile überwiegen mit Sicherheit den Nachteil des Lernaufwands, den jede neue Technologie mit sich bringt. Gerade Java-Programmierer sollten hierfür ein offenes Ohr haben, denn auch Java ist noch recht jung, weshalb nicht wenige von uns zuvor von anderen Programmiersprachen auf Java umgestiegen sind. Welches sind nun die Gründe dafür, dass Scala Produktivität und Qualität im Vergleich zu Java zu steigern vermag? Wir wollen hierfür die folgenden ins Feld führen: weniger Code und höheres Abstraktionsniveau.

    Wie wir im weiteren Verlauf dieses Buchs sehen werden, benötigen wir mit Scala signifikant weniger Code als mit Java, um ein Programm zu realisieren, das dieselben Anforderungen erfüllt. Mit signifikant meinen wir mindestens eine Reduktion von 50 Prozent, möglicherweise bzw. situativ sogar bis zu 80 Prozent.

    Es ist zwar richtig, dass moderne Java-Entwicklungsumgebungen beim Schreiben eines großen Teils des eingesparten Codes sehr gut unterstützen können; man denke zum Beispiel an Funktionen zur Erzeugung von Zugriffsmethoden – also Getter und Setter – wie sie jede moderne integrierte Entwicklungsumgebung (IDE) bietet. Somit sind wir beim Codeschreiben nicht unbedingt schneller. Aber wenn wir an unseren Alltag als Programmierer denken, dann werden die meisten von uns feststellen, dass wir insgesamt mehr Zeit darauf verwenden, Code zu lesen und zu verstehen, als zu schreiben. Das betrifft nicht nur fremden Code, den wir übernehmen oder warten dürfen, sondern auch eigenen, den wir vor Wochen oder gar Monaten geschrieben haben und dessen Verständnis uns heute einiges abverlangt.

    Es gibt Untersuchungen¹⁰, die belegen, dass die Geschwindigkeit, wie schnell wir Code lesen und verstehen können, ganz entscheidend von der Codemenge bestimmt wird. Wenn wir zum Beispiel an eine typische JavaBean denken, die quasi nur einen Datencontainer für eine Handvoll Properties darstellt, dann sehen wir uns einer gewaltigen Menge an semantisch wenig wertvollem Code gegenüber: Getter, die nur ein privates Feld zurückgeben. Oft auch Setter, die nur ein privates Feld verändern. Vermutlich auch mehrere Konstruktoren, mit denen alle oder zumindest einige der Felder initialisiert werden können. Und nicht selten auch noch Implementierungen der Methoden equals, hashCode und toString. Wenn wir nun diesen Code lesen und verstehen wollen, dann müssen wir im Verstand einen Filter aktivieren, der all den überflüssigen Kitt ausblendet und nur die eigentliche Intention durchlässt.

    Ein explizites Beispiel gefällig? Wie wäre es mit einer Klasse für eine Person, die Vor- und Nachname haben soll. Im Vorgriff auf die Prinzipien der funktionalen Programmierung soll diese Person unveränderlich sein, d. h. einmal erzeugt können deren Attribute nicht mehr verändert werden. Dieses Prinzip des Immutable Object¹¹ ist natürlich auch in Java bekannt, nicht erst seit dem Buch „Effective Java"¹² von Joshua Bloch. Zunächst zeigen wir den Java-Code, bei dem die Methoden equals und hashCode von der Entwicklungsumgebung generiert wurden:

    public class Person {

        private final String firstName;

        private final String lastName;

        public Person(String firstName, String lastName) {

            this.firstName = firstName;

            this.lastName = lastName;

        }

        public String getFirstName() {

            return firstName;

        }

        public String getLastName() {

            return lastName;

        }

        @Override

        public boolean equals(Object o) {

            if (this == o) return true;

            if (o == null || getClass() != o.getClass()) return false;

            Person person = (Person) o;

            if (firstName != null ?

                !firstName.equals(person.firstName) :

                person.firstName != null) return false;

            if (lastName != null ?

                !lastName.equals(person.lastName) :

                person.lastName != null) return false;

            return true;

        }

        @Override

        public int hashCode() {

            int result = firstName != null ? firstName.hashCode() : 0;

            result =

                31 * result + (lastName != null ? lastName.hashCode() : 0);

            return result;

        }

    }

    Und nun zum Vergleich der äquivalente Scala-Code, der wirklich funktional vollständig identisch ist, wie wir im Verlauf dieses Buchs noch sehen werden:

    case class Person(firstName: String, lastName: String)

    Nur eine einzige Codezeile in Scala im Vergleich zu – je nachdem wie wir zählen – zwanzig oder mehr in Java. Das liegt daran, dass wir nicht all die kleinen Details wie zum Beispiel die Zugriffsmethoden oder equals und hashCode ausprogrammieren müssen, sondern der Scala-Compiler diese Arbeit für uns macht. Zwar haben gerade erfahrene Java-Entwickler einen besonders gut geschulten kognitiven Filter für irrelevante Details, sodass wir beim Geschwindigkeitsvergleich für Lesen und Verstehen natürlich nicht von einem Verhältnis 1:20 ausgehen dürfen. Aber sicher kann niemand ernsthaft bestreiten, dass dieser Scala-Code nicht um Faktoren rascher aufgenommen werden kann als der entsprechende Java-Code. Und nun stellen wir uns einmal ein umfangreicheres Beispiel vor, bei dem wir den Java-Code ohne mehrfaches Blättern bzw. Scrollen gar nicht mehr lesen können.

    Weiter gibt es Aussagen¹³, dass zwischen der Codemenge und der Anzahl von Fehlern ein direkter Zusammenhang besteht. Oder anders ausgedrückt: je mehr Code, desto mehr Fehler. Unabhängig davon, ob das im Allgemeinen tatsächlich zutrifft, leuchtet das zumindest für unser Beispiel sofort ein. Denn der Java-Code hat ein niedriges Abstraktionsniveau, geht also stark ins Detail, und da versteckt sich bekanntlich gerne der eine oder andere Fehler. Man betrachte bloß obige Implementierungen von equals und hashCode.

    Im Hinblick auf das Abstraktionsniveau betrachten wir als Beispiel eine Liste von Personen, die wir anhand ihrer Nachnamen sortieren möchten. In Java würden wir wohl – ganz im guten alten imperativen Programmierstil – Hilfsvariablen anlegen und Schleifen programmieren, innerhalb derer wir die Hilfsvariablen verändern. Wir würden uns also im Detail darum kümmern, wie die Anforderung umzusetzen ist. In Scala hingegen machen wir das folgendermaßen, wobei wir davon ausgehen, dass wir eine Variable persons haben, die eine Liste von Personen repräsentiert.

    persons.sortWith((p1, p2) => p1.lastName < p2.lastName)

    Bitte nicht erschrecken! Hier geht es nicht darum, diesen Scala-Code exakt zu verstehen. Vielmehr wollen wir zwei Dinge deutlich machen. Erstens gibt es offenbar für Scala-Collections eine Methode sortWith, deren Bedeutung sich hoffentlich direkt aus dem Namen erschließt. Und zweitens übergeben wir dieser Methode ein Stück Code, welches offenbar die Sortierlogik enthält. Im Vorgriff auf spätere Kapitel: Es handelt sich hier um ein Lambda – also einen Funktionswert – der zwei Personen als Argumente entgegennimmt und deren Nachnamen mit dem Kleiner-Operator vergleicht.

    Auch wenn wir diesen Code jetzt noch nicht im Detail verstehen, können wir erkennen, dass ganz klar zum Ausdruck gebracht wird, was wir erreichen wollen: die Liste von Personen anhand der Nachnamen sortieren. Um das Wie hingegen, das uns eigentlich gar nicht interessiert, brauchen wir uns auch nicht kümmern, denn das ist in der Implementierung der Methode sortWith verborgen.

    Durch solch mächtige Methoden in Verbindung mit dem Sprachmerkmal von Funktionen erreichen wir in Scala eine höhere Abstraktionsebene, auf der wir uns nur noch um das Was kümmern müssen. Dadurch, dass wir die Details des Wie weglassen können, sind wir natürlich schneller und machen weniger Fehler, denn gerade die Details kosten Zeit und bergen hohes Risiko, etwas falsch zu machen.

    Selbstverständlich gibt es in Java seit der Version 8 auch Lambdas sowie das Streams API, welches grundsätzlich denselben funktionalen Ansatz ermöglicht, wenngleich dieses API bei Weitem nicht so reichhaltig ist, wie die Scala-Collections und Java-Collections zuerst zu Streams konvertiert werden müssen, um später mittels Collector wieder in eine Collection transformiert zu werden. Aber der funktionale Ansatz geht bei Scala viel weiter, wie wir im Verlauf dieses Buchs sehen werden.

    1.3 Warum Scala statt Groovy, Clojure und Co?

    So weit, so gut, Scala bietet also Vorteile gegenüber Java. Aber wie sieht es denn mit den anderen Programmiersprachen für die JVM aus, die in den letzten Jahren entstanden sind? Deren populärste Vertreter sind zurzeit wohl Groovy¹⁴ und Clojure¹⁵. All diese Sprachen haben ihre Stärken und setzen das eine oder andere innovative Konzept um, sodass wir volles Verständnis haben, eine solche Sprache anstatt Java zu verwenden.

    Wobei, es gibt da schon einen Punkt, bei dem wir skeptisch sind. Und zwar handelt es sich bei den genannten Sprachen und vielen weiteren um dynamisch typisierte Sprachen. Mit anderen Worten gibt es keine Überprüfung durch den Compiler, ob wir unsere Objekte oder Funktionen korrekt verwenden. Das wird zwar manchmal sogar als Vorteil verkauft, aber aus unserer Sicht ist es in den allermeisten Fällen genau anders herum: Für echte Softwareprojekte möchten wir auf keinen Fall eine Programmiersprache verwenden, die nicht statisch typisiert ist. Wir möchten nämlich viele Fehler bereits beim Compilieren erkennen und vermeiden, anstatt diese zur Laufzeit zu entdecken.

    Scala ist so eine statisch typisierte Sprache. Das bedeutet, dass wir einer Methode, die ein Argument vom Typ String erwartet, kein Date übergeben können. Nicht nur, aber auch darum geben wir Scala ganz klar den Vorzug vor etlichen anderen JVM-Sprachen.

    1 https://en.wikipedia.org/wiki/Write_once%2C_run_anywhere

    2 http://www.epfl.ch

    3 https://en.wikipedia.org/wiki/Generics_in_Java

    4 http://article.gmane.org/gmane.comp.lang.scala/17

    5 http://www.typesafe.com

    6 http://akka.io

    7 https://github.com/scala/community-builds

    8 https://de.wikipedia.org/wiki/Objektorientierung

    9 http://de.wikipedia.org/wiki/Funktionale_Programmierung

    10 http://infoscience.epfl.ch/record/138586/files/dubochet2009coco.pdf

    11 http://en.wikipedia.org/wiki/Immutable_object

    12 http://java.sun.com/docs/books/effective

    13 http://en.wikipedia.org/wiki/Source_lines_of_code

    14 http://www.groovy-lang.org

    15 http://clojure.org

    2 Entwicklungsumgebung

    In diesem Kapitel kümmern wir uns um unser Handwerkszeug, das wir für die Programmierung mit Scala benötigen. Wie wir sehen werden, stehen uns verschiedene Möglichkeiten zur Verfügung, von der minimalistischen Kommandozeile bis hin zur komfortablen IDE. Wir werden für die Beispiele in diesem Buch eine Konstellation wählen, wie wir sie auch regelmäßig in unseren echten Scala-Projekten einsetzen. Ganz konkret werden wir meist mit einer Kombination aus dem Build-Werkzeug sbt und der IDE IntelliJ IDEA arbeiten und manchmal auch – für schnelle Experimente – mit der von der Kommandozeile aus gestarteten REPL; die Details zu diesen Werkzeugen folgen unten. Allerdings ermutigen wir den Leser ausdrücklich, eigene Experimente anzustellen, um die für ihn am besten geeignete Wahl zu treffen.

    Selbstverständlich wollen wir nicht nur Trockenschwimmen üben, sondern die verschiedenen Möglichkeiten anhand des Klassikers schlechthin demonstrieren, also am guten alten „Hello World". Dabei werden uns natürlich die ersten Scala-Sprachmerkmale begegnen, die wir jedoch erst in späteren Kapiteln im Detail erläutern werden.

    2.1 Kommandozeilenwerkzeuge

    Wer bisher ausschließlich auf den Komfort einer IDE gesetzt hat und daher jetzt geneigt ist, dieses Kapitel zu überspringen, dem sei schon an dieser Stelle vorweg gesagt, dass Scala – anders als Java – über eine interaktive Konsole verfügt, die sich für Experimente und zum Testen ganz hervorragend eignet. Da dieses kleine aber feine Werkzeug aus dem Alltag eines Scala-Entwicklers quasi nicht wegzudenken ist, empfehlen wir dringend, sich zumindest das Kapitel 2.1.2 über scala zu Gemüte zu führen.

    Bevor wir die einzelnen Scala-Werkzeuge für die Kommandozeile betrachten können, müssen wir diese installieren. Dazu laden wir uns von der Scala-Website¹ die aktuelle Scala-Distribution als Archiv herunter, je nach Plattform im tgz- oder zip-Format. Zum Zeitpunkt, da wir dieses Buch schreiben, handelt es sich dabei um die Version 2.11.7 – spätere 2.11-Versionen sollten ohne Einschränkungen verwendbar sein.

    Nun entpacken wir das Archiv und fügen unserem Pfad das Verzeichnis bin der Scala-Distribution hinzu. Alternativ zum eben beschriebenen Vorgehen stellen manche Paketmanager, zum Beispiel Homebrew² für OS X, Installationspakete für Scala zur Verfügung. Im Resultat sollten wir jedenfalls – unabhängig vom Weg dorthin – in der Lage sein, das Folgende auf der Kommandozeile nachzuvollziehen:

    ~$ scala -version

    Scala code runner version 2.11.7 -- Copyright 2002-2013, LAMP/EPFL

    2.1.1 scalac

    Als Erstes wollen wir unsere Aufmerksamkeit auf den Scala-Compiler richten. Dafür benötigen wir natürlich Scala-Code zum Compilieren und das soll – wie oben angekündigt – der Klassiker „Hello World" sein:

    object Hello {

      def main(args: Array[String]): Unit = {

        println(Hello World)

      }

    }

    Wenn wir diesen Code betrachten, dann kommt uns einiges von Java bekannt vor, zum Beispiel die Methode main mit ihren Argumenten oder die Ausgabe mittels println. Anderes ist komplett neu, zum Beispiel die Schlüsselworte object und def oder die fehlenden Semikolons. Wir werden – wie versprochen – alle Scala-Sprachmerkmale in der nötigen Tiefe erläutern,

    Gefällt Ihnen die Vorschau?
    Seite 1 von 1