Gleichnis über Programmierer und Programmierer

Vor langer Zeit lebten in einer fernen Galaxie intelligente Säugetiere auf einem Provinzplaneten, der vor kurzem das Zeitalter der Informationstechnologie begann. In diesem Jahrhundert mussten viele Programme in verschiedenen Sprachen für verschiedene Softwareplattformen schreiben. Und jeder Nachkomme eines Affen von diesem Planeten, der mindestens ein paar Zeilen Code geschrieben hat, die einen dummen Computer dazu gebracht haben, vernünftige (aus der Sicht des Autors) Handlungen auszuführen, betrachtete sich bereits als ein aufgeklärter Weiser, der DAO der Informationstechnologien verstand und nichts weiter als ein Jedi- Programmierer genannt wurde.

Bild

Heute, liebe Liebhaber der Geschichte des Universums, werden wir versuchen herauszufinden, was der fundamentale Fehler dieser Nachkommen der Affen istMenschen, und was ist der Unterschied zwischen Programmierern und Nicht-Programmierern, der Einfachheit halber werden wir sie Codierer nennen.

Die überwiegende Mehrheit der Menschen glaubt, dass es überhaupt nicht darauf ankommt, wie das Ergebnis erzielt wurde, wenn die Aufgabe anscheinend gelöst wurde. Viele beginnen damit, jede Aufgabe der Softwareentwicklung (und nicht nur) zu lösen, denken nicht über die grundlegenden Prinzipien des Designs nach, sondern kopieren einfach die Arbeitsblöcke ihrer Vorgänger. Die mit einer Anleitung zur Syntax der Sprache und der Internet-Suchmaschine ausgestatteten Programmierer schaffen ihre "Mega-Meisterwerke der Programmierung". Indem die Entwickler das Programm mithilfe des Debuggers schnell zwingen, logische Verhaltensaktionen auszuführen, geben sie einen Auftrag ab. Der Kunde ist zufrieden, der Geldgeber - alle sind auf den ersten Blick glücklich.

Dann passiert in der Regel folgendes: Es vergeht sehr wenig Zeit und der Kunde möchte etwas in seinem Programm ändern, und in der Regel viel. Der Kunde kontaktiert entweder den Autor des Programms oder einen anderen Programmierer und bestellt die Änderungen. Der Auftragnehmer sieht sich den Code an und versteht nicht, wie dieser Stapel von Ergebnissen aus der Suchmaschine resultiert, und beginnt, den Code schmerzhaft umzuschreiben, wobei die Fristen selbst für "elementare Änderungen" überschritten werden. Bei der zweiten oder etwas späteren Überarbeitung wird der Anwendungscode so schwer verständlich, unhandlich und fehlerhaft, dass es wirklich einfacher wird, ihn von Grund auf neu zu schreiben, nachdem der Kunde ein vollständiges Budget für eine Neuentwicklung angefordert hat. Und hier spürt der Kunde endlich seinen epischen Fehler bei der Auswahl der Künstler, da er für die zweite Anwendungsentwicklung bezahlen muss,

Zusammen mit dem Bewusstsein für diese Situation sind wir den grundlegenden Unterschieden zwischen einem Spezialisten und einem Nicht-Spezialisten auf dem Gebiet der Softwareentwicklung näher gekommen. Im Gegensatz zu Programmierern verstehen Programmierer die grundlegenden Prinzipien ihres Fachs, wodurch sie einfachen und verständlichen Code schreiben können, der die Technologie in Bezug auf die aktuelle Aufgabe angemessen einsetzt. Dieser einfache und verständliche Anwendungscode ermöglicht es dem Kunden, Geld zu sparen, da ein solcher Code sowohl für einen anderen Programmierer als auch für einen beliebigen Codierer leicht zu lesen und zu ändern ist. Eine Anwendung mit einer guten Architektur und einem hochwertigen Code kann über einen beträchtlichen Zeitraum erfolgreich betrieben und weiterentwickelt werden, wobei die Kosten für Änderungen und Support für den Kunden minimal sind.

Und dann murmelten die empörten Programmierer: „Wir kennen all diese Grundprinzipien! Sie sind alle nutzlos und dumm! “ Und das Universum antwortete ihnen: "Vielleicht ist das so, aber vielleicht verstehen Sie sie nicht, und deshalb wissen Sie nicht, wie Sie sie anwenden sollen."

Nehmen wir einfache Codebeispiele mit der auf diesem provinziellen Planeten beliebten PHP-Webentwicklungssprache. Die Sprache selbst ist recht gut für den beabsichtigten Gebrauch, obwohl die Meinungen zu diesem Thema normalerweise unterschiedlich sind.

Teil 1: Code-Einfachheit


Beispiel 1:

if ($u->g) $u->reg($u->email, $u->nm);

Nur eine Codezeile, die von einem Encoder geschrieben wurde, aber was er tut, ist überhaupt nicht offensichtlich und erfordert zumindest Kommentare.
Nun die gleiche Codezeile, die der Programmierer geschrieben hat:

$user->email = $email;
$user->name = $name;
if ($user->isGuest) $user->register();

Ich denke, alle Fragen sind verschwunden und Kommentare sind nicht mehr nötig. Und Variablen und Funktionen werden nur richtig und eindeutig benannt.

Beispiel 2:

//…
$sql = 'SELECT * FROM usr LIMIT 10';
//…
/** view */
if ($n<10) echo ...;

Es scheint, dass der Code mehr oder weniger klar ist, obwohl magische Konstanten wie 10 alarmierend sind. Außerdem befindet sich der Code in verschiedenen Dateien und wird häufig wiederholt.
Wie würde ein Programmierer es schreiben? Ja so etwas:

class User
{
	const MAX_VIEW_USERS_ON_PAGE = 10;
	... ... ...
	$sqlQuery = 'SELECT * FROM `User` LIMIT '.User::MAX_VIEW_USERS_ON_PAGE;
	…
/** view */
if (count($users) < User::MAX_VIEW_USERS_ON_PAGE) echo ...;

Das Lesen des Codes ist jetzt viel bequemer und die Anzahl der Benutzer, die auf allen Seiten (10) angezeigt werden, ist jetzt leicht zu ändern, da sie über eine benannte Konstante verwendet werden, ähnlich wie der Name der Tabelle in der Datenbank.

Beispiel 3:

if ((isset($user->online) || (time() - $user->lastVisit < User::LOGOUT_TIMEOUT)) && Post::getNumOfPostsForUser($user->id) > Post::ACTIVE_USER_MIN_POSTS) 
	$Raiting::addBonus($user->id, Rating::BONUS_RATING_POINTS);

Es scheint, dass die Variablen mit Methoden und Konstanten gut benannt sind, aber es ist immer noch irgendwie zu schwer zu lesen.

$userOnline = (isset($user->online) || (time() - $user->lastVisit < User::LOGOUT_TIMEOUT));
$userIsActivePoster = Post::getNumOfPostsForUser($user->id) > Post::ACTIVE_USER_MIN_POSTS;
if ($userOnline && $userIsActivePoster) $Raiting::addBonus($user->id, Rating::BONUS_RATING_POINTS);

Nun, jetzt ist die Bedingung einfach und klar wie ein Tag geworden und es wurden nur zusätzliche logische Variablen eingeführt, um den Code zu vereinfachen.

Beispiel 4:

Der Code wird an mehreren Stellen wiederholt:

$hdr = explode(' ',trim($header));
$hdr[0] = ''.$hdr[0].'';
$header = implode(' ',$hdr);

Wie kann man die Situation verbessern?

class StringHelper
{
	/**
	 * Return text header with CSS
	 * @param string $header
	 * @return string
	 */ 
	static public function getCSSDecoratedHeader($header)
	{
		$hdr = explode(' ',trim($header));
		$hdr[0] = ''.$hdr[0].'';
		return implode(' ',$hdr);
	}
...
$header = StringHelper::getCSSDecoratedHeader($header);

Jetzt müssen wir nur noch unsere Hilfsfunktion aufrufen, um an allen Stellen der Anwendung das gleiche Ergebnis zu erzielen, und natürlich ist der Code einfacher geworden und seine Anzahl hat abgenommen.

Teil 2: Objekte und Klassen


Codierer sind ratlos: "Warum brauchen wir OOP, wenn alles mit Funktionen oder sogar nur mit Operatoren geschrieben werden kann?"
Das Universum antwortete: "Ja, dann egal - um großen oder komplexen Code einfacher, verständlicher und gut strukturierter zu machen."
Die Kapselung ist die wichtigste Eigenschaft beim Verwalten der Codekomplexität. Sie verbirgt unsere Daten und Algorithmen logisch in Methoden für private Klassen. Wir vereinfachen die gesamte Logik der Arbeit mit einer Klasse erheblich und vereinfachen auch alle zukünftigen Operationen, um das Verhalten einer Klasse zu ändern.
Vererbung ist eine großartige Möglichkeit, um in ähnlichen Klassen keinen doppelten Code zu schreiben und alle untergeordneten Klassen zu vereinfachen.
Polymorphismus - Wir ändern leicht die Logik des Verhaltens der abgeleiteten Klasse, indem wir nur eine Methode ändern.

Beispiel 5:

Der Encoder hat gelernt, Daten aus Datenbanktabellen zu extrahieren und schreibt nun in allen Dateien:

$sqlQuery = "SELECT * FROM User WHERE id=:id";
$connection = $this->getDbConnection();
$command = $connection->createCommand($sqlQuery);
$user = $command->execute(array(':id'=>$id));
echo $user['name'];

Dank OOP und einer speziell vorbereiteten Benutzerklasse können Sie jedoch viel kürzer und verständlicher schreiben:

$user = User::model()->findByPk($id);
echo $user->name;


Beispiel 6:

Der Kodierer hat mehrere Klassen für die von seiner Website unterstützten Zahlungssysteme geschrieben, von denen jede über mehrere völlig identische Methoden und Felder verfügt.

Der Programmierer würde eine Basisklasse eines Zahlungssystems erstellen, die gemeinsame Felder und Methoden für alle Systeme enthält, und bestimmte Klassen für jedes der Zahlungssysteme würden von der Basis erben, was die Menge an Code in diesen Klassen und das Projekt insgesamt erheblich reduzieren würde.

Teil 3: Modularität


Encoder sind ratlos: „Warum eine Menge Dateien in einem Programm und sogar in verschiedenen Ordnern erstellen? Sie können ein oder zwei Dateien erstellen, und es werden alle Konstanten, Klassen und Funktionen unseres Projekts sowie alle Variablen global sein. “Das

Universum antwortete:„ Ja ... aber Sie selbst und analysieren im Grunde genommen Ihre Kilometerdateien. “

Beispiel 7

Der Codierer lernte das Schreiben im MVC-Framework, war jedoch nicht mit der modularen Struktur vertraut und schreibt den gesamten Code im Modell:

class Article extends CModel
{
	... ...
	public static function getDecoratedHeader($header)
	{
		$words = explode(' ', $header);
		$words[0] = '' . $words[0] . '';
		return implode(' ', $words);
	}
	... ...
}

Dem Programmierer ist bekannt, dass das Modell ausschließlich Code für die Arbeit mit den Daten dieses Modells enthalten muss, und mit einer solchen Methode wird StringHelper :: getDecoratedHeader () in den Helfer eingefügt. Dementsprechend hat jede Funktion der Anwendung ihren eigenen spezifischen Zweck, der durch das Modul bestimmt wird, in dem sich ihre Implementierung befindet (Modell, Steuerung, Komponente, Widget usw.), und Programmierer werden viel über das Wesentliche der von anderen Programmierern geschriebenen Methoden verstehen, wenn sie nur sehen, welches Modul sich befindet er gehört.

Teil 4: Muster


Der Codierer hörte das Wort Muster und stufte es sofort als missbräuchlich ein, obwohl das Universum ihm anzeigte, dass Muster äußerst erfolgreiche Lösungen, typische Softwareentwicklungsaufgaben und dieses Wissen die Arbeit des Codierers sowie die Kommunikation mit Programmierern, die die Muster kennen, erheblich vereinfachen würden.

Beispiel 8:

Der Encoder verwendet eine externe Mailer-Komponente in seiner Anwendung und schreibt Aufrufe an seine send () -Methode in die Systemmodule.
Mailer :: send ($ subject, $ message);
Das Problem ist jedoch, dass in der neuen Version dieser Komponente, die eine Reihe von Fehlern behebt und die Leistung verbessert, die send () -Methode entfernt und durch die post () -Methode mit anderen erforderlichen Parametern ersetzt wurde. Der Encoder muss den gesamten Anwendungscode schaufeln und alle Komponentenaufrufe korrigieren. Wenn er eines der einfachsten Muster verwendet hat, lautet die Zugriffsmethode:

class MailerWrap 
{
	public function send($params)
	{
		return Mailer::send($params);
	}
}

Es würde für den Programmierer ausreichen, nur eine Methode mit einem Aufruf der Mailer-Komponente in der Wrapper-Klasse zu ändern, um die neue Version voll auszunutzen.

Teil 5: Frameworks


Der Programmierer ist zu faul, um das Framework zu lernen, er selbst kann alle erforderlichen Module und Komponenten perfekt schreiben, was zudem schneller funktionieren wird.

Beispiel 9:

Das Projekt wird ohne die Verwendung bekannter Rahmenbedingungen und Vereinbarungen für das Entwerfen und Schreiben von Code entwickelt. Ein neuer Entwickler ist zu dem Projekt gekommen, er versucht, die Dinge auf den neuesten Stand zu bringen, Wochen und Monate vergehen, aber er orientiert sich immer noch schlecht am heterogenen Anwendungscode, dessen Dokumentation noch niemand geschrieben hat. Er verbringt viel Zeit damit, Quellcodes auszuwählen, um zu verstehen, was passiert. Ein neuer Entwickler wird wegen "mangelnder Kompetenz" entlassen, ein neuer wird eingestellt und die Situation wird genau wiederholt. Programmierer würden das Framework für ein großes Projekt verwenden und die Codegenerierungskonventionen dieses Frameworks einhalten. Dies würde es ihnen ermöglichen, leicht neue Entwickler mit Kenntnissen dieses Frameworks einzustellen, während der Anpassungszeitraum für ein neues Teammitglied minimal wäre.

Teil 6: Optimierung


Der Programmierer hörte von Optimierung und benutzte sogar ein paar Tipps von der Suchmaschine in seinen Programmen, jedenfalls sagt er dies auch anderen.

Beispiel 10:

Der Programmierer hat ein Forum geschrieben, aber das Problem ist, dass nach ein paar Monaten aktiven Chatterns die Seiten der Site sehr langsam geöffnet wurden. Er vergrub sich in den Code und stellte mit Mühe fest, dass eine Abfrage der MySQL-Datenbank sehr lange dauerte. Der Encoder las Tipps von der Suchmaschine und beschloss, das gesamte Forum mithilfe der noSQL-Datenbank neu zu schreiben, da dies nur einen Monat dauert. In diesem Fall würde der Programmierer den Abfrageplan analysieren und in 3 Minuten ein paar Indizes zu den Tabellen hinzufügen.

Beispiel 11:

Der Encoder optimiert die Leistung seines Codes, der aus 8 Funktionen besteht, und optimiert diese nacheinander. Er verbrachte eine Woche damit, 5 Funktionen umzugestalten, aber der Leistungszuwachs betrug nur 10%. Der Codierer war von der Optimierung enttäuscht und warf dieses Ding, resigniert in die Bremsen der Anwendung. Der Programmierer würde die Ausführungszeit jeder der 8 Funktionen analysieren, wonach er beginnen würde, die am längsten laufende Funktion zu optimieren. Andere Funktionen, deren Ausführungszeit erheblich (um eine Größenordnung) kürzer ist als die Hauptfunktion, wurden überhaupt nicht optimiert.

Teil 7: Sicherheit


Ein Encoder hat nie wirklich an Codesicherheit gedacht. Warum? Niemand wird jemals seine Programme knacken ...

Beispiel 12:

Der Encoder hat viele Anfragen in der Anwendung, wobei er einfach die vom Benutzer übertragenen Daten (GET, POST, COOKIES, JSON, XML) direkt in die Anfrage einfügt:
$sqlQuery = 'SELECT `name`, `surname` FROM `User` WHERE `id`='.$_GET['id'];
$command->create($sqlQuery);
$result = $command->execute();
print_r($result);

Und was passiert, wenn der Benutzer die folgende Zeile "0 UNION SELECT` email`," password` FROM` User` LIMIT 10 "im id-Parameter übergibt? Wahrscheinlich wird es eine komplette ah-ah-ah geben!
Programmierer schreiben solche Anfragen etwa so:
$sqlQuery = 'SELECT * FROM `User` WHERE `id`=:id';
$command->create($sqlQuery);
$result = $command->execute(array(':id'=>$_GET['id']));
print_r($result);

Und Programmierer vergessen nie die Substitution von Werten in Funktionen wie eval () sowie das coole Wort "validation".

Fazit


Die Prinzipien des Aufbaus des Universums sind extrem einfach, wie das gesamte Universum, weshalb es so großartig ist. Wie in jedem Unternehmen ist es bei der Entwicklung von Software für eine langfristig nachhaltige Entwicklung vor allem wichtig, die Grundprinzipien zu verstehen und nicht die spezifischen Tools zu kennen, die kurzfristig nur ein oberflächliches Kompetenzniveau bieten. Alle oben genannten Grundprinzipien sind einfacher Natur und der Großteil der Programmierer kennt sie zumindest, aber nicht jeder versteht sie wirklich und verwendet sie in seiner Praxis.

Möge dieses große Wissen mit Ihnen sein, junger Padawan!

Jetzt auch beliebt: