Autor Beitrag
OldCat
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 77

Win 10 Pro x64
C# (VS 2019), (VS 2022)
BeitragVerfasst: So 31.10.21 13:30 
Liebe Gemeinschaft,

erneut wende ich mich an euch.

Es geht diesmal um sogenannte "Utility Klassen", und hängt auch mit meinem letzten Thread über das 'static'-Keyword zusammen.

Mein "Tutor" von der 'Columbia University of Art', welcher auf Youtube Kurse zum Programmieren hochlädt, lehrt in einem seiner Videos das Anlegen einer Utility Klasse (für Console-Apps), in der er statische Methoden in einer nicht-statischen Klasse schreibt.

Jetzt habe ich aber auch gelesen, dass solche Utility Klassen mit statischen Methoden lieber nicht angelegt werden sollen. Stimmt das?
Eine nicht-statische Klasse mit statischen Methoden, ist das 'erlaubt'?

Zur besseren Beurteilung, zeige ich euch den Link vom Video: Intro to C#: 9 - Static, Methods, Parameters and Return Statements in C#

Liebe Grüße und einen schönen Sonntag wünscht

Old Cat :wink2:

Moderiert von user profile iconTh69: URL-Titel hinzugefügt.
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 31.10.21 15:15 
Statische Klassen sind eigentlich nur Syntax-Zucker und haben keine technische Relevanz. Der Compiler verbietet einfach nur alle nicht-statischen Inhalte, mehr nicht.
Technisch wird daraus eine sealed abstract class, aber das macht für dich keinen Unterschied.
Der Knackpunkt ist nicht die statische Klasse, sondern die statischen Methoden.

Ob die nun "verboten" sind, hängt sehr stark von der Situation ab, es gibt also keine "böse" oder "nicht böse"-Antworten, aber generell sind sie problematisch, weshalb man sie vorsichtig einsetzen sollte.
Statische Methoden haben keine Abstraktion, jeder Code, der sie nutzt, ist also direkt davon abhängig und kann nicht ohne diese Utility-Methoden getestet werden und Änderungen in diesen Utility-Methoden kann den anderen Code direkt beeinflussen.
Das ist ein Problem, denn wenn z.B. eine MessageBox darin angezeigt wird, tötest Du damit jeden UnitTest.

Ist die Methode aber in sich abgeschlossen, hat keine direkten oder indirekten Abhängigkeiten und erledigt generell nicht allzu aufwändige Dinge (bestes Beispiel: Math-Klasse), dann sieht das etwas anders aus.
Man kann diese Klasse zwar nicht abstrahieren, doch das ist gar mehr nicht notwendig.
Dennoch bleibt die Abhängigkeit und dadurch potentielle Probleme, deshalb sollte man sowas mit Vorsicht einsetzen.

Ich persönlich fahre einen eher Modul-bezogenen Ansatz.
Bei mir sind Projekte immer in viele Teil-Projekte aufgeteilt, je nach Aufgabenbereich. Wenn ein Stück Code aus dem Gesamt-Projekt ein anderes Teil-Projekt benötigt, sieht es nur das, was es sehen können soll, der Rest bleibt verborgen (internal).
Dieser Aufbau und die dadurch erlangte Kontrolle verschafft mir einen kleinen "sicheren" Bereich, in dem ich auch mal mit Prinzipien brechen kann, wenn sie der Lesbarkeit oder Performance oder anderen Zielen schaden würden.
Z.B. habe ich in solchen Projekten häufig statische Utility-Klassen (immer internal, immer!) oder ich verwende "normale" Klassen ohne Abstraktion, alles nicht so wichtig, solange von außen nur Abstraktionen und bewusst geplante Klassen genutzt werden können.
Das heißt natürlich nicht, dass es dadurch keine Probleme geben kann, aber die Auswirkungen sind auf das Teil-Projekt begrenzt und damit überschaubar. Außerdem bin ich der Meinung, dass Klassen, die direkter Teil der Funktion einer anderen Klasse sind, nicht zwingend eine Abstraktion haben müssen, da man das Eine sowieso nicht ohne das Andere nutzen kann - vorausgesetzt es handelt sich nicht um eine Verletzung vom "S" in "S.O.L.I.D."

Parallel dazu habe ich aber auch eigene Utils-Projekte für abgeschlossene Klassen, die zu komplex sind, um sie (doppelten Code bewusst in Kauf nehmend) immer zu kopieren.
Damit meine ich z.B. eine AsyncLock-Implementierung oder andere komplizierte Hilfs-Klassen.
Hierbei ist es natürlich eine Gratwanderung, was eine Abstraktion bekommen sollte oder nicht und was statisch sein darf, denn solche Utilis-Projekte wirken sich häufig auf alles aus und können damit das ganze Projekt in Gefahr bringen.
Daher bleibt auch hier die absolut zwingende Grundregel: In sich abgeschlossen, keine direkten oder indirekten Abhängigkeiten und keine aufwändigen Aufgaben.

Bedenke aber auch, dass ein solche Aufteilung zwar Vorteile haben kann, bei falscher oder übermäßiger Umsetzung das ganze Projekt sehr schnell extrem komplex machen kann.
Gerade am Anfang mit wenig Erfahrung ist das also mit Vorsicht zu genießen und Du solltest lieber auf einfachere Regeln setzen.

Für diesen Beitrag haben gedankt: OldCat, Th69
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 31.10.21 17:58 
Zitat:
Eine nicht-statische Klasse mit statischen Methoden, ist das 'erlaubt'?

Ja es bedeutet nur das du von dieser Klasse weiterhin eine Instanz erzeugen kannst (du kannst new benutzen). Bei der hier gezeigten Klasse macht das aber keinen Sinn hätte der Author also auch eher als statische Klasse machen sollen.
Zitat:
Jetzt habe ich aber auch gelesen, dass solche Utility Klassen mit statischen Methoden lieber nicht angelegt werden sollen. Stimmt das?

Man muss sie nur möglichst richtig einsetzen ;) In dem Beispiel geht es ja um die Console Klasse und deren Write Methoden. Console ist selbst eine statische Klasse und Write(Line) sind statische Methoden dieser Klasse. Das .Net Framework das du benutz ist bereits voll von statischen Klassen mit statischen Methoden (anderes Beispiel wäre die Math Klasse die in Beispielen auch gern verwendet wird) ;) Hätten die anders machen können und an anderen Stellen würde ich auch sagen ist der Einsatz manchmal fragwürdig bei Console halte ich den Einsatz aber für nachvollziehbar. Es ist nicht schlecht das die Console Klasse statisch ist.

Kurze Videokritik.
Er benutzt using static Console um nicht überall Console. vor die Write(Line) Methoden schreiben zu müssen. Ich würde dir raten dieses Feature erstmal vollständig zu ignorieren. Es verschleiert wo Methoden herkommen und macht Code undurchsichtig. Beim Lernen ist das glaube ich nicht hilfreich. Er hätte dann gleich in der Program.cs Datei auch using static ConsoleUtils schreiben können dann wär das durcheinander perfekt (außer man weiß schon wie das Zeug funktioniert dann bräuchte man dieses Video aber nicht). Und übrigens auch wenn das ebenfalls das static Schlüsselwort ist es bedeutet etwas völlig anderes. Schön wenn Schlüsselwörter auch noch Kontextabhängig sind. In der Kombination "using static" gleich doppelt kontextabhängig. Ich glaube das ist im Video auch nirgendwo erwähnt. Es wird da einfach static benutzt in einem Beispiel zu static aber in einer ganz anderen Bedeutung als die die er erklären will :(

Er mischt in seiner "Utils" Klasse Methoden die man nicht zusammenpacken sollte oder die sinnlos sind da nicht wirklich wieder verwendbar. Ist halt nur Beispielcode. Ein Methode auszulagern die "Hello" ausgibt ist Unfug, vermutlich ist dir das auch bewusst. Der Rest der sich ums formatieren kümmert kann man so machen. Man sollte dann aber die reinen Mathefunktionen nicht dazu werfen.
Wen man statische Klassen/Methoden benutzt dann zumindest darauf achten sie thematisch auseinanderzuhalten und dann im Zweifel einfach mehrere anlegen. Dann werden die einzelnen Klassen zumindest einigermaßen wieder verwendbar. Das ist übrigens ein recht guter Maßstab. Wenn du eine Methode in einer statischen Klasse anlegst frag dich ob du die Methode auch so in einer ganz anderen Anwendung gebrauchen könntest. Dann ist die Wahrscheinlichkeit gegeben das du halbwegs richtig unterwegs bist. Dieses Video transportiert unterschwellig einfach alles auszulagern damit eine andere Klasse, hier die Programm Klasse, nicht zu komplex wird. Das ist sicher kein guter Maßstab und wieder dem geschuldet das das hier Beispielcode ist der die Verwendung von static zeigt aber nicht wie man eine gute Applikation schreibt.

Moderiert von user profile iconTh69: C#-Tags hinzugefügt

Für diesen Beitrag haben gedankt: OldCat, Th69
OldCat Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 77

Win 10 Pro x64
C# (VS 2019), (VS 2022)
BeitragVerfasst: Mo 01.11.21 14:36 
Super, danke ihr beiden. :think:

Eure Beiträge zum Thema haben mir sehr weiter geholfen!

Wünsche euch eine erfolgreiche und oder schöne Woche. Hab bestimt bald wieder Fragen :gruebel:

PS: Danke auch für die Vorstellung von S.O.L.I.D. Habe dazu auch ein paar Sachen zum Lernen gefunden.

Liebe Grüße
OldCat :wink2:
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Mo 01.11.21 15:52 
Zu SOLID ist Lektüre aber ein problematisches Thema.
Viele verschiedene Erklärungen und nicht alle sind gut.

David Tielke hat dazu je ein Video gemacht, die sind ganz gut.
Ich persönlich fand die Erklärungen im "Clean Architecture"-Buch von Robert C. Martin selbst am besten - das ist aber auf Englisch und kostet Geld, gibt's aber auch als Hörbuch.

Für diesen Beitrag haben gedankt: OldCat
OldCat Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 77

Win 10 Pro x64
C# (VS 2019), (VS 2022)
BeitragVerfasst: Mo 01.11.21 16:45 
user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
Ich persönlich fand die Erklärungen im "Clean Architecture"-Buch von Robert C. Martin selbst am besten - das ist aber auf Englisch und kostet Geld, gibt's aber auch als Hörbuch.


Das habe ich tatsächlich auch schon auf meiner persönlichen "Wunschliste" :dance2:

Allerdings eine deutsche Übersetzung davon: Clean Architecture - Gute Softwarearchitekturen: Das Praxis-Handbuch für professionelles Softwaredesign. Regeln und Paradigmen für effiziente Softwarestrukturierung

Werde mir die Videos von David Tielke efinitiv anschauen.

Liebe Grüße
OldCat :wink2: