Keine Ahnung

Diskutiere Keine Ahnung im Allgemeine Java-Themen Bereich.
Thallius

Thallius

Hi,

tja wie der Titel schon sagt stehe ich hier vor einem Problem das ich in der Art noch nie hatte und wie ich auch gar nicht weiß wie ich das lösen soll.

Ich habe ein Jave Projekt "geerbt" und das ist einfach unvorstellbar:

Die Main Klasse die den eigentlich Main View beherbergt hat lächerliche 54327 Zeilen Code. Sprich, es ist eigentlich die komplette Software in einem File.
Das größte Problem dabei ist, dass sich IntelliJi beim bearbeiten dieser Datei relativ schnell aufhängt wenn man mit Code Inspection arbeitet. DAs abschalten ist aber auch keine Dauerlösung.

Was kann ich also tun? Da die Klasse ja nur aus 100ten von Methoden besteht kann ich das File ja auch nicht so einfach splitten. Es sein denn es gäbe so etwas wie ein "include" bei PHP.

Hat jemand eine Idee wie ich möglichst automatisiert dieses Chaos bereinige?

Gruß

Claus
 
L

LimDul

Egal ob Eclipse oder IntelliJ oder sonst eine IDE. Versuch ihr so viel Speicher wie möglich zur Verfügung zu geben, dass Refaktoring noch klappt.

Und dann Fang an Teile mittels der Refaktoring Möglichkeiten rauszuziehen, idealerweise zusammenhängte Sachen.

Und sobald dann genug kleinere Einheiten da sind, kann man dann mal mehr Struktur reinbringen.
 
J

JustNobody

Also neben dem, was LimDul gesagt hat sehe ich ein sehr großes Problem darin, dass der Code bestimmt auch keine Unit Test haben dürfte.

Ein wichtiger Schritt wäre aus meiner Sicht also auch, hier schnellst möglich massiv nachzuliefern. Damit zurrst Du ein klares Verständnis vom Verhalten fest und Du hast dann zumindest eine Chance, Fehler zu finden, die Du beim Refactoring einbaust. Fehler passieren nun leider einmal.

Somit hast an hier ein abgewandeltes TDD:
- Test schreiben und sicher stellen, dass dieser erfolgreich ist. (Mit Coverage ausführen -> Wird der Code halbwegs vernünftig abgedeckt? Wird nach meiner Erfahrung bei solchen Projekten nie der Fall sein!)
- Refactoring durchführen
- Test laufen lassen: Ist noch alles ok?

Bei so Code kommt oft auch ein weiterer Punkt hinzu: Man findet gewisse Pattern ("Fehler"), die man beseitigen möchte. (In der Vergangenheit war das bei mir bei c# Code dann, dass das Disposable Pattern nicht beachtet wurde.) Hier würde ich die Stellen aber erst markieren (TODO Kommentare setzen) und erst den Code in eine Form bringen, dass dieser bearbeitbar ist.
- Unit Tests habe ich angesprochen
- Vernünftige Form war Dein Hauptanliegen
- Versioning des Codes fällt mir da auch direkt ein - Du hast da hoffentlich ein git oder ähnliches im Einsatz. Ansonsten wäre das mein erster Schritt.

Als Ergänzung zu Limdul hilft Dir evtl. noch der Link: https://www.jetbrains.com/help/idea/increasing-memory-heap.html
Wie viel es bringt, weiss ich nicht. Ich hatte so einen krassen Fall noch nicht. Aber evtl. reicht sowas schon, um die Crashs abzustellen.

Das einfach mal an Gedanken von meiner Seite. Gibt bestimmt noch mehr Punkte, die schnelle Abhilfe schaffen. So automatische Tools sehe ich kritisch. Das kann ein Versuch wert sein, aber ich würde die auf Grund des potentiellen Risikos nicht nutzen (so Tests fehlen, aber evtl. hast Du ja Glück und es gibt viele Tests? - Die Hoffnung stirbt zuletzt und ich würde es Dir von Herzen wünschen/gönnen!).
 
L

LimDul

Ich glaube bei so einem Monster im wahrsten Sinne des Wortes ist auch ein Stufenplan notwendig, dass du dich Schritt für Schritt drauf fokussieren kannst Verbesserungen rein zu bekommen. Es gibt so viele Baustellen, dass man ohne konkreten Plan sehr leicht vom Hölzchen aufs Stöcken kommt und sich in Details verirrt.

Es gibt ja mehrere Aspekte, die wichtig sind:
- Code in Struktur bringen, dass die IDE damit vernünftig arbeiten kann. Hier sollte man nur "harmlose" Refaktoring Möglichkeiten der IDE nutzen, weil an der Stelle wie @JustNobody erwähnt, vermutlich die Testabdeckung gleich 0 sein sollte. Also Hauptziel erstmal in mehrere Klassen aufteilen. Auch wenn dann vermutlich weiterer Boilerplate Code in Form von gettern/settern/delegator Methoden etc. generiert wird.
- Überblick über die Fachlichkeit verschaffen. Was tut der Code eigentlich? Welche Code-Blöcke gehören zusammen? Welche Variablen bilden eigentlich eine fachliche Identität?
- Unit Tests für entsprechende fachliche Blöcke schreiben
- Entsprechende Fachliche Blöcke sauber refaktoren. Im Gegensatz zum ersten Punkt geht es hier darum, den Code lesbar zu machen. Das heißt hier baut man dann wirklich den Code um - dafür sollte man für die entsprechenden Stellen Unit-Tests geschrieben haben

Ich würde daher raten immer einen Schritt sich konkret vorzunehmen und wirklich nur den zu machen und wenn es einen in den Fingern juckt an den anderen Baustellen, wo man vorbeikommt, direkt Hand anzulegen.
 
T

Tobias-nrw

Du meinst, damit Code, der gerade noch funktioniert, dann gar nicht mehr funktioniert?
Bei Pferden, wenn diese unheilbar erkrankt sind, ruft man eigentlich den Abdecker, um das Leiden zu beenden.

Kurz: Er wird in den Blob aufgrund der Monopolisierung einer Vielzahl an Attributen und Methoden keine lose Kopplung und hohe Kohäsion herstellen können.
 
L

LimDul

Du meinst, damit Code, der gerade noch funktioniert, dann gar nicht mehr funktioniert?
Bei Pferden, wenn diese unheilbar erkrankt sind, ruft man eigentlich den Abdecker, um das Leiden zu beenden.

Kurz: Er wird in den Blob aufgrund der Monopolisierung einer Vielzahl an Attributen und Methoden keine lose Kopplung und hohe Kohäsion herstellen können.
Warum nicht? Das geht immer - nur der Aufwand wird halt immer höher.

Vermutlich wäre die technisch bessere Variante - wegwerfen und neu machen. Allerdings ist das vermutlich eine Software, die a) genutzt wird, und b) weiterentwickelt werden muss. Da kann man sich als Techniker hinstellen und sagen "Die Wartung ist nicht sinnvoll wir müssen das neu machen und brauchen dafür X PT". Dann sagt aber das Management "Geht nicht, die Zeit/Budget haben wir nicht. Die Software muss gewartet werden".

Und dann ist der sinnvolle Weg in das Wartungs-Budget Refaktoring/Aufräumen mit einzupreisen und es zu nutzen, die Software sukzessive besser zu machen.
 
J

JustNobody

Du meinst, damit Code, der gerade noch funktioniert, dann gar nicht mehr funktioniert?
Bei Pferden, wenn diese unheilbar erkrankt sind, ruft man eigentlich den Abdecker, um das Leiden zu beenden.

Kurz: Er wird in den Blob aufgrund der Monopolisierung einer Vielzahl an Attributen und Methoden keine lose Kopplung und hohe Kohäsion herstellen können.
Es geht hier erst einmal um technische Wege. Diese kann man sachlich betrachten. Ob es schneller ist, so einen Code wegzuwerfen und neu zu schreiben hängt von vielen Punkten ab, die wir nicht entscheiden können.

a) Anforderungen: Sind diese dokumentiert? Gibt es Ansprechpartner (die die Anforderungen kennen)?
b) Vorstellungen vom Management?

Wenn die Anforderungen nicht klar bekannt sind, dann ist der Code ggf. die (schlechte) Dokumentation der Anforderungen. Ein "Neu Schreiben" kann extrem schlecht laufen, wenn dann halt wichtige Anforderungen ggf. vergessen werden. Die Akzeptanz sinkt dann ggf. sehr stark.
Und was man dem Management verkaufen kann, ist auch immer so eine Sache. Ein "Wegschmeißen und neu schreiben" wird da oft nicht akzeptiert, da hier halt oft falsche Vorstellungen vorhanden sind. Und aus meiner Sicht ist das auch schnell eine Gratwanderung. (Das habe ich direkt in meinem ersten Projekt gelernt. Da habe ich Code übernommen von jemandem, der hoch angesehen war beim Kunden. Und er hat nun wirklichen Schrott-Code verzapft. Aber da muss man sich starkt zurück nehmen, denn man selbst muss sich ein Vertrauen erst aufbauen. Sowas kann also schnell nach hinten losgehen!)

Nur für eine sachliche Argumentation, wieso man etwas wegschmeißen soll (Was ja eine Investition war) braucht man also gute Argumente. Und um diese zu bekommen muss man schon einige Analysen machen. Und da ist immer noch die Frage: Was ist, wenn jemand ankommt und sagt: Warum hast du nicht das und das Tool verwendet? ...

Somit in kurz: Ich sehe das nicht als so trivial an. Man muss zumindest schauen, was notwendig wäre und den Aufwand abschätzen. Denn so kommt man zu klaren Aussagen, mit denen ein Manager etwas anfangen kann. Der kann dann entscheiden: Will ich diese Kosten tragen oder nicht? Wenn man das "neu bauen" anbieten möchte (Da wäre ich mir auch nicht immer so sicher - denn wenn die Rahmenbedingungen nicht passen, dann ist die Chance sehr hoch, dass es ein Desaster wird!), dann gilt das ebenso.

Daher beschränke ich mich hier rein um technische Inhalte: Was wäre da für ein Refactoring für mich wichtig....
 
Thallius

Thallius

Schon einmal danke für alle Anregungen.

wie Nobody schon richtig erkannt hat handelt es hierbei um ein tool das seit Jahrzehnten von vielen Angestellten benutzt und geschätzt wird und das außerdem sehr viel ganz spezielles technisches Know-how beinhaltet. Zu 90% habe ich dieses Know-how aber die letzten 10% sind für mich böhmische dörfer und werden es auch bleiben (dazu bräuchte es eines Mathematik- und Physikstudiums)
Meine Aufgabe ist es tatsächlich dieses Tool neu zu schreiben aber dazu muss ich halt diese 10% die ich nicht selber erbringen kann (und die man übrigens auch nicht im Internet er-googeln kann) aus dem aktuellen sourcecode extrahieren. Und dafür muss ich erstmal den Code irgendwie in meiner ide vernünftig ans Rennen bringen um dann rum-time Debuggen zu können.

deshalb geht es nicht darum diesen Code sauber zu machen um ihn weiter zu benutzen sondern ihn einfach nur so zu “zerlegen“, dass er handelbar wird. Problem dabei ist, dass dieser Code, dadurch das er nur aus einer Klasse besteht, hunderte instanzenvariablen hat und fast jede methode zig davon benutzt. Es ist damit eine brutale Herausforderung herauszufinden was die einzelnen Methoden eigentlich machen und wie sie es machen, da man in jeder Methode erstmal wieder herausfinden muss wie eigentlich die ganzen Instanzvariablen initialiisert wurden die diese benutzen.

eine sysiphus Arbeit.
 
J

JustNobody

Wenn es nur um reines Verständnis geht, dann würde ich kein Refactoring durchführen sondern nur Dokumentation anlegen / hinzufügen.

Dadurch hast Du dann immer den original Code in den Du so nie etwas "kaputt" machen kannst.

Du kannst aber z.B. einmal schauen, wo welche Membervariablen verwendet werden ... wenn Du Glück hast unterteilt sich so einiges direkt.

Ansonsten würde ich generell schauen, dass ich alles sinnvoll unterteilen würde ... was ist UI? Was ist Model? So in der Art. Bei Methoden wird das nicht immer 1:1 gehen, aber da kann man dann evtl. Teile der Methode unterteilen.... Und dann schauen, was evtl. zusammen gehört und so Blöcke bilden, die man ggf. einzeln betrachten kann.

Meine Hoffnung / Zielsetzung wäre auf jeden Fall, dass ich eine Dokumentation bekomme, die ich dann verwenden kann für die neue Implementation.

Das wäre da mein Ansatz denke ich mal ... Wünsche Dir auf jeden Fall viel Erfolg (und nicht zu viel deprimierende Rückschläge).
 
Thallius

Thallius

Dokumentation kannst du vergessen. Da gibt es gar nichts.

im Prinzip geht es bei der Software um DICOM Image Analysen. Hier hat der Programmierer damals hat einfach alles was er Grafisch darstellen will vorher im gleichen Code berechnet. Code der Panels und Grafen erstellt wechselt sich zeilenweise mit irgendwelchen. Pixelberechnungen ab.
Dazu gibt es routinen die die Bilder einlädt und Routinen die sogenannte ROI (Region of Intrest) auf das Image legen und die damit betroffenen Pixel werden dann entsprechend für die Berechnungen herangezogen.
Nur mal als Beispiel: wer jetzt glaubt es gibt einen Methode die das Image lädt und die ein paar Parameter mitbekommt die definieren wie dieses formatiert sein soll, der irrt. Es gibt einen Methode loadImage(). Welches Image geladen werden soll wird vorher in einer instanzvariqble geschrieben. alle notwendigen Parameter ebenfalls und das Ergebnis kommt dann auch in eine instanzvariable... so zieht sich das durch den ganzen Code.

spaß pur...
 
J

JustNobody

Mein Punkt war, dass Du Dokumentation erstellst. Refactoring am Code ist kontraproduktiv, wenn das Ziel bereits ist, eine komplette Neuentwicklung durchzuführen ("Meine Aufgabe ist es tatsächlich dieses Tool neu zu schreiben"). Ich sehe da halt die Gefahr, dass Du versehentlich dabei etwas änderst, dass Auswirkungen auf die Funktionalität hat....

Daher wäre wirklich die Überlegung, was wie Sinn machen könnte um sich den langen Code irgendwie zu erarbeiten.

Das Ziel ist halt nicht mehr, den Code leserlicher zu machen.
 
Thallius

Thallius

Das Ziel ist es den Teil des Codes zu finden und zu extrahieren der die 10% der Berechnungen macht die ich nicht kann. Das kann ich aber nur durch debuggen undn nicht durch lesen erreichen. ich muss es also irgendwie schaffen das Dingen vernünftig im debugger ans laufen zu bekommen um mit Hilfe von breakpoints und Step by Step Debuggng zu verstehen was dort gemacht wird. Ob ich das Programm dabei kaputt mache ist eigentlich egal. Ich weiß welches Bild ich als Quelle benutzte und ich kenne die Ergebnisse die bei der Berechnung heraus kommen. Ich muss nun einfach nur den Weg finden
 
L

LimDul

Ich werfe mal eine brachiale Idee in den Raum, die man zum großen Teil sogar mit normalen Texteditoren oder ggf. einem Hilfprogramm hinbekommt

* Mache alle Felder deiner Monster-Klasse public
* Erzeuge Klassen Teil1 bis TeilN, die im Konstruktor ein Objekt deiner Monsterklasse bekommen und es als Feld speichern.
* Erzeugte im Konstruktor deiner Monsterklasse von jeder der Klassen Tel1 bis TeilN ein Objekt das das Objekt, was gerade im Konstrukor erzeugt wird, übergeben wird (Bevor jemand meckert, ja, sowas sollte man normalerweise nicht machen)
* Verschiebe die ersten X-Methoden deiner Monster-Klasse in die Klasse Teil1
* In der MonsterKlasse werden die Methoden durch reine Delegation an das Objekt vom Typ Teil1 implementiert.
* In Teil1 werden alle Zugriffe auf Felder durch den entsprechend Zugriff auf das Objekt deiner Monsterklasse ersetzt.
* Das wiederholst du für alle weiteren Teil-Klassen.

Am Ende sieht deine Monster-Klasse so:

Java:
public class Monster {
public Teil1 delegationTeil1;
public Teil2 delegationTeil2;
// usw
public int feld1;
public int feld2;
public String feld3;
// usw.

public int methode1(int var1) {
   return delegationTeil1.methode1(var1);
}
// usw.
}
Die Teil1 sieht dann so aus:
Java:
public class Teil1 {
private Monster monster;

public int methode1(int var1) {
return monster.andereMethode(monster.feld42, monster.feld128);
}
}
Dann sollte es auch im Debugger und der IDE handlebar sein.

Ggf. musst du dir dafür ein kleines Programm schreiben, was dafür sorgt, dass bei den Variablen der entsprechende Verweis auf die Monster-Klasse ergänzt wird und was die DelegationsMethoden in der MonsterKlasser ergänzt.
 
Thema: 

Keine Ahnung

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben