031.1 Lektion 1
Zertifikat: |
Web Development Essentials |
---|---|
Version: |
1.0 |
Thema: |
031 Softwareentwicklung und Webtechnologien |
Lernziel: |
031.1 Grundlagen der Softwareentwicklung |
Lektion: |
1 von 1 |
Einführung
Die ersten Computer wurden durch das mühsame Einstecken von Kabeln in Buchsen programmiert. Schon bald begannen Informatiker mit der endlosen Suche nach einfachen Möglichkeiten, dem Computer zu sagen, was er zu tun hat. Diese Lektion stellt die Werkzeuge der Programmierung vor. Sie behandelt die wichtigsten Methoden, mit denen Textanweisungen (Programmiersprachen) die Aufgaben formulieren, die Programmierer erledigen wollen, und die Werkzeuge, die das Programm in eine Form (Maschinensprache) umwandeln, so dass ein Computer sie ausführen kann.
Note
|
Im Folgenden verwenden wir die Begriffe Programm und Anwendung synonym. |
Quellcode
Programmierer entwickeln normalerweise eine Anwendung, indem sie eine textbasierte Beschreibung der gewünschten Aufgabe verfassen, die als Quellcode oder Source Code bezeichnet wird. Der Quellcode ist in einer sorgfältig definierten Programmiersprache geschrieben, die beschreibt, was der Computer auf einer für Menschen verständlichen höheren Abstraktionsebene tun kann. Es gibt auch Werkzeuge, mit denen Programmierer und sogar Nicht-Programmierer ihre Gedanken visuell ausdrücken können, aber das Schreiben von Quellcode ist immer noch die vorherrschende Art zu programmieren.
So wie eine natürliche Sprache über Substantive, Verben, Konstruktionen etc. verfügt, um Gedanken strukturiert auszudrücken, sind die Wörter und Zeichen in einer Programmiersprache symbolische Darstellungen von Operationen, die die Maschine ausführt.
In diesem Sinne unterscheidet sich Quellcode nicht wesentlich von anderen Texten, in denen ein Autor die bewährten Regeln einer natürlichen Sprache nutzt, um mit Lesern zu kommunizieren. Im Fall von Quellcode ist der “Leser” die Maschine, so dass der Text keine Zweideutigkeiten oder Unstimmigkeiten enthalten darf — nicht die geringsten.
Und wie jeder Text, der ein Thema eingehend behandelt, muss auch der Quellcode bei der Entwicklung komplexer Anwendungen gut strukturiert und logisch aufgebaut sein. Sehr einfache Programme und didaktische Beispiele umfassen wenige Zeilen einer einzigen Textdatei, die den gesamten Quellcode des Programms enthält. Komplexere Programme können in Tausende von Dateien mit jeweils Tausenden von Zeilen aufgeteilt sein.
Der Quellcode professioneller Anwendungen sollte in verschiedenen Verzeichnissen organisiert werden, die jeweils einem bestimmten Zweck zugeordnet sind. Ein Chat-Programm kann zum Beispiel in zwei Verzeichnissen organisiert werden: eines enthält die Codedateien, die das Senden und Empfangen von Nachrichten über das Netzwerk abwickeln, und ein anderes Verzeichnis die Dateien, die die Schnittstelle aufbauen und auf Benutzeraktionen reagieren. Tatsächlich sind viele Verzeichnisse und Unterverzeichnisse mit Quellcodedateien üblich, die ganz bestimmten Aufgaben innerhalb der Anwendung zugeordnet sind.
Quellcode besteht nicht immer nur aus eigenen Dateien, und nicht alles ist in einer einzigen Sprache geschrieben. In Webanwendungen kann ein HTML-Dokument beispielsweise JavaScript-Code einbetten, um das Dokument um zusätzliche Funktionen zu ergänzen.
Code-Editoren und IDE
Die Vielfalt an Möglichkeiten, Quellcode zu schreiben, wirkt schnell einschüchternd. Daher greifen viele Entwickler auf Tools zurück, die das Schreiben und Testen des Programms unterstützen.
Die Quellcodedatei ist eine einfache Textdatei und als solche lässt sie sich mit jedem noch so einfachen Texteditor bearbeiten. Zur einfacheren Unterscheidung zwischen Quellcode und einfachem Text hat jede Sprache eine selbsterklärende Dateinamenerweiterung: .c
für die Sprache C, .py
für Python, .js
für JavaScript usw. Allzweck-Editoren verstehen den Quellcode beliebter Sprachen oft gut genug, um Kursivschrift, Farben und Einrückungen hinzuzufügen und den Code verständlich zu machen.
Nicht jeder Entwickler entscheidet sich für die Bearbeitung des Quellcodes in einem Allzweck-Editor. Eine integrierte Entwicklungsumgebung (Integrated Development Environment, IDE) bietet einen Texteditor in Verbindung mit Werkzeugen, die syntaktische Fehler und offensichtliche Inkonsistenzen vermeiden helfen. Diese Umgebungen sind weniger erfahrenen Programmierern zu empfehlen, aber auch erfahrene Programmierer nutzen sie.
Beliebte IDEs wie Visual Studio, Eclipse und Xcode verfolgen auf intelligente Weise, was der Programmierer eingibt, und schlagen daraufhin mögliche Ergänzungen vor (Autocompletion) und überprüfen den Code in Echtzeit. IDEs bieten sogar automatisches Debugging und Testen an, um Probleme bei jeder Änderung des Quellcodes zu erkennen.
Erfahrenere Programmierer entscheiden sich häufig für weniger intuitive Editoren wie Vim, die mehr Flexibilität bieten und nicht die Installation zusätzlicher Pakete erfordern. Solche Programmierer nutzen externe, eigenständige Werkzeuge, um die Funktionen zu ergänzen, die eine IDE bereits mitbringt.
Code warten
Ob Sie auf eine IDE oder eigenständige Tools setzen — wichtig ist irgendeine Art von Versionskontrollsystem (VCS). Quellcode wird ständig weiterentwickelt, weil unvorhergesehene Fehler behoben und Verbesserungen eingepflegt werden müssen. Eine unvermeidliche Folge dieser Entwicklung ist, dass Korrekturen und Erweiterungen andere Teile der Anwendung mit einer großen Codebasis beeinträchtigen können. Versionskontrollwerkzeuge wie Git, Subversion und Mercurial zeichnen alle am Code vorgenommenen Änderungen auf und geben Aufschluss darüber, wer diese vorgenommen hat, so dass man eine unerwünschte Änderung zurückverfolgen und eventuell zurücknehmen kann.
Außerdem ermöglichen Versionskontrollwerkzeuge jedem Entwickler im Team, an einer Kopie der Quellcodedateien zu arbeiten, ohne die Arbeit der anderen Programmierer zu beeinträchtigen. Sobald die neuen Versionen des Quellcodes fertig und getestet sind, können andere Teammitglieder die Korrekturen oder Verbesserungen, die an einer Kopie vorgenommen wurden, übernehmen.
Git, das derzeit beliebteste Versionskontrollsystem, erlaubt es, dass viele unabhängige Kopien eines Repositorys von verschiedenen Personen verwaltet werden, die ihre Änderungen nach Belieben austauschen. Unabhängig davon, ob ein dezentrales oder ein zentrales Versionskontrollsystem im Einsatz ist, pflegen die meisten Teams ein einziges vertrauenswürdiges Repository, auf dessen Quellcode und Ressourcen sie sich verlassen. Mehrere Online-Dienste bieten Speicherplatz für Quellcode-Repositories an. Die bekanntesten sind GitHub und GitLab, aber auch das GNU-Projekt Savannah sei erwähnt.
Programmiersprachen
Es gibt eine Vielzahl von Programmiersprachen — und immer kommen neue hinzu. Jede Programmiersprache hat ihre eigenen Regeln und empfiehlt sich für bestimmte Zwecke. Obwohl die Sprachen oberflächliche Unterschiede in der Syntax und bei den Schlüsselwörtern aufweisen, unterscheiden sie sich vor allem in ihren zugrundeliegenden konzeptionellen Ansätzen, die als Paradigmen bezeichnet werden.
Paradigmen
Paradigmen sind die Prämissen, auf denen eine Programmiersprache basiert, insbesondere in Bezug auf die Struktur des Quellcodes.
Entwickler gehen vom Sprachparadigma aus, um die Aufgaben zu formulieren, die die Maschine ausführen soll. Die Aufgaben werden wiederum mit den von der Sprache angebotenen Wörtern und syntaktischen Konstruktionen symbolisch ausgedrückt.
Eine Programmiersprache ist prozedural, wenn die Anweisungen im Quellcode nacheinander ausgeführt werden — wie ein Drehbuch. Ist der Quellcode in Funktionen oder Unterprogramme unterteilt, sorgt eine Hauptroutine dafür, dass die Funktionen nacheinander aufgerufen werden.
Der folgende Code ist ein Beispiel für eine prozedurale Sprache. Er ist in C geschrieben und definiert Variablen zur Darstellung der Kante, der Seitenfläche und des Volumens geometrischer Formen. Der Wert der Variable side
wird in der Funktion main()
zugewiesen, die bei der Ausführung des Programms aufgerufen wird. Die Variablen area
und volume
werden in den Unterprogrammen square()
und cube()
berechnet, die der Hauptfunktion vorausgehen:
#include <stdio.h>
float side;
float area;
float volume;
void square(){ area = side * side; }
void cube(){ volume = area * side; }
int main(){
side = 2;
square();
cube();
printf("Volume: %f\n", volume);
return 0;
}
Die Reihenfolge der in main()
definierten Aktionen bestimmt die Abfolge der Programmzustände, die durch den Wert der Variablen side
, area
und volume
gekennzeichnet sind. Das Beispiel endet, nachdem der Wert von volume
mit der Anweisung printf
angezeigt wurde.
Das Paradigma der objektorientierten Programmierung (OOP) hat demgegenüber als Hauptmerkmal die Aufteilung des Programmzustands in unabhängige Unterzustände. Diese Unterzustände und die zugehörigen Operationen sind die Objekte — so genannt, weil sie innerhalb des Programms mehr oder weniger unabhängig existieren und bestimmte Aufgaben erfüllen.
Unterschiedliche Paradigmen schränken nicht unbedingt die Art der Aufgaben ein, die ein Programm ausführen kann. Der Code aus dem vorangegangenen Beispiel lässt sich gemäß dem OOP-Paradigma in der Sprache C++ wie folgt schreiben:
#include <iostream>
class Cube {
float side;
public:
Cube(float s){ side = s; }
float volume() { return side * side * side; }
};
int main(){
float side = 2;
Cube cube(side);
std::cout << "Volume: " << cube.volume() << std::endl;
return 0;
}
Die Funktion main()
gibt es immer noch, aber auch ein neues Wort, class
, das die Definition eines Objekts einleitet. Die definierte Klasse namens Cube
enthält eigene Variablen und Subroutinen. In der OOP werden eine Variable auch als Attribut und ein Unterprogramm als Methode bezeichnet.
Es geht über das Thema dieser Lektion hinaus, den gesamten C++-Code des Beispiels zu erklären. Wichtig für uns ist hier, dass Cube
das Attribut side
und zwei Methoden enthält. Die Methode volume()
berechnet das Volumen des Würfels.
Sie können mehrere unabhängige Objekte aus derselben Klasse erstellen und Klassen aus anderen Klassen zusammensetzen.
Denken Sie daran, dass dieselben Funktionen auch anders geschrieben werden können und dass die Beispiele in dieser Lektion stark vereinfacht sind. C und C++ haben sehr viel ausgefeiltere Funktionen, die deutlich komplexere und praktischere Konstruktionen erlauben.
Die meisten Programmiersprachen schreiben nicht strikt ein Paradigma vor, sondern erlauben es den Programmierern, verschiedene Aspekte des einen oder anderen Paradigmas zu wählen. JavaScript zum Beispiel enthält Elemente verschiedener Paradigmen. Sie können das gesamte Programm in Funktionen zerlegen, die keinen Zustand miteinander teilen:
function cube(side){
return side*side*side;
}
console.log("Volume: " + cube(2));
Obwohl dieses Beispiel der prozeduralen Programmierung ähnelt, ist zu beachten, dass die Funktion eine Kopie aller für ihre Ausführung notwendigen Informationen erhält und immer dasselbe Ergebnis für denselben Parameter liefert, unabhängig von Änderungen, die außerhalb des Funktionsbereichs stattfinden. Dieses Paradigma, das als funktional bezeichnet wird, ist stark vom mathematischen Formalismus beeinflusst, bei dem jede Operation autark ist.
Ein anderes Paradigma umfasst deklarative Sprachen, die die Zustände beschreiben, in denen sich das System befinden soll. Eine deklarative Sprache findet heraus, wie man die angegebenen Zustände erreicht. SQL, die universelle Sprache zur Abfrage von Datenbanken, wird manchmal als deklarative Sprache bezeichnet, obwohl sie in Wirklichkeit eine einzigartige Nische im Pantheon der Programmierung einnimmt.
Es gibt kein universelles Paradigma, das sich auf jeden Kontext übertragen lässt. Die Wahl der Sprache kann auch dadurch eingeschränkt sein, welche Sprachen die Plattform oder die Ausführungsumgebung, in der das Programm verwendet wird, unterstützt.
Eine Webanwendung, die im Browser laufen soll, muss beispielsweise in JavaScript geschrieben werden, einer Sprache, die alle Browser unterstützen. (Einige andere Sprachen sind möglich, da sie Konverter für die Erstellung von JavaScript bereitstellen.) Für den Webbrowser — manchmal auch als Clientseite oder Frontend der Webanwendung bezeichnet — muss der Entwickler also den in JavaScript zulässigen Paradigmen folgen. Die Serverseite oder das Backend der Anwendung, das die Anfragen des Browsers bearbeitet, wird normalerweise in einer anderen Sprache programmiert — PHP ist hier am beliebtesten.
Unabhängig vom Paradigma verfügt jede Sprache über vorgefertigte Bibliotheken (Libraries) von Funktionen, die in den Code integriert werden können. Mathematische Funktionen — wie die im Beispielcode dargestellten — müssen Sie nicht von Grund auf neu implementieren, da die Sprache die Funktion bereits zur Verfügung stellt. JavaScript zum Beispiel bietet das Math
-Objekt mit den gängigsten mathematischen Operationen.
Speziellere Funktionen sind in der Regel vom Anbieter der Sprache oder von Drittanbietern erhältlich. Diese zusätzlichen Ressourcenbibliotheken können in Form von Quellcode vorliegen, d.h. in zusätzlichen Dateien, die in die Datei eingebunden werden, in der sie gebraucht werden. In JavaScript erfolgt die Einbettung mit import from
:
import { OrbitControls } from 'modules/OrbitControls.js';
Diese Art des Imports, bei der die eingebettete Ressource auch eine Quellcodedatei ist, wird meist in sogenannten interpretierten Sprachen verwendet. Kompilierte Sprachen erlauben unter anderem die Einbindung vorkompilierter Funktionen in Maschinensprache, also kompilierte Bibliotheken. Im nächsten Abschnitt geht es um die Unterschiede zwischen diesen Sprachentypen.
Compiler und Interpreter
Wie wir bereits wissen, ist der Quellcode eine symbolische Darstellung eines Programms, das in Maschinensprache übersetzt werden muss, um ausgeführt werden zu können.
Grob gesagt gibt es zwei Möglichkeiten der Übersetzung: die Konvertierung des Quellcodes im Voraus für eine spätere Ausführung oder die Konvertierung des Codes zum Zeitpunkt seiner Ausführung. Sprachen des ersten Typs werden als kompilierte Sprachen und Sprachen des zweiten Typs als interpretierte Sprachen bezeichnet. Einige interpretierte Sprachen bieten die Kompilierung vorab als Option an, so dass das Programm schneller startet.
Bei kompilierten Sprachen gibt es eine klare Unterscheidung zwischen dem Quellcode des Programms und dem Programm selbst, das vom Computer ausgeführt wird. Sobald das Programm kompiliert ist, funktioniert es in der Regel nur auf dem Betriebssystem und der Plattform, für die es kompiliert wurde.
Bei einer interpretierten Sprache wird der Quellcode selbst als das Programm behandelt, und der Prozess der Umwandlung in Maschinensprache ist für den Programmierer transparent. Bei einer interpretierten Sprache bezeichnet man den Quellcode üblicherweise als Skript. Der Interpreter übersetzt das Skript in die Maschinensprache für das System, auf dem es läuft.
Kompilierung und Compiler
Die Programmiersprache C ist eines der bekanntesten Beispiele für eine kompilierte Sprache. Die größten Stärken der Sprache C sind ihre Flexibilität und Leistungsfähigkeit. Sowohl Hochleistungssupercomputer als auch Mikrocontroller in Haushaltsgeräten können in der Sprache C programmiert werden. Weitere Beispiele für beliebte kompilierte Sprachen sind C++ und C# (“C sharp”). Wie ihre Namen vermuten lassen, sind diese Sprachen von C inspiriert, enthalten aber Funktionen, die das objektorientierte Paradigma unterstützen.
Dasselbe in C oder C++ geschriebene Programm kann für verschiedene Plattformen kompiliert werden, wobei der Quellcode wenig oder gar nicht geändert werden muss. Es ist der Compiler, der die Zielplattform des Programms bestimmt. Es gibt sowohl plattformspezifische als auch plattformübergreifende Compiler wie GCC (GNU Compiler Collection), die Binärprogramme für viele verschiedene Architekturen erzeugen können.
Note
|
Es gibt auch Tools, die den Kompilierungsprozess automatisieren. Statt den Compiler direkt aufzurufen, erstellen Sie eine Datei, die die verschiedenen Kompilierungsschritte angibt, die automatisch ausgeführt werden. Das traditionelle Werkzeug für diesen Zweck ist |
Der Kompilierungsprozess erzeugt nicht immer ein Binärprogramm in Maschinensprache. Es gibt kompilierte Sprachen, die ein Programm im sogenannten Bytecode erzeugen. Wie ein Skript ist auch Bytecode nicht in einer plattformspezifischen Sprache verfasst und benötigt daher ein Interpreterprogramm, das ihn in Maschinensprache übersetzt. In diesem Fall nennt man das Interpreterprogramm einfach Laufzeit.
Die Sprache Java verfolgt diesen Ansatz, so dass kompilierte Programme, die in Java geschrieben sind, auf verschiedenen Betriebssystemen verwendet werden können. Trotz des Namens ist Java nicht mit JavaScript verwandt.
Bytecode ist der Maschinensprache näher als der Quellcode, so dass seine Ausführung in der Regel vergleichsweise schneller ist. Da bei der Ausführung von Bytecode noch ein Konvertierungsprozess stattfindet, ist es schwierig, die gleiche Leistung wie bei einem entsprechenden in Maschinensprache kompilierten Programm zu erzielen.
Interpretation and Interpreter
In interpretierten Sprachen wie JavaScript, Python und PHP muss das Programm nicht vorkompiliert werden, was Entwicklung und Änderung des Programms erleichtert. Statt es zu kompilieren, wird das Skript von einem anderen Programm, dem Interpreter, ausgeführt. Üblicherweise heißt der Interpreter einer Sprache wie die Sprache selbst. Der Interpreter eines Python-Skripts ist zum Beispiel ein Programm namens python
. Der JavaScript-Interpreter ist meist der Webbrowser, aber das Programm node
kann Skripte auch außerhalb eines Browsers ausführen. Da ein interpretiertes Programm bei jeder Ausführung in binäre Anweisungen umgewandelt wird, ist es tendenziell langsamer als ein entsprechendes kompiliertes Programm.
Es spricht nichts dagegen, dass eine Anwendung aus Komponenten in verschiedenen Sprachen besteht. Falls erforderlich kommunizieren diese Komponenten über eine wechselseitig verstandene Programmierschnittstelle, ein Application Programming Interface (API).
Die Sprache Python verfügt beispielsweise über sehr ausgefeilte Fähigkeiten zur Datengewinnung und Datentabellierung. Der Entwickler wählt Python, um die Teile des Programms zu schreiben, die sich mit diesen Aspekten befassen, und eine andere Sprache, wie z.B. C++, um die aufwendigere numerische Verarbeitung durchzuführen. Diese Strategie ist auch dann möglich, wenn es keine API für eine direkte Kommunikation zwischen den beiden Komponenten gibt. In Python geschriebener Code kann beispielsweise eine Datei in einem Format erzeugen, die ein in C++ geschriebenes Programm nutzen kann.
Obwohl sich fast jedes Programm in jeder Sprache schreiben lässt, sollten Sie diejenige wählen, die dem Zweck der Anwendung am besten entspricht. Auf diese Weise profitieren Sie von der Wiederverwendung bereits getesteter und gut dokumentierter Komponenten.
Geführte Übungen
-
Welche Art von Programm können Sie zur Bearbeitung von Quellcode verwenden?
-
Welche Art von Werkzeug hilft bei der Integration der Arbeit verschiedener Entwickler in dieselbe Codebasis?
Offene Übungen
-
Angenommen Sie wollen ein 3D-Spiel schreiben, das im Browser gespielt werden soll. Webanwendungen und Spiele werden in JavaScript programmiert. Obwohl es möglich ist, alle Grafikfunktionen von Grund auf neu zu schreiben, ist es produktiver, eine fertige Bibliothek für diesen Zweck zu verwenden. Welche Bibliotheken von Drittanbietern bieten Möglichkeiten für 3D-Animationen in JavaScript?
-
Welche anderen Sprachen neben PHP bieten sich auf der Serverseite einer Webanwendung an?
Zusammenfassung
Diese Lektion behandelt die wichtigsten Konzepte der Softwareentwicklung. Der Entwickler muss die wichtigsten Programmiersprachen und das passende Anwendungsszenario für jede Sprache kennen. Diese Lektion umreißt die folgenden Konzepte und Verfahren:
-
Was Quellcode ist.
-
Quellcode-Editoren und verwandte Werkzeuge.
-
Prozedurale, objektorientierte, funktionale und deklarative Programmierparadigmen.
-
Merkmale kompilierter und interpretierter Sprachen.
Lösungen zu den geführten Übungen
-
Welche Art von Programm können Sie zur Bearbeitung von Quellcode verwenden?
Grundsätzlich jedes Programm, das einfachen Text bearbeiten kann.
-
Welche Art von Werkzeug hilft bei der Integration der Arbeit verschiedener Entwickler in dieselbe Codebasis?
Ein Quellcode- oder Versionskontrollsystem, wie z.B. Git.
Lösungen zu den offenen Übungen
-
Angenommen Sie wollen ein 3D-Spiel schreiben, das im Browser gespielt werden soll. Webanwendungen und Spiele werden in JavaScript programmiert. Obwohl es möglich ist, alle Grafikfunktionen von Grund auf neu zu schreiben, ist es produktiver, eine fertige Bibliothek für diesen Zweck zu verwenden. Welche Bibliotheken von Drittanbietern bieten Möglichkeiten für 3D-Animationen in JavaScript?
Es gibt zahlreiche Optionen für 3D-Grafikbibliotheken für JavaScript, z.B. threejs und BabylonJS.
-
Welche anderen Sprachen neben PHP bieten sich auf der Serverseite einer Webanwendung an?
Jede Sprache, die von der auf dem Server-Host verwendeten HTTP-Server-Anwendung unterstützt wird. Einige Beispiele sind Python, Ruby, Perl und JavaScript selbst.