Zum Inhalt springen

Ab wann ist OOP eigentlich wirklich OOP?


Gurki

Empfohlene Beiträge

Ja Hallo erst mal,

(wusste jetzt nicht wo ich das Thema eröffnen sollte, es gibt leider kein "Allgemein" unter dem Abschnitt "Programmierung")

was ist eigentlich richtiges OOP und ab wann ist es wirklich OOP? Simple Frage mit ganz viel Potential zum Antworten. ;)

Den Sinn dahinter, nämlich die Wiederverwendbarkeit des Quellcodes habe ich insoweit verstanden. Aber wie gestaltet man den Code nun wirklich Objektorientiert und Sauber?

Ist es schon Objektorientiert wenn ich einige Daten (Methoden, Variablen - halt Code) in neuen Klassen auslagere? Wobei es da ja schon gleich anfängt; Wie benenne ich "Sinnvoll" die Klasse?

Und: Was kommt letzten Endes wirklich in die Klasse und was nicht?

Ist es Objektorientiertes Programmieren, wenn ich eine Klasse habe, von der ein Objekt erstelle und damit dann weiter arbeite? Oder ist das nur der Anfang vom OOP?

Ist es Sinnvoll Globale Variablen zu setzen? Sicher, in einigen Fällen schon, aber ich nutze sie, damit ich diese Parameter z.b. nicht jeder Methode übergeben muss.

Um eine Wiederverwendbarkeit des Quellcodes herzustellen, lagere ich auch einiges als Methoden aus. Ein Sprichwort besagt ja: "Don't repeat your self" - gut, das will ich mit dem Auslagern bewirken - mitunter ist dies aber auch nicht möglich, also doch doppelten Code schreiben. Dann ist es oftmals so, wenn ich eine Formsanwendung schreibe, wie greife ich auf Daten zu, wie auf die Formelemente? Beides soll ja schließlich getrennt sein.

Schlußendlich lagere ich paar Daten in Methoden und Klassen aus - gebe die Daten ggf. zurück an die Formsklasse und das war es dann auch schon. Meiner Meinung nach ist das aber kein sauberer, guter Objektorientierter Code, er funktioniert halt nur.

So - ich würde das gerne ändern, weiß aber nicht wie... Wie gesagt, mir fallen nicht mal sinnvolle Klassennamen ein. In einem Spiel ist es einfacher, da gibts dann die Klasse "Game", "Player", "Enemy" und dann halt paar andere noch. Allerdings wie die dann wiederum aufgebaut werden, sodass OOP entsteht, weiß ich nicht und das als FIAE im 2. Lj. :(

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du siehst das zu technisch.

Objektorientierung ist ein Prozess und noch viel mehr eine Philosophie und Lebens(Arbeits)weise. Durch die Gedanken die du dir machst bist du schon auf einem guten Weg. Bei dem ganzen den Sinn nur in "Wiederverwendbarkeit des Quellcodes" zu sehen greift natürlich viel zu kurz.

Weitere Faktoren sind Erweiterbarkeit, Wartbarkeit, Stabilität, Vorhersagbarkeit und vieles mehr.

Ich denke du solltest dir nochmal auf "abstrakter" Ebene, also oberhalb des Codes anschauen in welcher Beziehung Objekte zueinander stehen können, was es mit Interfaces auf sich hat usw. UML kann dazu ein Werkzeug sein.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ist es schon Objektorientiert wenn ich einige Daten (Methoden, Variablen - halt Code) in neuen Klassen auslagere?
Nein.

Und: Was kommt letzten Endes wirklich in die Klasse und was nicht?
Das ergibt sich aus der Analyse und dem Design. Objektorientierung fängt nicht mit OOP an, sie hört mit OOP auf.

Ist es Sinnvoll Globale Variablen zu setzen?
Nein.

Sicher, in einigen Fällen schon, aber ich nutze sie, damit ich diese Parameter z.b. nicht jeder Methode übergeben muss.
Das ist Faulheit. Objektorientierung bedeutet auch saubere Schnittstellen. Mit globalen Variablen machst du auf einen Schlag alle Schnittstellen in deinem Programm kaputt, weil du nicht ausschließen kannst, dass zusätzlich Informationen über die globalen Variablen übergeben werden.

Um eine Wiederverwendbarkeit des Quellcodes herzustellen, lagere ich auch einiges als Methoden aus.
Das hat nichts mit OOP zu tun, das ist schon in der strukturierten Programmierung eine sinnvolle Idee.

Dann ist es oftmals so, wenn ich eine Formsanwendung schreibe, wie greife ich auf Daten zu, wie auf die Formelemente? Beides soll ja schließlich getrennt sein.
Dafür gibt es bewährte Modelle, wie z.B. MVC.

So - ich würde das gerne ändern, weiß aber nicht wie... Wie gesagt, mir fallen nicht mal sinnvolle Klassennamen ein.
Wie gesagt, OOP ist der letzte Schritt. Objektorientierung fängt mit Analyse und Design an.
Link zu diesem Kommentar
Auf anderen Seiten teilen

Als FIAE im 2. LJ solltest du das glaub ich wissen :D

Im gegensatz zu afo sehe ich die "Wiederverwedbarkeit des Codes" als den wesentlichen Pluspunk der OOP. Die Klasse beinhaltet eine/alle Eingenschaft/Eingeschaften der Objekte, bzw. erben die erzeugten Objekte die Eig. der Klasse, dies erleichtern das Anlegen gleichartigerer Objekte.

UML erleitert den Entwurf und auch das Verstehen von Zwischenbeziehungen zw. Klassen und Objekten.

PS: Hab mal ETIT studiert, bin kein ausgelernter AE oder so :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Nach meiner persönlichen Erfahrung wird der Wiederverwendbarkeits-Effekt überschätzt. Eine Problemlösung, ob jetzt OO oder nicht, ist immer irgendwo zwischen generisch und problemspezifisch. Je allgemeiner die Lösung ist, desto höher ist die Wiederverwendbarkeit, aber das erhöht auch den Aufwand. Man muss da ein gesundes Mittelmaß finden, das ist vermutlich eine Erfahrungsfrage.

Ein meiner Meinung nach viel wichtigerer Effekt eines guten OO-Designs ist die verbesserte Wartbarkeit und Erweiterbarkeit. Ein sauberes Design ist robuster gegenüber neuen oder veränderten Anforderungen, und die sind leider die Regel.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Als FIAE im 2. LJ solltest du das glaub ich wissen :D

Mach mir doch keine Angst! Ich fühl mich ja gerade so, als ob ich nichts kann... Mir fehlt gefühlt so viel Wissen und ich weiß nicht wie ich das ändern soll. Ich programmiere am WE ja nun schon bald mehr als in der Firma. Lesen tue ich auch - nur irgendwann fühlt sich mein Gehirn voll an mit dem ganzen Krempel...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mach mir doch keine Angst! Ich fühl mich ja gerade so, als ob ich nichts kann... Mir fehlt gefühlt so viel Wissen und ich weiß nicht wie ich das ändern soll. Ich programmiere am WE ja nun schon bald mehr als in der Firma. Lesen tue ich auch - nur irgendwann fühlt sich mein Gehirn voll an mit dem ganzen Krämpel...

Ja, es muss schon echt Leidenschaft sein..deshalb hab ich mich für FISI entschieden:)

Aber mach dir kein Kopf, hauptsache nicht aufgeben! Die Fragen klären sich von selbst wenn man gut genug informiert ist. Meiner Erfahrung nach strukturiert sich das Wissen i-wie "von selbst". Ich hatte während des Programmierens auch öfters das Gefühl alles wächst mir über den Kopf, aber ab einem gewissen Moment ist es wie Erleuchtung und du denkst:" accchhhh...sooo funzt das!". Also, kommt Zeit kommt Rat :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Aber mach dir kein Kopf, hauptsache nicht aufgeben! Die Fragen klären sich von selbst wenn man gut genug informiert ist. Meiner Erfahrung nach strukturiert sich das Wissen i-wie "von selbst". Ich hatte während des Programmierens auch öfters das Gefühl alles wächst mir über den Kopf, aber ab einem gewissen Moment ist es wie Erleuchtung und du denkst:" accchhhh...sooo funzt das!". Also, kommt Zeit kommt Rat :)

Das ist das wichtigste. Die Einsichten kommen mit wachsender Erfahrung zum Teil von selbst. In den "interessantesten" Augenblicken. Ich habe zum Beispiel heute Morgen auf dem Fahrrad eine weitere Facette des Factory-Patterns verstanden. Obwohl ich nicht bewusst in diese Richtung gedacht habe war es plötzlich einfach da.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also ich finde es recht schwierig quasi aus dem Stand eine tragfähige Definition für Objektorientierung geben zu können.

Ich habe irgendwo einmal einen plausiblen Erklärungsansatz gelesen, der in etwa folgendes beinhaltet:

* Objektorientierte Programmierung beschäftigt sich mit den "Dingen"/"Substantiven" Deiner Problemdomäne

Ein einfaches Beispiel, was immer wieder gerne genommen wird: »Bankwesen«

Wenn Du mit der Analyse des Bankwesens anfängst und eine Liste machst, kommst Du zu einer Reihe von Dingen und einer Reihe von Vorgängen.

Beispielsweise:

1) Kunde

2) Konto

3) Überweisung

Wenn Du diese drei Punkte vor Dir hast, beginnst Du zu überlegen, ob es sinnvol ist (für Deinen Anwendungsfall) aus all diesen Substantiven auch Klassen zu machen. Bei (3) fällt auf, das es zwar ein Substantiv ist, aber im Grunde ein substantiviertes Verb beinhaltet. Also wäre es nicht in jedem Falle notwendig, aus »Überweisung« eine Klasse zu machen. Sicher ist allerdings, dass es sich bei dem Konto (2) um eine Klasse handelt. Von da ausgehend modellierst Du Deine Objekte und Vorgänge.

Zur Objektorientierung gehört ein ganzer Katalog an Anforderungen, die ein gut gestaltetes Programm erfüllen soll:

Prinzipien Objektorientierten Designs

Als FIAE im 2. LJ solltest du das glaub ich wissen

Woher? Vom Himmel fällt das Wissen nicht. Wenn er keinen guten Betrieb oder eine schöechte berufsschule hat, kann man ihm daraus nicht unbedingt einen Strick drehen.

Eine Problemlösung, ob jetzt OO oder nicht, ist immer irgendwo zwischen generisch und problemspezifisch. Je allgemeiner die Lösung ist, desto höher ist die Wiederverwendbarkeit, aber das erhöht auch den Aufwand. Man muss da ein gesundes Mittelmaß finden, das ist vermutlich eine Erfahrungsfrage.

Vorallem hilft da YAGNI

Insgesamt ist für mich als Programmierer nicht die Frage, ob ein Programm objektorientiert ist oder nicht, entscheidend, sondern eher: ist das Programm sinnvoll strukturiert und leicht verständlich bzw. letztlich leicht änderbar.

Es gibt auch immer schöne Grenzfälle wie P of EAA: Transaction Script wo man behaupten könnte, das soetwas nichts in OOD zu suchen habe.

Alles in allem: DON'T PANIC!

Wenn Du noch kein Gefühl für OOAD hast, kommt es bestimmt noch :]

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke für Eure Antworten!

Alles in allem: DON'T PANIC!

Wenn Du noch kein Gefühl für OOAD hast, kommt es bestimmt noch :]

Aber das sagst Du so einfach... ich mache mich schon innerlich selber fertig, weil ich so wenig Wissen habe. (Und in 1 Jahr soll ich zur Abschlussprüfung...) Und ja; In meinem Betrieb habe ich das Gefühl das ich wirklich SEHR wenig lerne. Im Grunde muss ich mir alles selber beipulen... Aber ich glaube gelesen zu haben, das musstest Du auch (?).

Jedenfalls sagt einer meiner Arbeitskollegen auch immer: "Das kommt noch". Fragt sich nur wann... Naja ich werde dann mal weiter lesen und rum probieren!

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ist es schon Objektorientiert wenn ich einige Daten (Methoden, Variablen - halt Code) in neuen Klassen auslagere?

Das bezeichne ich eher als "Programmieren mit Klassen". Leider ist es das, was viele tun, wenn sie denken, sie entwickeln objektorientiert.

Im gegensatz zu afo sehe ich die "Wiederverwedbarkeit des Codes" als den wesentlichen Pluspunk der OOP.

Und wo unterscheidet sich OOP dann diesbezüglich von der guten alten prozeduralen Programmierung? Wesentliche Pluspunkte der OOP sind wohl eher Dinge wie Polymorphie, Vererbung etc.

Aber das sagst Du so einfach... ich mache mich schon innerlich selber fertig, weil ich so wenig Wissen habe. (Und in 1 Jahr soll ich zur Abschlussprüfung...)

Also ich hab schon etliche FIAE gesehen, und von denen war keiner ein "OOP-Guru". Das braucht tatsächlich Erfahrung und kommt erst mit der Zeit. Aber natürlich nicht von allein, indem man immer weiter üblen Code hackt. Such dir einen Mentor in deiner Firma, einen der wirklich Ahnung hat und nicht seit 98 in seinem VB6 hackt und denkt, das wäre OOP. Und ein gutes Buch über Softwaretechnik und Design Pattern.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Aber ich glaube gelesen zu haben, das musstest Du auch (?)

Ja. Traurig aber wahr. Mein Betrieb war -um es neutral zu formulieren- kein Top-Arbeitgeber.

(Und in 1 Jahr soll ich zur Abschlussprüfung...)

Naja. Gleiche Voraussetzungen wie bei mir. Ich bin quasi in's 2te Lehrjahr eingestiegen mit ~ 0 Wissen, was Programmierung angeht. Hab zuhause ein bisschen C gecodet und ein bisschen gescriptet aber nie seriös.

Andererseits ist die Prüfung halb so wild. Fang nur zeitig an, alte Prüfungen in punkto Programmieren durchzugehen, damit Du ein Gefühl dafür bekommst unter "Zeitdruck" mit Pen&Paper-Coding zurecht zu kommen. Das ist in meinen Augen für die Prüfung wichtiger.

Was mir eben geholfen hat war jede Menge You-Tube-Videos zu gucken (Fachvorträge), Videos - Øredev 2011 , Facilitating the spread of knowledge and innovation in enterprise software development , dnrTV und eine Handvoll Bücher ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 3 Wochen später...
Danke für Eure Antworten!

Aber das sagst Du so einfach... ich mache mich schon innerlich selber fertig, weil ich so wenig Wissen habe.

So habe ich mich in meiner Ausbildung nach 2 Moanaten gefühlt. Und dann kam auch noch extremer Druck vom Chef dazu....ich sag nur soviel, ich hab die Ausbildung dort nicht beendet.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich denke der grundlegende Aspekt von OOP (bzw. OOD) ist ein ganz anderer:

Die strikte Kapselung von Zustand und Operationen in das Objekt hinein - der innere Zustand ist von außen nicht erfahrbar, aber auch nicht relevant.

Objekte operieren eigentlich autonom auf sich selbst, in sich selbst, und kommunizieren lediglich mittels Nachrichten über definierte Schnittstellen miteinander.

Implementationstechnisch äußerst sich dies uA. dadurch, daß man stets das Objekt selbst aufruft, um eine Operation durchzuführen,

also obj.doSomething() statt doSomething(obj).

Selbst Klassen und Vererbung sind hier eher ein optionales Feature. In einigen Scriptsprachen, zB. Javascript, kann man die Methoden auch im Konstruktur an die konkrete Objekt-Instanz binden.

Im Grunde genommen sollte man das vielleicht sogar in Subjektorientierung umbenennen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Die strikte Kapselung von Zustand und Operationen in das Objekt hinein - der innere Zustand ist von außen nicht erfahrbar, aber auch nicht relevant.

IMHO stimmt dies so nicht, denn es gibt keine Unterscheidung zwischen "inneren" und "äußeren" Zustand, denn in diesem Fall könnte ein Objekt zu einem Zeitpunkt unterschiedliche Zustände haben und das lässt sich deterministisch gar nicht mehr umsetzen. Da die Programmiersprache deterministisch sein muss, ist somit die Aussage über zwei Zustände nicht korrekt.

Das Objekt hat, so lange es existiert, zu einem Zeitpunkt genau einen Zustand. Ein Methodenaufruf oder das setzen einer Eigenschaft verändert den Zustand, d.h. hier findet ein Zustandsübergang statt. Würden mehrere Zustände existieren wären die Wege im Statechartdiagramm redundant und damit würden Zyklen entstehen, die eine definierte Ausführung des Programm nicht mehr möglich machen würden.

Bei Timerstrukturen wie z.B. Threads, die unabhängig arbeiten, hat man sogar noch Epsilonübergänge (spontane Zustandsänderungen)

Implementationstechnisch äußerst sich dies uA. dadurch, daß man stets das Objekt selbst aufruft, um eine Operation durchzuführen,

also obj.doSomething() statt doSomething(obj).

Und wie definierst Du dann statische Aufrufe? Denn bei statischen Aufrufen existiert kein Objekt, d.h. nach dieser Definition würden statische Methoden und Eigenschaften nicht möglich sein. Gerade aber das Singleton-Pattern ist ein schönes Beispiel für statische Strukturen.

Zu Deinem Codebeispiel, das ist auch so nicht korrekt, Matlab bzw Python haben von ihrer Methodensignatur


def myPythonMethod(self) :

     pass


function myMatlabMethod(this)

end

In Matlab kann ich beide Methodenaufrufen durchführen und Matlab erkennt, dass als erster Parameter ein Objekt übergeben wurde. In Python ist die Objektreferenz letztendlich durch einen Parameter geregelt.

Bearbeitet von flashpixx
Link zu diesem Kommentar
Auf anderen Seiten teilen

IMHO stimmt dies so nicht, denn es gibt keine Unterscheidung zwischen "inneren" und "äußeren" Zustand, denn in diesem Fall könnte ein Objekt zu einem Zeitpunkt unterschiedliche Zustände haben und das lässt sich deterministisch gar nicht mehr umsetzen. Da die Programmiersprache deterministisch sein muss, ist somit die Aussage über zwei Zustände nicht korrekt.

Das Objekt hat, so lange es existiert, zu einem Zeitpunkt genau einen Zustand. Ein Methodenaufruf oder das setzen einer Eigenschaft verändert den Zustand, d.h. hier findet ein Zustandsübergang statt. Würden mehrere Zustände existieren wären die Wege im Statechartdiagramm redundant und damit würden Zyklen entstehen, die eine definierte Ausführung des Programm nicht mehr möglich machen würden.

Bei Timerstrukturen wie z.B. Threads, die unabhängig arbeiten, hat man sogar noch Epsilonübergänge (spontane Zustandsänderungen)

So war es bestimmt nicht gemeint.

Gemeint war eher, dass, die Hintertür per Introspektion/Reflection ausgenommen, es einen privaten und einen öffentlichen Teil des Zustandes gibt, wovon letzterer über fest definierte Schnittstellen gekapselt, letzterer lediglich dem Objekt selbst bekannt (sein sollte) ist. Ausnahmen gibt es bspw. in der Form, dass "private" auch Zugriff von Objekten gleichen Typs zulässt. Ansonsten sind die Objekte autark.

Insgesamt gilt:

Die drei wesentlichen Grundideen der OOP sind nachwievor

1) Kapselung von Daten únd Funktionen in Objekten (im Gegensatz bspw. zu C, wo Datenstrukturen und Funktionen getrennt sind)

2) Polymorphie

3) Vererbung

Unterschwellig könnte man das Konzept der "Nachricht" noch hinzuzählen, wonach ein Methodenaufruf gleichzusetzen ist, mit dem Senden einer Nachricht an das Objekt »Object.print()« schickt demnach die Nachricht "print" an das Objekt "Object".

Dass die ein oder andere Sprache Teile dieses Konzepts aufgenommen hat, ändert nichts an den Grundpfeilern der OOP.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Gemeint war eher, dass, die Hintertür per Introspektion/Reflection ausgenommen, es einen privaten und einen öffentlichen Teil des Zustandes gibt, wovon letzterer über fest definierte Schnittstellen gekapselt, letzterer lediglich dem Objekt selbst bekannt (sein sollte) ist.

Nein! Der externe ist identisch mit dem inneren Zustand (Determinismus). Der Zustand muss eindeutig sein. Ein Zustand ist etwas abstraktes, natürlich kann die Sichtweise (View) aufgrund des Zustandes variieren, der Zustand ist aber gleich. Es ist zu unterscheiden, was der Zustand eines Objektes ist und was die Sichtweise ist, das sind zwei unterschiedliche Betrachtung. Wäre es möglich mehrere Zustände eines Objektes zur gleichen Zeit zu haben, dann könnte man in der OOP keinen deterministischen Algorithmus entwickeln und das widerspricht ja nun mal der Realität. Für den Betrachter kann natürlich das Objekt nach außen anders aussehen aber der Zustand in den Fällen kann gleich sein.

Unterschwellig könnte man das Konzept der "Nachricht" noch hinzuzählen, wonach ein Methodenaufruf gleichzusetzen ist, mit dem Senden einer Nachricht an das Objekt »Object.print()« schickt demnach die Nachricht "print" an das Objekt "Object".

Genau das war ja mein Hinweis bezüglich der Zustandsübergänge, dazu Moore-Automat bzw Deterministischer endlicher Automat

die Methode verändert den Zustand, ob man das nun "Nachricht", "Event", "Message"... ist ja unerheblich

Bearbeitet von flashpixx
Link zu diesem Kommentar
Auf anderen Seiten teilen

Wäre es möglich mehrere Zustände eines Objektes zur gleichen Zeit zu haben, dann könnte man in der OOP keinen deterministischen Algorithmus entwickeln und das widerspricht ja nun mal der Realität. Für den Betrachter kann natürlich das Objekt nach außen anders aussehen aber der Zustand in den Fällen kann gleich sein.

Er spricht doch erstmal gar nicht von mehreren Zuständen sondern von Unterzuständen und deren Beobachtbarkeit.

Naja, was sind denn dann bitte zusammengsetzte Zustände (teilweise autark). Damit kannst du genau das beschriebene modellieren. Das Zusammensetzen von Zuständen widerspricht doch gar nicht dieser Modellierung.

Außerdem was würdest du dann in einem Aktormodel machen das ähnlich einem Petrinetz organisiert ist. Außerdem musst du explizit Mealy und Moore Automaten unterscheiden...

Deswegen, was er beschreibt mit der Kapselung und dem Information Hiding ist richtig.

Ja OOP beschreibt sich vor allem durch die explizite Zusammenfassung aller Daten und ihrer Funktionen zum Manipulieren in feste Blöcke mit verständlichen Metaphern. Polymorphie findet auch in der funktionalen Programmierung statt und Vererbung heißt ja erstmal nichts anders als du bildest Obermengen an Funktionalität und Daten.

Bearbeitet von Wodar Hospur
Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...