Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

1

05.03.2015, 10:50

Software Architektur in der Java Welt

Guten Tag,

am 2. Januar dieses Jahres habe ich meinen Job bei einem großem IT Unternehmen begonnen. Wir sind die in-house IT und entwickeln Kundennahe Lösungen die wir durch andere Teile des Unternehmens rein bekommen.
Ich arbeite in der Java Abteilung und sollte gleich zu Anfang dieses Übungsprogramm schreiben. Dazu hätte ich von euch gerne einmal Feedback, wie "professionell" das ganze jetzt geworden ist. Feedback von meinem Software Architekten habe ich schon (länger, so wurde es als "geleckt" akzeptiert), aber ich bin aktuell nicht sehr zufrieden wie offenbar in der Industrie Software entwickelt wird, bzw. was in der Java Welt als "best practice" angesehen wird (Stickwort: overengineering).

Also, was haltet ihr davon? Kennt ihr das auch wenn ihr zuhause mit aktuellen Technologien arbeitet und Probleme einfach löst, und euch dann so unproduktiv/altmodisch im Unternehmen vorkommt? Das muss sich nicht unbedingt auf mein Mini-Projekt beziehen, es wäre allgemein mal interessant zu hören wie das bei anderen so läuft.

Noch nebenbei: ich bin überhaupt kein Java Fan, genaugenommen finde ich Java obsolet/veraltet/schlecht designed, aber damit muss ich jetzt erstmal leben.

[Edit]

Dieser sehr gute, nicht mehr ganz aktuelle, Artikel trifft eigentlich was ich denke. Und hier auch erlebe.

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »DeKugelschieber« (16.03.2015, 14:59)


Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

2

05.03.2015, 12:11

Was genau sollte die Anwendung abdecken? Also: was waren die Anforderungen?

Da (meiner Meinung nach) noch ein paar Informationen fehlen, kann ich nur anhand der Namen grob abschätzen, welche Klasse was darstellen soll. Bisher ist mir aufgefallen:
  • Es gibt eine Klasse für einen "Getränkewunsch". Das kann man (in diesem Fall) vereinfachen, da der "Getränkewunsch" nichts weiter als ein Getränk (beschrieben durch das Fach, in welchem es lagert) ist. Am Ende würde man also das Getränk/das Fach des Getränks (oder dessen ID/Nummer) verwenden, statt eine Klasse dafür anzulegen.
  • Ein "Münzschacht" und ein "Getränkefach" sind meiner Meinung nach unterschiedliche Dinge. Ich bin mir nicht sicher, was mit diesen Beiden Dingen genau gemeint ist, allerdings kann ich mir anhand des Namens nicht vorstellen, dass sie an irgendeiner Stelle anhand ihrer gemeinsamen Basisklasse (also polymorph) verwendet werden würden.
  • Diverse Exceptions erscheinen mir dem Namen nach nicht unbedingt sinnvoll. Wenn der Benutzer bspw. zu wenig Geld eingeworfen hat, um ein Getränk zu erwerben, dann schalten die meisten Automaten auf einen anderen Zustand um, statt die Eingabe (Getränkauswahl) zu verweigern.
  • Der Name fachPreisSetzen ist schlecht gewählt, da bereits setzeFachPreis besser wäre.
  • Diverse Setter erscheinen mir überflüssig zu sein, da diese sehr wahrscheinlich nur ein einziges Mal aufgerufen werden (für Getraenkefach.setPreis(int) würde ich das annehmen). Stattdessen wäre ein weiterer Parameter im Konstruktor und ein Verzicht auf den Setter besser.
  • Getraenkewunsch.getraenkeFachNummer, Fach.inhaltLimit etc. könnte genausogut auf final und public gesetzt werden, wodurch der Getter nicht mehr erforderlich wäre.
  • Es werden in manchen Methoden bei Fehlern Exceptions geworfen, in anderen wird false zurückgegeben (Beispiel: Fach). Man sollte das einheitlicher gestalten.
  • Allgemein wird scheinbar einfach probiert, eine Aktion durchzuführen und auf eine Exception zu warten, statt vorher zu prüfen, ob die Operation überhaupt möglich ist. Das ist nur an solchen Stellen nicht der Fall, an denen mit Hilfe des eigenen Code geprüft werden _muss_ (bspw. weil sonst das Fachlimit überschritten werden würde).
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

3

05.03.2015, 13:15

Gut die Anforderungen waren am Anfang nicht klar spezifiziert. Mir war die Freiheit gelassen einen sinnvollen und nachvollziehbaren Getränkeautomaten zu implementieren.


  • Es gibt eine Klasse für einen "Getränkewunsch". Das kann man (in diesem Fall) vereinfachen, da der "Getränkewunsch" nichts weiter als ein Getränk (beschrieben durch das Fach, in welchem es lagert) ist. Am Ende würde man also das Getränk/das Fach des Getränks (oder dessen ID/Nummer) verwenden, statt eine Klasse dafür anzulegen.
  • Ein "Münzschacht" und ein "Getränkefach" sind meiner Meinung nach unterschiedliche Dinge. Ich bin mir nicht sicher, was mit diesen Beiden Dingen genau gemeint ist, allerdings kann ich mir anhand des Namens nicht vorstellen, dass sie an irgendeiner Stelle anhand ihrer gemeinsamen Basisklasse (also polymorph) verwendet werden würden.
  • Diverse Exceptions erscheinen mir dem Namen nach nicht unbedingt sinnvoll. Wenn der Benutzer bspw. zu wenig Geld eingeworfen hat, um ein Getränk zu erwerben, dann schalten die meisten Automaten auf einen anderen Zustand um, statt die Eingabe (Getränkauswahl) zu verweigern.
  • Diverse Setter erscheinen mir überflüssig zu sein, da diese sehr wahrscheinlich nur ein einziges Mal aufgerufen werden (für Getraenkefach.setPreis(int) würde ich das annehmen). Stattdessen wäre ein weiterer Parameter im Konstruktor und ein Verzicht auf den Setter besser.
  • Getraenkewunsch.getraenkeFachNummer, Fach.inhaltLimit etc. könnte genausogut auf final und public gesetzt werden, wodurch der Getter nicht mehr erforderlich wäre.
  • Allgemein wird scheinbar einfach probiert, eine Aktion durchzuführen und auf eine Exception zu warten, statt vorher zu prüfen, ob die Operation überhaupt möglich ist. Das ist nur an solchen Stellen nicht der Fall, an denen mit Hilfe des eigenen Code geprüft werden _muss_ (bspw. weil sonst das Fachlimit überschritten werden würde).
Bei Punkt 1 wären wir schon mal beim "Javaland" in dem es nur Nomen gibt. Mein C++ Gehirn hatte an der Stelle auch erstmal keine Klasse angelegt, sondern wie du schon sagst, einfach mit einer Nummer (echten Daten) gearbeitet. Die Klasse wurde dann auf Wunsch hin eingebaut.

Der Punkt 2 wäre mir jetzt auch erstmal nicht aufgefallen. Das entstand dann aus dem Kontext der "Vereinfachung" heraus, da sich beide Klassen Member teilen.
Jetzt wo du es sagst: in C++ hätte ich das wahrscheinlich nie so geschrieben, da natürlich kein polymorphes Verhalten erwünscht ist.

Punkt 3: das scheint eine echt grusselige Praxis in Java Enterprise Bereich zu sein: Exceptions werden als Rückgabewerte missbraucht. Ich hatte im ganzen Programm zunächst keine einzige Exception.
Wobei ich da meinem Architekten recht geben muss: wenn etwas schief geht erkennt man an einer fachlichen Exception was nicht stimmt. Trotzdem werden diese falsch eingesetzt...

Getter und Setter... ja auch eher weils so üblich ist. Ich hatte zunächst wie mit structs in C++ gearbeitet und Klassen als Tupel verwendet, mit public Membern.

Zum letzten Punkt: jop, gefällt mir auch garnicht. Sehe ich auch in dem Projekt in dem ich Arbeite, dass Objekte in ungültigen Zuständen rumdümpeln und eher mit try...catch korrigiert werden (bzw. Loggen -> weitermachen), anstatt dieses Antidesign von vorne herein zu vermeiden.

Um noch mal auf den Kontext einzugehen: mein Ansatz war sehr C++ getrieben, da ich eigentlich selten in Java programmiere. Das war jetzt das erste mal dass ich mit der Business Welt in diesem Bereich zu tun hatte.
Ich finde es sehr interessant, dass sich dort diese scheußlichen Muster eingeschleift haben. Damit will ich garnicht mal alle Java Entwickler beleidigen. Aber mal ehrlich, ist das nicht auffällig? Woran liegt das?
Das Design sieht mir in Java immer Object-Obsessed aus, statt Data oriented zu sein.

Auch finde ich überall Locator, Factories und Singletons... muss das sein? Ich hätte einfach gerne eine Erklärung dafür und vielleicht gute Argumente, um mal etwas dagegen zu halten.

Aber Danke schon mal für dein Feedback Sacaldur :)

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »DeKugelschieber« (05.03.2015, 13:26)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

05.03.2015, 13:28

Die Anforderungen sind unbekannt, es wirkt auf den ersten Blick aber overengineered.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

5

05.03.2015, 13:44

Wobei ich es oftmals sehr schwierig finde bei ebend unbekannten Anforderungen den richtigen Grad zwischen Overengineering und "zu wenig über die Architektur nachgedacht" zu finden. Oftmals stellt sich auch die Frage danach, wie lange die Technologie die man verwendet offiziell Support hat, solange die Software im Einsatz ist.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

6

05.03.2015, 14:05

Oftmals stellt sich auch die Frage danach, wie lange die Technologie die man verwendet offiziell Support hat, solange die Software im Einsatz ist.

Wie meinst du das genau? Was ich hier sehe sind gigantisch große Frameworks die irgendwie komisch in das eigene Design integriert wurden.
Wir sind also noch nicht so weit Frameworks wie z.B. Spring einzusetzen, die oberflächlich erstmal besser aussehen. Die ganze Toolchain ist sowieso veraltet...

Toa

Alter Hase

Beiträge: 944

Beruf: Research associate

  • Private Nachricht senden

7

05.03.2015, 14:28

Hey,

ich hab nur die Tests von deinem Projekt gelesen und es wirkt auf mich, als hättest du noch nicht viel tdd in deinem Leben gemacht. Du hast oftmals keine Unit-Tests sondern Integration-Tests geschrieben. Wenn du Tests für den Getränkeautomaten schreibst, musst du alle anderen Dinge wegmocken, was bei deiner akuellen Codestruktur gar nicht möglich ist. Deshalb schätze ich, dass du die Tests nachträglich geschrieben hast.

Außerdem sind deine Tests schwer zu lesen. Ich mag Test bei denen ich eine Testerwartung (expected) und ein reeles Ergebnis (actual) haben und dann nur eine Testbedingung geprüft wird. Das verletzt du auch sehr häufig. Wenn du magst, kannst du bisschen durch unseren Testcode stöbern, der ist aber in C#.

Grüße T0a
"Das ist ein Minkovski Raum, manche Menschen nennen ihn auch Weltraum" Prof. Dr. Jürgen Wambach, Theoretische Physik, TU Darmstadt | Meine Homepage

buggypixels

Treue Seele

Beiträge: 125

Wohnort: Meerbusch

Beruf: Programmierer

  • Private Nachricht senden

8

05.03.2015, 14:33

Ich kann Dich beruhigen, denn so programmiert keiner im normalen Berufsleben. Allerdings glaube ich gerne, dass ein Softwarearchitekt das vielleicht sogar gut findet.
Immer merken, dass im echten Leben Architekten und Projektleiter keine Ahnung haben. Sonst würden sie auch nicht so einen Job machen. Da sind meistens die Aussortierten.
Aber das ist ein ganz anderes Thema.
Also der Code ist so dermaßen komplex. Man glaubt gar nicht, dass es nur um einen Getränkeautomaten geht. Wenn mir das jemand gezeigt hätte, ohne jegliche Information von
wem das ist usw., ich hätte nach 2 Minuten gesagt, dass ist einer frisch von der Uni. Ich will Dich hier nicht beleidigen, also verstehe mich nicht falsch.
Man sieht auch, dass Du Java nicht magst. Hättest Du nicht erwähnen müssen. Aber das solltest Du schleunigst ablegen, denn Java ist und bleibt die Nummer 1 der Computersprachen
und das vermindert dann doch die Jobauswahl, wenn es nicht Java sein soll. Vor allem in den Geschäftsbereichen wo richtig Geld verdient wird ist Java Standard.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

9

05.03.2015, 14:47

@Toa: ja die Tests waren überhaupt nicht vorgesehen und wurden dann im nachhinein geschrieben ;)
Im Projekt in dem ich arbeite sind die Tests aber noch hässlicher, teilweise mit > 100 Zeilen in einer Methode... Ich guck mir deinen Code mal an.

@buggypixels: ja ich dachte auch "frisch von der Uni" :D Mein erster Ansatz lief schon, war naiv und simpel. Sinnvoll aufgeteilt aber eben straight das Problem gelöst, so wie ich es in meinen eher favorisierten Sprachen auch getan hätte.
Meinem Mentor ging es darum die Logik so klein zu zerlegen wie möglich ("single layer of abstraction"). Ich finde es nur begrenzt sinnvoll...

Also nur damit da keine Missverständnisse auftreten: das ist nicht mein Stil, das Programm ist in mehreren Iterationen entstanden in denen ich dann auch häufig gegen die gewünschten Änderungen argumentiert habe. Letztendlich habe ich das geschrieben was jemand anderes sich so vorgestellt hat. Das ist nicht völlig schwachsinnig, ich glaube schon das mein Mentor sein Fach beherrscht. Aber er ist eben mit Java aufgewachsen und hat (denke ich) noch nie in einer anderen Sprache programmiert.

Gegen Java habe ich übrigens gar nicht so viel als Sprache (schon einiges, aber das schreckt mich nicht ab), sondern eher wie damit umgegangen wird. Was sich so als Industriestandard eingebürgert hat (die ganzen viel zu fetten Frameworks und overengineering, excessive Nutzung von Patterns und static Methoden die eignetlich first class functions sein sollten, ...).

[Edit]

@Toa: das System hinter deinen Tests ist entweder deutlich besser designed oder weniger komplex. Das die Tests in dem Projekt in dem ich arbeite wesentlich größer sind ist teilweise schon legitim (200.000 Zeilen Code müssen eben getestet werden), da das Projekt uralt ist. Bei neuen Tests/Projekten verwenden wir Jnario, das sieht dann auch so aus wie bei dir, von der Länge und Komplexität her.

[Edit]

Noch ein Nachtrag, mir ist gerade aufgefallen dass ihr euch das Design auch visuell ansehen könnt:


(Link)


Gott Münzschacht... :P

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »DeKugelschieber« (05.03.2015, 14:55)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

10

05.03.2015, 16:13

Immer merken, dass im echten Leben Architekten und Projektleiter keine Ahnung haben. Sonst würden sie auch nicht so einen Job machen. Da sind meistens die Aussortierten.
Das ist dann ein Zeichen für eine schlechte Firma, wenn die Idioten hochgelobt werden. Sorry.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige