Connect with us

Entwicklung & Code

Das Paradox der Softwarearchitektur | heise online


Seitdem wir Mitte der Neunziger-Jahre an dem ersten Buch der Pattern-Oriented-Software-Architecture-Serie gearbeitet haben, tauchte auf Konferenzen und in Fachgremien immer wieder die Diskussion auf, was Softwarearchitektur denn konkret beinhaltet. Vergleiche mit Gebäudearchitektur, Elektrotechnik-Schaltplänen oder Kunst schienen schon damals zu kurz gegriffen, obwohl die genannten Gewerke durchaus einige Gemeinsamkeiten mit Softwarearchitektur aufwiesen. Der folgende Artikel illustriert meine heutige Sicht.

Weiterlesen nach der Anzeige


Michael Stal

Michael Stal

Prof. Dr. Michael Stal arbeitet seit 1991 bei Siemens Technology. Seine Forschungsschwerpunkte umfassen Softwarearchitekturen für große komplexe Systeme (Verteilte Systeme, Cloud Computing, IIoT), Eingebettte Systeme und Künstliche Intelligenz.

Er berät Geschäftsbereiche in Softwarearchitekturfragen und ist für die Architekturausbildung der Senior-Software-Architekten bei Siemens verantwortlich.

Versammelt jemand zehn Softwarearchitekten in einem Raum und bittet sie, ihr Handwerk zu definieren, trägt diese Person wahrscheinlich elf verschiedene Antworten und Kopfschmerzen davon. Das liegt nicht daran, dass Architekten von Natur aus widersprüchlich wären, obwohl einige dies durchaus sind, sondern weil Softwarearchitektur eine eigentümliche Position im Pantheon menschlicher Bestrebungen einnimmt. Sie sitzt unbequem an der Kreuzung mehrerer Disziplinen, verweigert eine ordentliche Kategorisierung, verwendet antike Traditionen und erfindet gleichzeitig völlig neue Paradigmen.

Dazu folgende Überlegung: Als der Architekt Frank Lloyd Wright sein Haus Fallingwater entwarf, arbeitete er mit Materialien, die seit Jahrtausenden existierten. Stein, Wasser, Stahl, Beton. Diese Substanzen besaßen bekannte Eigenschaften, verstandene Verhaltensweisen und Jahrhunderte akkumulierter Weisheit über ihre Verwendung. Als Ada Lovelace den ersten Algorithmus schrieb, arbeitete sie mit nichts als reiner Abstraktion, mathematischer Notation auf Papier, die Operationen für eine Maschine beschrieb, die kaum existierte. Softwarearchitekten erben heute beide Traditionen, operieren jedoch in einem Reich, das weder Wright noch Lovelace wiedererkennen könnten.

Die Frage, was Softwarearchitektur wirklich ist, zählt mehr als bloßes philosophisches Nabelschauen vermuten ließe. Die Disziplin prägt immerhin die Praxis, die Lehre, die Bewertung und letztendlich den Bau der digitalen Infrastruktur, von der die moderne Zivilisation zunehmend abhängt.

Wenn Martin Fowler ein gut gestaltetes System beschreibt, klingt er manchmal eher wie ein Kunstkritiker, der ein Meisterwerk diskutiert, als wie ein Ingenieur. Er spricht von „Eleganz“, von „Klarheit“, von Lösungen, die sich „richtig“ anfühlen. Dies sind nicht die kalten, klinischen Begriffe reiner Ingenieurkunst. Sie tragen ästhetisches Gewicht, subjektives Urteil, einen Appell an etwas jenseits bloßer Funktionalität.

Weiterlesen nach der Anzeige

Und tatsächlich durchzieht Kunstfertigkeit die Softwarearchitektur auf mehreren Ebenen. Die Wahl zwischen Microservices und einem Monolithen ist selten eine rein mathematische Entscheidung. Zwei gleich versierte Architekten treffen für dasselbe Problem möglicherweise entgegengesetzte Entscheidungen und schaffen beide erfolgreiche Systeme. Der Unterschied liegt nicht in objektiver Korrektheit, sondern in Vision, im Geschmack, in einem intuitiven Gespür dafür, was sich für den Kontext angemessen anfühlt.

Großartige Softwarearchitektur besitzt eine Qualität, die ihre technischen Spezifikationen transzendiert. Wer das Design von Unix mit seiner Philosophie kleiner, komponierbarer Werkzeuge untersucht oder die klare Trennung der Belange in einer gut gestalteten hexagonalen Architektur beobachtet, erkennt eine unleugbare Schönheit darin. Der Code entwickelt sich zu einer Ausdrucksform, zu einer Methode, dem Chaos roher rechnerischer Möglichkeiten menschliche Bedeutung und Ordnung aufzuerlegen.

Die Architektin, die ein System für Millionen gleichzeitiger Nutzer entwerfen muss, steht vor einem unendlichen Lösungsraum. Sie könnte ereignisgesteuerte Architektur, Aktor-Modelle, reaktive Streams oder unzählige andere Muster wählen. Die Einschränkungen verengen die Optionen, aber selten auf eine einzige „korrekte“ Antwort. Was leitet ihre endgültige Wahl? Erfahrung, gewiss. Technisches Wissen, absolut. Aber auch Intuition, ästhetische Präferenz und eine kreative Vision davon, wie die Teile zusammenpassen sollten. Dies ist die Arbeit einer Künstlerin, die rohe Materialien zu etwas formt, das zuerst in der Vorstellung existiert, bevor es Realität annimmt.

Der kreative Prozess in der Softwarearchitektur spiegelt künstlerisches Bestreben auf eine weitere entscheidende Weise: die Bedeutung des Negativraums, dessen, was bewusst nicht gebaut wird. Ein Bildhauer enthüllt Form durch das Entfernen von Stein. Ein Architekt offenbart Klarheit durch Widerstand gegen die Versuchung, Komplexität hinzuzufügen. Die Zurückhaltung, ein System einfach zu halten, wenn jeder Stakeholder ein weiteres Feature fordert, der Mut, Code zu löschen, statt hinzuzufügen – all das erfordert künstlerische Sensibilität ebenso wie technische Fertigkeit.

Softwarearchitektur als reine Kunst zu bezeichnen, hieße jedoch, die rigorose wissenschaftliche Grundlage zu ignorieren, auf der sie ruht. Anders als ein Gemälde, das Physik und Logik im Dienste emotionaler Wahrheit verletzen kann, muss ein Softwaresystem unnachgiebigen mathematischen Gesetzen und physischen Einschränkungen gehorchen.

Wenn eine Architektin die erwartete Last auf einem verteilten System berechnet, wendet sie Warteschlangentheorie an, einen Zweig der Mathematik mit Wurzeln in frühen Telefonnetzwerken des zwanzigsten Jahrhunderts. Wenn sie über die Konsistenzgarantien einer Datenbank nachdenkt, befasst sie sich mit dem CAP-Theorem, einem formalen Beweis, der einschränkt, was in verteilter Datenverarbeitung möglich ist. Wenn sie die Zeitkomplexität eines Algorithmus analysiert, arbeitet sie innerhalb des Rahmens der Berechnungskomplexitätstheorie, einem Feld mit tiefen Verbindungen zu Logik und Mathematik.

Die wissenschaftliche Methode durchdringt die architektonische Praxis auf offensichtliche und subtile Weise. Eine Architektin bildet Hypothesen darüber, wie sich ein System unter Last verhalten sollte, entwirft Experimente in Form von Leistungstests, sammelt empirische Daten und verfeinert ihr Verständnis basierend auf Beobachtungen. Sie könnte Chaos Engineering nutzen, um bewusst Ausfälle zu injizieren und die Produktionsumgebung als Labor zu behandeln, in dem sie Theorien über Resilienz gegen die unnachgiebige Realität der physischen Welt testet.

Informatik liefert das theoretische Werkzeugset, das jede Softwarearchitektin beherrschen muss. Konzepte wie Zustandsautomaten, Graphentheorie, formale Verifikation und Berechnungskomplexität sind keine abstrakten akademischen Übungen. Sie bilden die Linse, durch die eine Architektin versteht, was möglich, was effizient und was beweisbar korrekt ist. Beim Entwurf eines Konsensalgorithmus für ein verteiltes System geht es nicht um kreativen Ausdruck, sondern um präzises logisches Denken, das sicherstellt, dass das System unter allen möglichen Ereignissequenzen seine Invarianten beibehält.

Die wissenschaftliche Natur der Softwarearchitektur offenbart sich am deutlichsten, wenn Dinge schiefgehen. Ein Systemausfall ist keine Frage ästhetischer Meinungsverschiedenheit. Er ist eine empirische Tatsache, die systematische Untersuchung verlangt. Die Architektin muss Hypothesen über Grundursachen bilden, Experimente entwerfen, um diese Hypothesen zu testen, und rigorose Denkweisen anwenden, um die zugrunde liegenden Mechanismen zu verstehen. Dies ist Wissenschaft in ihrer reinsten Form: Beobachtung, Hypothese, Experiment und die allmähliche Verfeinerung des Verständnisses durch Konfrontation mit der Realität.

Wäre Softwarearchitektur nur Kunst und Wissenschaft, könnte sie eine intellektuelle Übung bleiben, schön in der Theorie, aber getrennt von der chaotischen Realität des Baus tatsächlicher Systeme. Hier offenbart sich die Ingenieurperspektive als wesentlich. Ingenieurwesen handelt fundamental von Kompromissen, von der Lieferung funktionierender Lösungen innerhalb realer Einschränkungen von Zeit, Geld und menschlicher Fähigkeit.

Ein Ingenieur unterscheidet sich von einem reinen Wissenschaftler in der Akzeptanz, dass Perfektion weder möglich noch überhaupt wünschenswert ist. Wo ein Wissenschaftler die optimale Lösung suchen könnte, sucht ein Ingenieur die ausreichende Lösung, die sich morgen ausliefern lässt, statt der perfekten Lösung, die vielleicht niemals eintrifft. Dieser Pragmatismus steht im Zentrum architektonischer Praxis. Die Architektin muss ständig konkurrierende Belange ausbalancieren: Performance gegen Wartbarkeit, Konsistenz gegen Verfügbarkeit, Sicherheit gegen Benutzerfreundlichkeit, Innovation gegen Zuverlässigkeit.

Die ingenieurmäßige Realität technischer Schulden benötigt ebenfalls eine Betrachtung. Eine Architektin entwirft möglicherweise ein schönes, theoretisch solides System, aber wenn das Team es nicht verstehen, nicht warten oder nicht innerhalb des Geschäftszeitrahmens liefern kann, verwandelt sich jenes elegante Design in ein Hindernis statt in einen Vorteil. Gutes Engineering bedeutet, anzuerkennen, dass das System von realen Menschen mit unterschiedlichen Fähigkeiten gebaut, über Jahre von Personen gewartet, die bei seiner Entstehung nicht anwesend waren, und weiterentwickelt werden muss, um Anforderungen zu erfüllen, die zur Entwurfszeit nicht vollständig bekannt sein können.

Die Ingenieurdisziplin manifestiert sich auch in der Beziehung des Architekten zu Einschränkungen. Wo ein Künstler gegen Einschränkungen aufbegehren oder eine Wissenschaftlerin versuchen könnte, sie durch bessere Theorie zu eliminieren, arbeitet ein Ingenieur innerhalb von Einschränkungen und nutzt sie sogar. Begrenztes Budget erzwingt Einfachheit. Enge Zeitpläne ermutigen die Wiederverwendung bewährter Muster. Legacy-Systeme verlangen kreative Anpassung statt Greenfield-Idealismus. Diese Einschränkungen schmälern die Arbeit nicht, sondern formen sie, ähnlich wie die Eigenschaften von Stahl und Beton prägen, was ein Bauingenieur errichten kann.

Softwarearchitektur als Ingenieurwesen bedeutet, Praktiken wie Standardisierung, Dokumentation und wiederholbare Prozesse anzunehmen. Es bedeutet, Systeme zu schaffen, die Teams betreiben, die nicht an ihrem Design beteiligt waren. Es bedeutet, über Wartung, Überwachung, Bereitstellung und all die unscheinbaren, aber wesentlichen Belange nachzudenken, die ein schönes Design von einem funktionierenden Produkt trennen. Die Architektin muss Fehlermodi, Wiederherstellungsprozeduren, Backup-Strategien und Upgrade-Pfade berücksichtigen. Dies sind Ingenieursbelange, verwurzelt in der Realität, dass Systeme nicht in makelloser Isolation existieren, sondern in der chaotischen, fehleranfälligen realen Welt.

Vielleicht am faszinierendsten ist die Verbindung der Softwarearchitektur zu deutlich älteren Traditionen von Handwerk und Handwerkskunst. Bevor Wissenschaft oder Ingenieurwesen als formale Disziplinen existierten, bauten Menschen Kathedralen, Schiffe und Städte durch akkumuliertes Handwerkswissen, das der Meister an den Lehrling weitergegeben hat. Diese Übertragung impliziten Wissens, von Fertigkeiten, die gelernt, aber nicht vollständig artikuliert werden, bleibt zentral für die architektonische Praxis.

Wenn ein leitender Architekt das Design eines Juniors überprüft, widersetzt sich viel dem Feedback der Formalisierung. Der Senior könnte sagen, das Design „riecht falsch“ oder „fühlt sich spröde an“ oder „es fehlt an Kohäsion“. Dies sind keine wissenschaftlichen Begriffe mit präzisen Definitionen. Sie bilden die Sprache des Handwerks, beschreiben Intuitionen, die sich durch jahrelange Erfahrung entwickelt haben. Ein Meisterschreiner kann fühlen, wenn eine Verbindung nicht ganz richtig sitzt, bevor irgendeine Messung es beweist. Ein Meisterarchitekt kann spüren, wenn ein Design zu Problemen führen dürfte, lange bevor diese Probleme sich manifestieren.

Dieses Handwerkswissen erweitert sich durch Praxis und Mustererkennung. Eine Architektin, die zehn Systeme gebaut hat, trifft andere Entscheidungen als eine, die ein System zehnmal gebaut hat. Die Erfahrung zu sehen, wie Designs altern, zu beobachten, welche Teile von Systemen zu Wartungsalpträumen mutieren und welche durch Jahre der Evolution stabil bleiben, schafft ein intuitives Verständnis, das sich nicht auf Regeln oder Algorithmen reduzieren lässt.

Die Handwerkstradition betont auch die Bedeutung von Werkzeugen und deren richtiger Verwendung. Genauso wie ein Holzarbeiter verschiedene Sägen, Hobel und Meißel beherrschen muss, muss ein Softwarearchitekt Entwurfsmuster, architektonische Stile und Frameworks meistern. Doch Meisterschaft bedeutet, nicht nur zu wissen, wie diese Werkzeuge zu verwenden sind, sondern wann sie zu verwenden sind und zu entscheiden, wann nicht. Ein junger Architekt könnte das neueste architektonische Muster auf jedes Problem anwenden, während ein Meister weiß, dass manchmal der einfachste Ansatz der beste ist, wenngleich er unmodisch erscheint.

Das Lehrlingsmodell, obwohl weniger formal als in mittelalterlichen Gilden, besteht in der Softwareentwicklung durch Mentoring, Code-Review und Paarprogrammierung fort. Architektur lernt sich nicht primär aus Büchern, obwohl Bücher helfen, sondern durch die Arbeit neben erfahrenen Praktikern, durch Absorption ihrer Urteilskraft, ihrer Zurückhaltung, ihrer Denkweise über Probleme. Dieser implizite Wissenstransfer ist nach modernen Standards ineffizient, aber vielleicht unersetzlich für die Entwicklung der tiefen Intuition, die architektonische Meisterschaft charakterisiert.



Source link

Entwicklung & Code

Sicheres Linux: Amutable bringt „kryptografisch verifizierbare Integrität“


Ein Team von namhaften Linux-Entwicklern hat sich zum Ziel gesetzt, Linux sicherer zu machen und die Integrität von Linux-Systemen kryptografisch zu verifizieren. Das Projekt sattelt unter anderem auf „immutable Linux“ auf, also schreibgeschützten, unveränderlichen Kernsystemen. Der Name: Amutable. Die Firma hat ihren Sitz in Berlin.

Weiterlesen nach der Anzeige

Große Namen sind als Gründer involviert. Etwa Lennart Poettering, der systemd entwickelt und pflegt, oder Christian Brauner, der das VFS-Subsystem in Linux betreut, sowie Christ Kühl, ehemals Gründer von Kinvolk – die Flatcar Container Linux, ein immutable-Linux-System, entwickelt haben und von Microsoft eingekauft wurden.

Details liefert Amutable bislang nicht, deutet aber die Ziele an. Die Integrität des Systems soll kryptografisch prüfbar sein, das „System startet in einem verifizierten Status und bleibt im Zeitverlauf vertrauenswürdig“. Als Stichworte nennt die „Über“-Seite von Amutable die Integrität des Build-Prozesses, des Boot-Vorgangs und zur Laufzeit. Lennart Poettering hat bereits heiße Eisen mit „Measured Boot“ im Feuer. Ein Fingerzeig ist auch der geplante Vortrag „Remote Attestation of Imutable Operating Systems built on systemd“, den er am 12. März auf der Open Confidential Computing Conference in Berlin halten will.

Beim „Measured Boot“ prüft das System ausgehend von einer „Root of Trust“ im Trusted Platform Module (TPM) die Integrität von Firm- und Software beim Systemstart anhand von digitalen Fingerabdrücken, sogenannten Hash-Werten. Die Vergleichshashes liegen ebenfalls im TPM, dort in sogenannten Platform Configuration Registers (PCRs). Der Prozess ähnelt Secure Boot. Allerdings bricht Secure Boot bei abweichenden Hashes den Startvorgang ab, während Measured Boot die Hashes der Komponenten und ihrer Konfiguration protokolliert und sie verschlüsselt zur Überprüfung an andere Systeme senden kann (Remote Attestation, ausführliche Erläuterung von Infineon). Ein Vortrag auf der „All Systems Go“ im vergangenen Jahr zeigt zudem, was Poettering sich für Gedanken um die Sicherheitsarchitektur in Linux macht.

Derzeit besteht das Team von Amutable aus den Gründern Chris Kühl (CEO), Christian Brauner (CTO) und Lennart Poettering (Chief Engineer); Chief Product Officer ist David Strauss. Das Programmier-Team besteht aus Rodrigo Campos Catelin, Zbyszek Jędrzejewski-Szmek, Kai Lüke, Daan De Meyer, Joaquim Rocha, Aleksa Sarai und Michael Vogt. Die Beteiligten bringen Erfahrungen etwa für den Bau traditioneller Distributionen wie Debian, Fedora/CentOS, SUSE und Ubuntu mit, aber auch für unveränderliche, Image-basierte Distributionen wie Flatcar Container Linux, ParticleOS und Ubuntu Core, erklärt die Projekt-Ankündigung.

Kompetenzen für die genannten Ziele sind also reichlich vorhanden. Was genau Amutable aber bauen will, ist derzeit noch unklar. Eine diesbezügliche Anfrage wurde nicht umgehend beantwortet. Gegebenenfalls aktualisieren wir die Meldung damit.

Weiterlesen nach der Anzeige


(dmk)



Source link

Weiterlesen

Entwicklung & Code

Eine Schätzung ist keine Prognose: Sprachphilosophie im Softwareprojekt


Nicht nur in agilen Projekten gehört es zum normalen Vorgehen, Aufgaben zu schätzen (Ticket-Estimation). Persönlich vertrete ich dabei die Meinung, dass Schätzungen immer richtig sind. Es handelt sich schließlich um eine Schätzung.

Weiterlesen nach der Anzeige


Escape the Feature Factory: Stefan Mintert

Escape the Feature Factory: Stefan Mintert

(Bild: 

Stefan Mintert

)

Stefan Mintert arbeitet mit seinen Kunden daran, die Unternehmenskultur in der Softwareentwicklung zu verbessern. Das derzeit größte Potenzial sieht er in der Leadership; unabhängig von einer Hierarchieebene.

Die Aufgabe, dieses Potenzial zu heben, hat er sich nach einem beruflichen Weg mit einigen Kurswechseln gegeben. Ursprünglich aus der Informatik kommend, mit mehreren Jahren Consulting-Erfahrung, hatte er zunächst eine eigene Softwareentwicklungsfirma gegründet. Dabei stellte er fest, dass Führung gelernt sein will und gute Vorbilder selten sind.

Es zeichnete sich ab, dass der größte Unterstützungsbedarf bei seinen Kunden in der Softwareentwicklung nicht im Produzieren von Code liegt, sondern in der Führung. So war es für ihn klar, wohin die Reise mit seiner Firma Kutura geht: Führung verbessern, damit die Menschen, die die Produkte entwickeln, sich selbst entwickeln und wachsen können.

Für Heise schreibt Stefan als langjähriger, freier Mitarbeiter der iX seit 1994.

Wikipedia versteht darunter die genäherte Bestimmung von Zahlenwerten, Größen oder Parametern durch Augenschein, Erfahrung oder statistische Methoden. Eine Schätzung bestimmt also etwas, was ist, und nicht etwas, was wird. Eine Schätzung kümmert sich nicht um die Zukunft.

Die meisten Manager, die ich erlebt habe, behandeln Schätzungen aber wie eine Prognose, also eine Vorhersage über die Zukunft.

Wenn die Zukunft dann zur Gegenwart geworden ist, vergleicht man die Schätzung aus der Vergangenheit mit einem Wert, der sich zu einem späteren Zeitpunkt entwickelt hat. Das passt nicht zusammen.

Was die Manager eigentlich wollen, ist – wie gesagt – eine Prognose. Auch dazu hat Wikipedia etwas Interessantes zu sagen: Von anderen Aussagen über die Zukunft (z. B. Prophezeiungen) unterscheiden sich Prognosen durch ihre Wissenschaftsorientierung.

Wer sich als Entwickler von Schätzungen und dem Umgang damit unter Druck gesetzt fühlt, kann mal versuchen, Schätzungen durch Prognosen zu ersetzen. Selbstverständlich explodiert damit der Aufwand. Und genau das ist der Punkt: Viele Manager sprechen sehr viel und sehr gerne darüber, wie man besser schätzen kann. In diese Frage wird viel Energie gesteckt. Die Frage, wie man besser arbeiten kann, tritt dabei oft in den Hintergrund.

Weiterlesen nach der Anzeige

Es wirkt manchmal so, als ob die Schätzung (die eigentlich eine Prognose sein soll) wichtiger als das Produkt ist. Der Grund dahinter ist oft die den Managern heilige Planung. Die Gründe für deren Scheitern liegen aber nicht in der Durchführung der Schätzung. Eine Schätzung ist immer richtig, wie ich auch bereits an anderer Stelle schrieb.

Das gilt auch, wenn der geschätzte Wert vom wahren Wert abweicht. Wenn mir das nicht gefällt, müsste ich eine Schätzung durch eine Messung ersetzen. Das ist in diesem Fall nicht möglich, weil ich zukünftige Ergebnisse nicht heute messen kann.

Wenn ein Ticket bei Fertigstellung also dreimal so viel Zeit erforderte, wie geschätzt (prognostiziert) wurde, wird nicht die Frage gestellt, ob die Umsetzung des Tickets gut gelaufen ist. Nein. Bereits die Abweichung von der Schätzung (Prognose) genügt, um die geleistete Arbeit zu diskreditieren. Das halte ich für wenig zielführend, und hier sind meines Erachtens Softwareentwickler aufgefordert, der missbräuchlichen Verwendung von Schätzungen entgegenzutreten.

Der erste Schritt kann darin bestehen, klarzumachen, dass Pläne auf Grundlage von Schätzungen selbst Schätzungen und keine Zusagen sind. Wer es anders sieht, dem kann man mit hoher Wahrscheinlichkeit eine turbulente Zukunft prophezeien.

Wenn Du die Themen, die ich im Blog anspreche, in Deiner Firma verbessern möchtest, komm’ in unsere Leadership-Community für Softwareentwicklung. Sie wirkt auch ohne Führungsposition. Mit dem Code „heisedev“ gibt’s den Heise-Rabatt für Interactive-Members.


(rme)



Source link

Weiterlesen

Entwicklung & Code

Neu in .NET 10.0 [6]: Generische Erweiterungsblöcke in C# 14.0


Erweiterungsblöcke mit dem Schlüsselwort extension habe ich in der vorherigen Folge der Serie zu .NET 10.0 vorgestellt. Ein Erweiterungsblock darf einen oder mehrere generische Typparameter (optional inklusive Einschränkung mit where) besitzen:

Weiterlesen nach der Anzeige

extension(List source) { … }

oder

extension(List source) where T : INumber { … }


Der Dotnet-Doktor – Holger Schwichtenberg

Der Dotnet-Doktor – Holger Schwichtenberg

Dr. Holger Schwichtenberg ist technischer Leiter des Expertennetzwerks www.IT-Visions.de, das mit 53 renommierten Experten zahlreiche mittlere und große Unternehmen durch Beratungen und Schulungen sowie bei der Softwareentwicklung unterstützt. Durch seine Auftritte auf zahlreichen nationalen und internationalen Fachkonferenzen sowie mehr als 90 Fachbücher und mehr als 1500 Fachartikel gehört Holger Schwichtenberg zu den bekanntesten Experten für .NET und Webtechniken in Deutschland.

Folgender Code zeigt eine Klasse mit Erweiterungsblocken für List, wobei T auf Zahlen beschränkt ist, durch where T : INumber:


public static class MyExtensions
{
 extension(List source) where T : INumber // <-- Receiver Ein Erweiterungsblock darf eine oder mehrere generische Typparameter (optional inklusive Constraint) besitzen!!!
 {
  public List WhereGreaterThan(T threshold)
           => source.Where(x => x > threshold).ToList();
 
  public bool IsEmpty
           => !source.Any();
 
  /// 
  /// Erweitern um eine Instanz-Eigenschaft mit Getter und Setter
  /// 
  public int Size
  {
   get { return source.Count; }
   set
   {
    while (value < source.Count) source.RemoveAt(source.Count - 1);
    if (value > source.Count) source.AddRange(Enumerable.Repeat(default(T)!, value - source.Count).ToList());
   }
  }
 
  // NEU: Operatorüberladung als Extension und neu ist auch, dass man += überladen kann
  public void operator +=(int count)
  {
   source.Size = source.Count + count;
  }
 
  // NEU: Operatorüberladung als Extension und neu ist auch, dass man -= überladen kann
  public void operator -=(int count)
  {
   source.Size = source.Count - count;
  }
 
  // NEU: Operatorüberladung als Extension und neu ist auch, dass man ++ überladen kann
  public void operator ++()
  {
   source.Size += 1;
  }
 }
}


Folgender Code ruft die Erweiterungsmethoden für List auf:

Weiterlesen nach der Anzeige


public void Run()
 {
  CUI.Demo(nameof(CS14_ExtensionDemo) + ": Collection");
 
  var list = new List { 1, 2, 3, 4, 5 };
  var large = list.WhereGreaterThan(3);
  Console.WriteLine(large.IsEmpty);
  if (large.IsEmpty)
  {
   Console.WriteLine("Keine Zahlen größer als 3!");
  }
  else
  {
   Console.WriteLine(large.Count + " Zahlen sind größer als 3!");
  }
 
  CUI.H2("list.Size = 10");
  // Das klappt: Die Liste wird auf 10 Elemente mit Nullen aufgefüllt
  list.Size = 10;
  foreach (var x in list)
  {
   CUI.OL(x, separator: " = ");
  }
 
  CUI.H2("list.Size -= 2");
  list.Size -= 2;
  bool restart = true;
  foreach (var x in list)
  {
   CUI.OL(x, separator: " = ", restartCounter: restart);
   restart = false;
  }
 
  CUI.H2("list.Size++");
  list.Size++;
  restart = true;
  foreach (var x in list)
  {
   CUI.OL(x, separator: " = ", restartCounter: restart);
   restart = false;
  }
 }


Der Code erzeugt folgende Ausgabe:



Ausgabe des Beispielcodes


(rme)



Source link

Weiterlesen

Beliebt