Wie kann ich mein 8 Klassen Gebilde objektorientierter schreiben?

berndoa

Top Contributor
In #3 habe ich klare Vorschläge gegeben, was man denn zu eigenständigen Objekten zusammen fassen könnte ...

in #10 habe ich dann noch einmal etwas aufgezeigt, wie sowas aussehen könnte.

Deine Erläuterungen in #11 waren teilweise leicht verwirrend. Du hast zwar versucht, die einzelnen Variablen etwas zu erläutern, aber aus der kurzen Erläuterung konnte ich jetzt nicht wirklich ableiten, was da genau gespeichert wird und welcher Art da die Zugriffe sind.

Daher blieb es vor allem bei den allgemeinen Aussagen, wobei #10 ja schon etwas aufzeigt, wie sowas aussehen würde.

Dann wurde leider abgewichen, aber das durchaus zu Recht, denn auch wenn Du es bisher nicht wahr haben willst: Viele der angesprochenen Punkte würden sehr helfen, dass wir Dir besser helfen können. Derzeit ist es recht hart zu verstehen, was die Abläufe sind. Man muss in mehreren Dateien schauen, wo eine Variable verwendet wird um dann aus den zugewiesenen Werten schlau zu werden.

Aber vielleicht können wir einfach das Vorgehen etwas an einem konkreten Beispiel vorstellen. Du hast ja etwas, das den Einsatz steuert.
Dazu hast Du ja ein Array mit Werten erstellt:
int[] einsbut={10,50,100,200,500,1000,2500,5000,10000,50000,100000};

Vorgehen ist, dass Du Einsätze festlegst. Dabei gehst Du auf Farbe.

Wenn eine Farbe 7 Mal nicht gekommen ist, dann setzt Du 10 auf diese Farbe.
Wenn die Farbe 8 Mal nicht gekommen ist, dann setzt Du 50 auf diese Farbe.
...
Bis Du 100.000 setzt.

Das habe ich verstanden. Es gibt die Farben ROT und SCHWARZ. Gibt es noch andere Möglichkeiten? (Ich kenne mich da absolut nicht aus. War da nicht etwas mit einer Neutralen Zahl? Zero?)

Und was passiert dann erst einmal? Du hast eine Sammlung von Ziehungen. Da interessiert nur die Farbe oder willst Du da alles erfassen? Was gibt es denn da genau?

Und dann geht man hin und schaut sich sozusagen an, womit man da hantiert:
- Man hat Farben. Also sowas wie enum Color { RED, BLACK, ZERO }.
- Du hast dann Ergebnisse, Würfe, wie auch immer da das eigentliche Wort ist. Das hat eine Farbe und eine Zahl. Also baut man sowas:
public class RouletteResult { private int number; private Color color; ..... }
- Dann brauchst Du eine ErgebnisListe. Da hast Du dann sowas wie eine Queue von Ergebnissen. Da dies vergangene Dinge sind, nennen wir es einfach mal History. Es gibt eine maximale Anzahl von Ergebnissen, die Du speichern willst. Und dann kannst Du da Ergebnisse Hinzufügen: add(RouletteResult). Aber Du kannst auch abfragen, wie viele Würfe ein Ergebnis her ist. int lastResult(Color). - Da gehst Du halt durch die Queue bis Du die angegebene Farbe hast.

Und dann kannst Du die Taktik als Klasse bauen. Und da kannst Du dann einfach ein Array mit Deinen Einsätzen geben. Der Index ist die Anzahl der Würfe bis zu der Farbe:
0 -> Kein Einsatz (0)
1 -> Kein Einsatz (0)
2 -> Kein Einsatz (0)
...
6 -> Kein Einsatz (0)
7 -> 10
8 -> 50
...

Für die Taktik brauchen wir jetzt Wetteinsätze. Dazu müssen wir die erst einmal beschreiben. Wir gehen nur auf Farbe, daher haben wir hier eine Klasse, die nur eine Farbe und einen Einsatz hat.
Damit kann die Taktik nun einfach vorgehen:
Für jede Farbe holt sie sich aus der History die Anzahl der Würfe, die diese Farbe nicht geworfen wurde.
Diese Zahl wird als Index verwendet. Wenn die Zahl größer ist als der Index, dann ist der Einsatz xyz (musst Du festlegen!)
Wenn der ermittelte Einsatz > 0 ist, wird in eine Liste mit Wetteinsätzen ein neuer Wetteinsatz gepackt aus Farbe, Einsatz.

Damit haben wir hier eine einfache Klasse Tactic. Damit diese aber funktionieren kann, braucht diese die History. Also verlangen wir, dass beim Konstruktor diese mit angegeben wird.

Somit haben wir diese Logik schnell und einfach beschrieben.Die lässt sich so schon schnell aufbauen. Und wir haben eine Aufteilung:
- Enum Color
- RouletteResult
- History
- Tactic

Jede Klasse ist für sich nicht wirklich komplex. Jede Klasse ist doch eigentlich so überschaubar, oder?
Grundsätzlich:
Beim Roulette wird die Kugel in den sich drehenden Kessel geworfen.
Sobald es sich ausgedreht hat, liegt die Kugel auf der Gewinnzahl dieser Runde.

Kurzum:
Es wird eine Zahl aus 0-36 gezogen wobei jede Zahl noch eine Farbe haben.
die 0 ist als einzige grün, manche Zahlen sind rot, manche schwarz.
Uns interessieren nur die Farben, die gezogen werden, Zahlenwert ist unwichtig.
(Wobei eine grüne Farbe ja shcon impliziert dass eine Null gezogen wrurde weil die halt einzigartig ist)

Nun kann man vor einer Runde einen beliebigen Einsatz (auch null euro im Online Casino) wählen und auf Alles erdenkliche setzen (auf jede der 37 möglichen zahlen, auf alle geraden zahlen, etc. pp.)

Mich interessiert nur die 3 Möglichkeiten "auf rot, schwarz oder grün setzen".

Kurzum, mich juckt nach einer runde nicht welche konkrete zahl rauskam sondern nur ob sie rot war, schwarz war oder halt die grüne 0 gezogen wurde.

natürlich kann man in einer Runde auch auf mehrere sachen gleichzeitig setzen.

bspw. werde ich, je nach Situation einen Betrag auf rot/schwarz setzen und einen Betrag auf die null.

Zur Grundstrategie:
Aus dubiosen gründen nehme ich an dass eine der farben rot und schwarz nur maximal 16 mal hintereinander kommen kann (die null explizit ausgschlossen hierbei!).

heißt, es kann theoretisch 16 mal rot kommen und die nächste runde MUSS dann schwarz sein.
Natürlich könnte zu jedem Zeitpunkt auch eine Null kommen und den Plan schmeissen.

Strategie ist ganz primitiv eigentlich:
War die letzte gezogene Zahl rot, wird in der folgerunde auf schwarz und null gesetzt, wobei die beiden einsätze nicht gleich sind .
wurde zuletzt schwarz gezogen, wird auf rot und null gesetzt.

Wir setzern halt so lange auf die andere farbe bis wir spätestens in der 17. runde gewinnen.
und um zu verhindern dass wir zwischendurch eine random null kriegen, wird ab einem gewissen punkt ein kleinbetrag auf die null gesetzt.

kurzum, es wird in jeder runde auf eine der 2 farben sowie auf die null mit entsprechenden Beträgen gesetzt.

Die Setztaeblle die mithilfe der Exceltabelle eingelesen wird, gibt an was in welcher Runde gesetzt wird.
Wobei wir die Einsätze für die farbe im Array listOfAllBetStacksForColor
und die für die null im Array listOfAllBetStacksForZero gespeichert haben und von da ablesen wenn nötig.

Langer rede, kurzer sinn: wir drehen so lange leer (nix setzen, nur drehbutton drücken) bis wir 7 mal rot oder 7 mal schwarz hintereinander haben.
ab dann wird gesetzt.
Hierzu wird ntürlich immer gegukt was als letztes gezogen wurde bzw. ich merke mir intern die letzten 16 gezogenen farben.
kann man ja dran ablesen ob 7 mal die selbe farbe kam und Ähnliches.


Insofern wird wie folgt gesetzt:
war die letzte farbserie 1 lang, dann setze 0 auf andere farbe und 0 auf null.
war die letzte farbserie 2 lang, dann setze 0 auf andere farbe und 0 auf null.
.....

war die letzte farbserie 7 lang, dann setze 0 auf andere farbe und 0 auf null.
nachfolgend sind die einsätze wie folgt:

Code:
runde|auf andere Farbe | auf Null

8 0,1    0
9 0,3    0,1
10 0,7    0,1
11 1,5    0,1
12 3,2    0,2
13 6,8    0,4
14 14,4    0,8
15 30,5    1,7
16 64,6    3,6
17 136,8    7,6
(Die Werte oben sind in Euro, werden aber im Programm in Cent umgerechnet)

In Summe hat man 7 runden leergedreht und maximal 10 runden mit einsatz gedreht.
früher oder später muss man da gewinnen, und sei es nur durch den ausreißer die null, die ab runde 9 abgesichert wird.
(Und ja, würde unglücklicherweise genau in Runde 8 eine Null kommen, würde man 10 Cent verlieren. Vertretbares Risiko.)




So in etwa das Ganze.

Um nun bspw. 70 cent auf rot zu setzen, müssen erst 50 und dann 20 cent jeweils ausgewählt und auf das "rot" feld geklickt werden.
Je nachdem wie gerade unten das "Rad" mit den auswählbaren einsätzen gerade steht muss so lange nach rechts oder links gedreht werden bis der jeweils benötigte Einsatz sichtbar und damit anklickbar ist.
also entsprechedn rechts/linkdrehen, auf den 50 cent coinn klicken, auf das rot feld klicken,
rad links/rechts zu 20 cent drehen, auf den 20 cent coin klicken, auf rot, klicken, fertig.
Einsötze sind nun platziert, nun auf den Dreh button unten rechts klicken um das rad zu drehen.

Nach der und der Zeit oben rechts colorpixelsearchen welche farbe die neu gezogene zahl hat.

Dann interne berechnungen, anpassen der lsite der bisher gezogenen sachen, bestimmen ob gewonnen oder verloren wurd,e einsätze für nächste runde anpassen etc. pp.
nächste runde, wieder einsätze platzieren wie oben.


Und da die roulette seite nicht von selbst auftaucht, wir ganz am Anfang chrome mit der rouletteseite aufgemaht, auf der erscheinden loginseite eingeloggt, kurz gewartet. und das spiel kann beginnen.

Achja, es gibt auch noch einen Zeitcheck der im auge behält wie lang man auf der rouletteseite aktiv ist.
Aus Gründen will man nicht länger als 51 Minuten am Stück auf der Seite sein, wobei man aber auch nicht dicht machen will wenn man gerade 5 mal in Reihe verloren hat und noch ein paar Runden machen müsste um das wieder reinzuholen (Also sich bspw gerade in Rudne 14 der Setztabelle befindet und daher schon eingie Euro in der aktuellen Serie investiert hat).

Daher wird dieser Timecheck nur gemacht entweder zu Beginn einer Lerrdrehenrunde.Oder wenn gerade gewonne wurde, also bevor man "aufs Neue sein Glück versucht".

Hierzu wird halt der Timer abgeglichen, ist er über 51 Minuten, wird erst der rowser zugemacht mit alt+f4 oder ähnlichem.
Da aus praktischen Gründen das nächste fenster mit fokus die konsole sein wird, wird die ebenso mit alt+f4 gekillt.
Damit killt sich das Programm dann selbst (strg+c würde es auch tun, ich weiß) und der Spuk ist vorbei. :)
 
Y

yfons123

Gast
es war eig als spaß gemeint :(

scriptable objects sind witziger weise in unity objekte die global sind aber nicht static
deswegen verbiete ich da jegliche änderung
 

KonradN

Super-Moderator
Mitarbeiter
Dann sollte meine erste Beschreibung ja relativ gut passen und für diesen Part brauchst du nur minimale Anpassungen.

Damit hast Du ein Grundgerüst, dass Du erweitern kannst. Du kannst die Setztabelle aus einer Excel Tabelle laden und so ...
 

temi

Top Contributor
Ich blicks mittlerweile nicht mehr, ich höre zwar über "Objektorientiert programmieren!" aber was das nun kopnkret heißen soll, weiß ich nicht.
Schon oft erwähnt (auch in einem deiner Themen): "Entwurfsmuster von Kopf bis Fuß". Lies das und du wirst mehr wissen. Du wirst einsehen, dass man hier im Forum nicht den Inhalt eines ganzen Buches erläutern kann. Hilfreich ist evtl. auch noch "Domain Driven Design" aber, das ist evtl. schon etwas zu viel.
 

Neumi5694

Top Contributor
@berndoa Was überflüssige oder fehlende Imports angeht, würde eine IDE das für dich beim Speichern lösen :), ebenso die fehlenden Klammern usw.. Refactoring (Umbenennen von Variablen z.B.) geht auch einfach von der Hand. Die Autoformater sind normalerweise schon recht gut eingestellt.

Was mit nicht gefällt, ist die LoginLogout Klasse mit den statischen Methoden, die allesamt Objekte des selben Typs verändern.
Meine Meinung dazu hab ich schon gesagt, aber wenn du die Methoden so gruppieren willst .... ok.
Aber ehrlich ... "myGame().getCurrentPlayer().rollDice()" (als Beispiel) wäre doch deutlich sinnvoller als "DiceManager.roll(myGame)" und in DiceManager steht dann "PlayerManager.getCurrentplayer(myGame)". Meinst du nicht?
Das hier tut schon ziemlich weh im Verdauungstrakt:
Java:
einsaetzeposprep(respi);
openBrowser(respi);
loginCheck(respi);

Kapsle aber als nächstes alle Variablen in Realspiel. Setz sie auf private, schreib getter und setter.


Statische Methoden sind durchaus notwendig und sinnvoll, aber außer in wenigen Einzelfällen halt nicht dafür gedacht, den Zustand eines Objekts von außen zu ändern. Das ist NICHT Objektorientierung, hat aber - je nach Fall - auch seine Daseinsberechtigung. Am besten formuliert man immer in Worten aus, wer was womit machen muss, dann kommt man auch zu einem recht brauchbaren Entwurf, wo welche Methoden stehen sollten.
"Der Spieler würfelt" ist halt ganz was anderes als : "Es wird gewürfelt, mit dem Spieler als aktuellem Würfler".
"Die Figur B des aktiven Spielers auf dem Spielbrett 3 Felder weiterbewegt" würde entsprechend nahelegen, auf dem Spielbrett eine (NICHT statische) Bewege-Funktion zu erstellen, mit Parametern, welche Spielfigur wie weit bewegt werden soll. Die Figur weiß, wer ihr Besitzer ist, also brauchen wir den Spieler nicht mit zu übergeben.
Dass vorher gewürfelt wurde und für welche Figur der Spieler sich entschieden hat, hat hingegen mit dem Spielfeld nichts zu tun, sondern mit der Ablauflogik. Das steht also im Code der Klasse mit der Ablauflogik.
Edit: Wichtig: Die Parameter sollten ebenfalls sinnvoll gewählt sein. Anstatt an die Bewege-Methode die Klasse Ablauflogik zu übergeben und die holt sich dann den Spieler, die gewählte Figur und die Anzahl der Felder raus, übergibt man eben nur die Spielfigur und die Anzahl der Felder.
Das heißt nicht, dass ich grundsätzlich was gegen Containerklassen habe. Ein Rechteck kann anhand seiner 4 Parameter oder auch als Rechteckobjekt übergeben, was durchaus sinnvoll ist, da alle 4 Parameter sich auf die selbe Entität beziehen.

@mihe7 Seien wir froh, dass Java einen Mittelweg gegangen ist :) In Smalltalk sind alle Zahlentypen Subklassen von Number (gibt's so auch in Java natürlich) und Operatoren wie "+" werden ersetzt durch Methoden der Klasse Number.
 

berndoa

Top Contributor
Java:
einsaetzeposprep(respi);
openBrowser(respi);
loginCheck(respi);

Kapsle aber als nächstes alle Variablen in Realspiel. Setz sie auf private, schreib getter und setter.
Das kann ich zwar machen, aber die Frage bleibt:
Wie greift ein Objekt einer anderen klasse auf diese Settermethode zu?

Dazu muss dem ja eine Referenz des Realspiel Objekts übergeben werden.

Gut, was mir so einfiele, man könnte halt hingehen und gucken dass Realspiel als Attribut die Objekte der anderen Klassen hat.
sowie umgekehrt in jeder anderen Klasse als Attribut ein Realspielobjekt vorhanden ist.
Müsste dann halt bspw. bei der Erzeugung eines Rundenmanagement Objekts, d.h. konkret beim Aufruf des Konstruktors, einmalig die Objektreferenz der anderen Klasse übergeben werden.

Sinnbildlich so:
Java:
public class Hauptklasse{
    Nebenklasse nebenklassenObjekt;

    public Hauptklasse(){
        nebenklassenObjekt=new Nebenklasse(this);
    }
    
    public void testMethode(){
        /*hier muss halt nicht mehr die Nebenklassenmethode aufgerufen
        und ihr mit this das aktuelle Objekt übergeben werdn weil
        es das halt schon hat*/
        nebenklassenObjekt.testMethode2();
    }


}



Java:
public class Nebenklasse{
    Hauptklasse hauptklassenObjekt;

    public Nebenklasse(Hauptklasse hauptklassenObjekt){
        this.hauptklassenObjekt=hauptklassenObjekt;
    }
    
    public void testMethode2(){
        hauptklassenObjekt.testMethode1();
    }


}

So in etwa.
Nun kennen sich die Objekte der Haupt und Nebenklsse gegenseitig (bzw. besitzen jeweils Referenz auf das Gegenüber) und können sich darüber ansprechen.

Macht das Sinn oder ist das, mal wieder, nur Quatsch?

Um das generelle Objektname.Methonname(...) komme ich damit aber imme rnoch nciht drum herum :-/

Und klar, da sind nicht keine Getter und Setter drin, ich weiß.
 

Neumi5694

Top Contributor
Als erstes solltest du aufhören, von "anderen Klassen" zu reden und anfangen über "andere Objekte" oder "andere Instanzen" zu reden. Das ist schon mal ein großer Schritt in Richtung Verständnis. Eine andere Klasse ist nur ein Ort auf deiner Festplatte, wo ein Muster gespeichert ist. Die Klasse hat keine Bedeutung, außer eine Vorlage zu sein.. Ein anderes Objekt hingegen ist etwas, das im RAM erzeugt wird, ist ein anderes Ding sozusagen. Du kannst zwei Dinge(Instanzen) der selben Klasse haben, die jeder seine eigenen Eigenschaften und Methoden haben, die sich nicht gegenseitig in die Quere kommen. DASS Dinge zu einer bestimmten Klasse gehören, versteht sich von selbst.

"Wie greift ein Objekt einer anderen klasse auf diese Settermethode zu? Dazu muss dem ja eine Referenz des Realspiel Objekts übergeben werden."
Natürlich. Um auf die Eigenschaften eines Objekts zugreifen zu können, muss man das Objekt ja erst mal kennen.

Was du ganz hinten geschrieben hast, geht in die Richtige Richtung, falls deine Nebenklasse Objekte der Klasse Hauptklasse braucht, um zu funktionieren.
Getter und Setter sind auch nur Methoden, das passt schon. Sie dienen dazu, kontrollierten Zugriff auf die Eigenschaften zu erlauben anstatt jedem Dödel zu erlauben, Müll reinzuschreiben. Dadurch kannst du abfangen, dass jemand ungültige Daten übergibt oder womöglich eine Liste oder ein Objekt komplett löscht. Direkter Variablenzugriff ist ein großes Nono. Besser noch als die Klasse zu übergeben und im anderen Objekt auslesen zu lassen, ist das andere Objekt so zu gestalten, dass es nur die Daten braucht, nicht aber das Containerobjekt selbst.

Du willst in einem Textfeld ja nur Text anzeigen und keine Spieler verwalten.

Code:
class Main {
  public static void main(...) {
      new Spielelogik().run();
   }
}

class SpieleLogik {
  Spielbrett brett = ...;
  List<Spieler> spieler = new ArrayList<>();
  public void run() {
      spieler.add(new Spieler());
      meineUI.printSpielername(spieler.get(0).getName()); //anstatt die Spielelogik zu übergeben und eine printMethode dann die Logik auslesen zu lassen, was völliger Unsinn ist. Aber das hast du in einigen deiner statischen Methoden so gemacht.
      ...
    brett.setzeFigur(spieler.getFigur(2), feldIndex);
   }
}

class Spieler {
   String name ...;
}

Dein Hauptfehler besteht darin, dass du dich per copy/paste in ein Projekt gestürzt hast, das weit jenseits deiner aktuellen Fähigkeiten liegt. Du hättest kleiner anfangen und erst mal Grundlagen lernen sollen.
 

Neumi5694

Top Contributor
Ich würde vorschlagen, du jagst das Ganze erst mal zum Teufel und fängst neu an. Nicht mit der Logik, sondern mit einer Klasse namens Spieler. Erstell die mal und gib ihr alle Eigenschaften, die ein Spieler haben kann (spielunabhängig). Die Variablen werden durch getter und setter angesprochen.
Mach nichts weiter als das, es wird kein Ergebnis auf dem Bildschirm geben, das ist nur eine Datenklasse. Mach die mal und poste sie.
 

temi

Top Contributor
DASS Dinge zu einer bestimmten Klasse gehören, versteht sich von selbst.
Ich würde Klassen eher als Typen betrachten. Objekte gehören nicht zu einer Klasse, sondern sind vom Typ der Klasse.

Welche Klassen benötigt werden und welche Aufgaben diese Klassen haben, ist eine andere Sache und vom konkreten Problem abhängig. Dafür gibt es kein Patentrezept, das muss man einfach üben und es gibt dafür auch unterschiedliche Ansätze, z. B. Domain Driven Design.

Es gibt Grundregeln des OOP wie SOLID. Aber das können wir dir hier nicht alles in diesem Thema erläutern. Wie schon oben geschrieben: Damit werden Bücher gefüllt.

Ich persönlich würde dir empfehlen, dich erst mal mit solcher Theorie etwas zu beschäftigen. Dazu gehören SOLID und Entwurfsmuster, glaube mir, das macht sogar Spaß (ich fand es total interessant). Aber es dauert seine Zeit, das fällt nicht vom Himmel. Man wird jedoch am Ende mit schöner Software belohnt. Ja, Software kann sehr schön und elegant sein (leider auch hässlich) und ein schönes Stück Software zu betrachten macht mir Freude.

Mal ne Frage an den Rest hier: Geht das nur mir so, oder bin ich seltsam?
 
Zuletzt bearbeitet:

Neumi5694

Top Contributor
Ich würde Klassen eher als Typen betrachten. Objekte gehören nicht zu einer Klasse, sondern sind vom Typ der Klasse.



Mal ne Frage an den Rest hier: Geht das nur mir so, oder bin ich seltsam?
Stimmt, war zweideutig ausgedrückt (da hat sich etwas Dialekt eingeschlichen). Für den Laien mag da der Sinn ein anderer sein.

Seltsam ... erst mal müsste man definieren, nach welchen Kriterien das definiert wird.

Doch, schöner Code kann schon Freude machen, Außenstehende können damit freilich nichts anfangen (selbst nach der langen Zeit ist die einzige Frage meines Vaters zu meinem Job, ob ich genug Arbeit hätte und das ist mehr, als alle anderen fragen können), aber es schleicht sich schon ein gewisses Zufriedenheitsgefühl ein, wenn man ein Problem elegant und "schön" gelöst hat.
Meine bastelnde und kinderliederschreibende (na gut, eines für den Kindergarten, in dem sie arbeitet) Schwester war ganz erstaunt, als ich bei einem Schnelltest in einer Zeitung als der deutlich kreativere von uns beiden rauskam. Natürlich darf man darauf nicht zu viel geben, aber die meisten unterschätzen, wie wichtig das ist, wenn man mehr als eine Tipse ist und selbst entwickelt. Das Fachwissen ist nur ein Teil des Ganzen. Und ich denke, jeder kreativ Arbeitende kann eine gewisse 'Anmut' im Erstellten durchaus schätzen, sei es im fertigen Produkt (GUI) als auch in seinen Bestandteilen.
 

berndoa

Top Contributor
Ich werde mir vermutlich einfach mal meinen gekauften Udemy Kurs angucken und das Programm jetzt einfach so laufen lassen wie es ist.

Das von Grund auf neu zu schreiben werde ich mir vermutlich in absehbarer Zeit nicht antun;
das Neuschreiben als ich von autohotkey zu java gewechselt bin war damals schon nervig genug.

Und auch mal dieses Buch mit dem "von kopf bis Fuß" angucken, wobei ich eigentlich mehr so der Videotyp bin :)
 

shokwave

Mitglied
Sorry wenn ich mich als Frischling hier meinen Senf dazu gebe. Vielleicht hilft ein konkretes Beispiel.
Deine ExcelReader-Klasse, würde meinem Verständnis nach, was man Dir hier versucht näher zu bringen, so aussehen.
Java:
import java.io.File;
import java.io.IOException;

import org.jopendocument.dom.spreadsheet.SpreadSheet;
import org.jopendocument.dom.spreadsheet.MutableCell;
import org.jopendocument.dom.spreadsheet.Sheet;

//Alles zum Einlesen der Exceldatei
public class ExcelReader {

    private final int[] et = new int[17];
    private final int[] ft = new int[17];

    // Ab hier ODS Kram (Einsätze aus Openoffice Tabelle ablesen)
    ExcelReader(String filename, int leerDrehen) {

        try {
            final File file = new File(filename);
            // Getting the 0th sheet for manipulation| pass sheet name as string
            final Sheet sheet = SpreadSheet.createFromFile(file).getSheet(0);

            // Get row count and column count
            final int nColCount = sheet.getColumnCount();
            final int nRowCount = sheet.getRowCount();

            System.out.println("Rows :" + nRowCount);
            System.out.println("Cols :" + nColCount);

            // Iterating through each row of the selected sheet
            MutableCell<SpreadSheet> cell = null;
            // bei 7 mal leerdrehen
            for (int i = 0; i < leerDrehen; i++) {
                et[i] = 0;
                ft[i] = 0;
            }

            for (int i = leerDrehen; i < 17; i++) {
                cell = sheet.getCellAt(3, i - leerDrehen + 3);
                et[i] = (int) (100 * Double.parseDouble((cell.getValue() + "")));
                cell = sheet.getCellAt(4, i - leerDrehen + 3);
                ft[i] = (int) (100 * Double.parseDouble((cell.getValue() + "")));
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public int[] getET() {
        return et;
    }

    public int[] getFT() {
        return ft;
    }
}

Und der Aufruf in deiner Realspiel-Klasse so:
Java:
    int leerDrehen = 7;
    ExcelReader er = new ExcelReader("C:\\Users\\blablabla\\Exceldateiname.ods", leerDrehen);
    int[] et = er.getET();
    int[] ft = er.getFT();

Damit hättest du nichts statisches mehr, musst das Realspiel nicht übergeben und hast das einlesen schön gekapselt.
Das lässt sich natürlich noch verfeinern. Z.B. weiß ich nicht ob leerDrehen noch woanders eine Rolle spielt. wenn nicht kann es hier mit rein und man spart sich den Parameter.

Vielleicht wird es ja so klarer.
 

berndoa

Top Contributor
Bin nicht sicher, ob es gute Videos zu dem Thema gibt. Die Sprache an sich zu lernen ist nur die halbe Miete. Vermutlich nicht mal die halbe Miete.
Irgendwas mit guten Beispielen zum Thema Clean Code und OOP Kram wird sich hoffentlich darin finden.
Irgendjemand (weiß nicht mehr wer genau) hatte den Kurs jedenfalls empfohlen, weil er recht umfangreich und aber auch rech billig zu haben ist (kostete 18,90 Euro oder so für 35 Stunden Videos)
 
Y

yfons123

Gast
Sorry wenn ich mich als Frischling hier meinen Senf dazu gebe. Vielleicht hilft ein konkretes Beispiel.
Deine ExcelReader-Klasse, würde meinem Verständnis nach, was man Dir hier versucht näher zu bringen, so aussehen.
Java:
import java.io.File;
import java.io.IOException;

import org.jopendocument.dom.spreadsheet.SpreadSheet;
import org.jopendocument.dom.spreadsheet.MutableCell;
import org.jopendocument.dom.spreadsheet.Sheet;

//Alles zum Einlesen der Exceldatei
public class ExcelReader {

    private final int[] et = new int[17];
    private final int[] ft = new int[17];

    // Ab hier ODS Kram (Einsätze aus Openoffice Tabelle ablesen)
    ExcelReader(String filename, int leerDrehen) {

        try {
            final File file = new File(filename);
            // Getting the 0th sheet for manipulation| pass sheet name as string
            final Sheet sheet = SpreadSheet.createFromFile(file).getSheet(0);

            // Get row count and column count
            final int nColCount = sheet.getColumnCount();
            final int nRowCount = sheet.getRowCount();

            System.out.println("Rows :" + nRowCount);
            System.out.println("Cols :" + nColCount);

            // Iterating through each row of the selected sheet
            MutableCell<SpreadSheet> cell = null;
            // bei 7 mal leerdrehen
            for (int i = 0; i < leerDrehen; i++) {
                et[i] = 0;
                ft[i] = 0;
            }

            for (int i = leerDrehen; i < 17; i++) {
                cell = sheet.getCellAt(3, i - leerDrehen + 3);
                et[i] = (int) (100 * Double.parseDouble((cell.getValue() + "")));
                cell = sheet.getCellAt(4, i - leerDrehen + 3);
                ft[i] = (int) (100 * Double.parseDouble((cell.getValue() + "")));
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public int[] getET() {
        return et;
    }

    public int[] getFT() {
        return ft;
    }
}

Und der Aufruf in deiner Realspiel-Klasse so:
Java:
    int leerDrehen = 7;
    ExcelReader er = new ExcelReader("C:\\Users\\blablabla\\Exceldateiname.ods", leerDrehen);
    int[] et = er.getET();
    int[] ft = er.getFT();

Damit hättest du nichts statisches mehr, musst das Realspiel nicht übergeben und hast das einlesen schön gekapselt.
Das lässt sich natürlich noch verfeinern. Z.B. weiß ich nicht ob leerDrehen noch woanders eine Rolle spielt. wenn nicht kann es hier mit rein und man spart sich den Parameter.

Vielleicht wird es ja so klarer.
hier wäre anzunörgeln dass dein konstruktor alles macht eg outprintln, setzen und logik

dies wäre zu trennen
stell dir vor du willst einfach mal keine ausgabe dann musst alles umschreiben
 

KonradN

Super-Moderator
Mitarbeiter
Ja, immer versuchen in Objekten zu denken. Man hat also etwas, das diese Daten hält. Das hatte ich ja in einem Post schon skizziert. Das würde ich separat halten. Sprich: Die beiden Arrays werden gekapselt mit den Daten, die da drin sind und dann wird darauf über Methoden zugegriffen. Dabei wird aber nicht das Array nach außen gegeben - das ist ein internes Implementationsdetail.

Und der Reader wäre dann halt nach üblichen Vorbild ein

Java:
public class WhatEverReader {
    public WhatEverReader (String filename) { ...}
    
    public WhatEver read() { .... }
}

So in der Art halt.

Aber das ist auch schon öfters skizziert und gezeigt worden. Das Model eines solchen Spiels habe ich ja in einem Post einmal etwas aufgebaut.
 

shokwave

Mitglied
Danke für das Feedback. Ihr habt natürlich Recht. Ich wollte nur erst einmal zeigen, dass es nicht so schwierig ist die statischen Variablen Methoden los zu werden und somit etwas OOP hineinzubringen.
Im nächsten Schritt wollte ich dann auf CleanCode eingehen. Was dann, nach meinem bisherigen Verständnis, in etwa so aussehen könnte.
Java:
import java.io.*;
import org.jopendocument.dom.spreadsheet.*;

//Alles zum Einlesen der Exceldatei
public class Configuration {

    private final int[] nextBetsColor = new int[17];
    private final int[] nextBetsZero = new int[17];
    private final int noBets = 7;

    public void readFile(final String filename) {
        try {
            final File file = new File(filename);
            // Getting the 0th sheet for manipulation| pass sheet name as string
            final Sheet sheet = SpreadSheet.createFromFile(file).getSheet(0);


            printTableSize(sheet);
            padArraysWithZeros();
            fillArraysFromFile(sheet);

        } catch (IOException e) {

            e.printStackTrace();
        }
    }

    private void printTableSize(final Sheet sheet) {
        final int numCols = sheet.getColumnCount();
        final int numRows = sheet.getRowCount();

        System.out.println("Rows :" + numRows);
        System.out.println("Cols :" + numCols);
    }

    private void padArraysWithZeros() {
        for (int i = 0; i < noBets; i++) {
            nextBetsColor[i] = 0;
            nextBetsZero[i] = 0;
        }
    }

    private void fillArraysFromFile(final Sheet sheet) {
        MutableCell<SpreadSheet> cell = null;
        for (int i = noBets; i < 17; i++) {
            cell = sheet.getCellAt(3, i - noBets + 3);
            nextBetsColor[i] = (int) (100 * Double.parseDouble((cell.getValue() + "")));
            cell = sheet.getCellAt(4, i - noBets + 3);
            nextBetsZero[i] = (int) (100 * Double.parseDouble((cell.getValue() + "")));
        }
    }

    public int[] getNextBetsColor() {
        return nextBetsColor;
    }

    public int[] getNextBetsZero() {
        return nextBetsZero;
    }
}

Und er ensprechende Aufruf:
Java:
        Configuration configuration = new Configuration();
        configuration.readFile("C:\\Users\\blablabla\\Exceldateiname.ods");
        int[] nextBetsColor = configuration.getNextBetsColor();
        int[] nextBetsZero = configuration.getNextBetsZero();
Wobei das sicher auch noch verbesserungswürdig ist.

Was ich damit zeigen wollte ist, dass man schon beim "Aufruf" sieht, woher die Daten kommen und um was für Daten es sich handelt. Außerdem werden durch die Auslagerung in einzelne Methoden, die meisten Kommentare im Code überflüssig.

Ich hoffe das hilft berndoa ein bisschen weiter.
 
Y

yfons123

Gast
die statischen Variablen Methoden los zu werden und somit etwas OOP hineinzubringen.
manchmal ist es einfach und manchmal endet man weinend in der ecke vom static spaghetti code

Wobei das sicher auch noch verbesserungswürdig ist.
mach halt das printen public und nicht im readfile... wenn jemand das ausgelesen haben will muss derjenige halt die methode aufrufen
 

Neumi5694

Top Contributor
Was auch recht praktisch ist, damit man Exceptions auch wirklich nur dort auswerten muss, wo sie geschen: Optionale Rückgabewerte. Von der Datei kann was eingelesen worden sein oder auch nicht. Falls nicht, dann kann man immer noch im Errorlog nachschauen, was passiert ist anstatt sich in der aufrufenden Klasse damit rumzuschlagen, die will im Normalfall nur wissen, OB was zurückgekommen ist.
Natürlich hat beides seine Vor- und Nachteile, aber man kann ja je nach Situation entscheiden, was gerade sinnvoller wäre.
 

mihe7

Top Contributor
Wir können das Design von @KonradN aus #47 mal aufgreifen, ein wenig ausführen und in Code gießen.

Erstmal die zwei kleinen Hilfstypen:
Java:
public enum Color { GREEN, RED, BLACK }
Java:
public record RouletteResult(Color color) {
    public boolean equalsInColor(RouletteResult result) {
        return color == result.color;
    }
}
Zu Color gibt es nicht viel zu sagen, RouletteResult ist a) ein Record (gibts seit Java 16, bitte nachschlagen, ich habe keine Lust, das an jeder Ecke zu wiederholen) und besteht b) nur aus der Farbe, weil aktuell nicht mehr interessiert. Später könnte der Wert hinzukommen.

Außerdem wollen wir noch die Wette auf eine Farbe darstellen:
Java:
public record Bet(Color color, int cents) {}


Gut, fangen wir an: was ist der Kern der Anwendung? Offensichtlich soll ein Roulette-Roboter entwickelt werden. Was macht der? Im Endeffekt spielt er (bis zu einem gewissen Punkt) Roulette und wendet dabei eine Taktik an. Die Taktik entscheidet, welche "Wetten" in der nächsten Runde abgegeben werden. Wie genau, ist ein Implementierungsdetail, das für den Roulette-Roboter irrelevant ist.

Daher erstmal eine Schnittstelle:
Java:
import java.util.Collection;

/**
 * Von jeder Taktik zu implementierende Schnittstelle.
 */
public interface Tactic {

    /**
     * Liefert die nächsten Einsätze.
     *
     * @return  Liste der nächsten Einsätze.
     */
    Collection<Bet> nextBets();
    
    /**
     * Wendet ein Spielergebnis auf die Taktik an.
     *
     * @param  result  das letzte Spielergebnis.
     */
    void apply(RouletteResult result);
}

Das Roulette ist aus Sicht des Roboters ebenfalls ein Implementierungsdetail: es interessiert nicht, was für ein Roulette es ist, ob es sich um ein lokales oder ein Online-Roulette handelt, ob die Kommunikation wia java.awt.Robot, REST-Services, einem Selenium Web-Driver oder wie auch immer abläuft usw. Was der Roboter braucht, sind ein paar Methoden:
  • Läuft das Spiel noch, oder ist es schon vorbei?
  • Einsätze müssen vom Tisch genommen werden können.
  • Einsätze müssen platziert werden können
  • Die Runde muss gestartet werden können (Rouletterad drehen)
  • Das Ergebnis der letzten Runde muss abgerufen werden können.
Das lässt sich wieder mit einer Schnittstelle spezifizieren:
Java:
/** 
 * Von jedem Roulette zu implementierende Schnittstelle.
 */
public interface Roulette {
    /**
     * Prüft, ob das Spiel beendet ist.
     *
     * Das Spiel ist beendet, wenn keine weiteren Einsätze angenommen 
     * und keine weiteren Runden gespielt werden können.
     *
     * @return {@code true}, falls das Spiel beendet ist, {@code false} sonst.
     */
    boolean isOver();
    
    /**
     * Entfernt alle Einsätze vom Tisch.
     *
     * @throws IllegalStateException     falls das Spiel bereits beendet ist.
     */
    void clearBets();
    
    /**
     * Platziert eine Wette auf eine Farbe.
     *
     * @param bet  Wette.
     *
     * @throws IllegalArgumentException  falls die Wette nicht angenommen wird.
     * @throws IllegalStateException     falls das Spiel bereits beendet ist.
     */
    void betOnColor(Bet bet);
    
    /**
     * Spielt eine Runde, dreht also das Rouletterad und 
     * lässt dabei die Kugel laufen.
     *
     * @throws IllegalStateException  falls das Spiel bereits beendet ist.
     */
    void spinWheel();
    
    /** Liefert das Ergebnis der letzten gespielten Runde. 
      * Mit anderen Worten, wo die Kugel im Roulettekessel der letzten
      * Runde liegen geblieben ist.
      *
      * @return RouletteResult  Ergebnis der letzten Runde.
      * @throws IllegalStateException  falls die Methode aufgerufen wurde,
      *                                bevor das Rad mind. einmal gedreht wurde.
      */  
    RouletteResult getResult();
}

Mehr braucht es für den Roboter nicht, der muss einfach nur wissen, mit welchem konkreten Roulette und welcher Taktik er spielen soll:
Java:
public class RouletteRobot {
    private final Roulette game;
    private final Tactic tactic;
    
    public RouletteRobot(Roulette game, Tactic tactic) {
        this.game = game;
        this.tactic = tactic;
    }
    
    public void play() {
        while (!game.isOver()) {
            game.clearBets();
            for (Bet bet : tactic.nextBets()) {
                game.betOnColor(bet);
            }
            game.spinWheel();
            tactic.apply(game.getResult());
        }
    }
}
Gut, hier sollten Exceptions noch behandelt werden aber im Wesentlichen ist das der Kern der Anwendung. Taktik und das Roulette sind einfach "Add-Ons".

Wo ist die Historie? Nun, die betrachte ich als Teil der Taktik. Eine Zufallstaktik braucht z. B. keine Historie, ebenso wird diese nicht benötigt, wenn nur das letzte Ergebnis interessiert.

Wie könnte nun eine solche Taktik aussehen?
Java:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

public class BerndoaTactic implements Tactic {
    public static record ColorBet(int centsOnColor, int centsOnZero) { }

    private final List<ColorBet> bets;
    private final History history;
    private final int streakLength;

    private int round = 0;
    private boolean initialized;
    
    public BerndoaTactic(List<ColorBet> bets, History history, int streakLength) {
        this.bets = new ArrayList<>(bets);
        this.history = history;
        this.streakLength = streakLength;
    }
    
    @Override
    public Collection<Bet> nextBets() {
        if (!initialized || round >= bets.size()) {
            return Collections.emptyList();
        }

        Color color = determineColor();        
        ColorBet nextBets = bets.get(round);
        round++;
        
        return List.of(
                new Bet(color, nextBets.centsOnColor()),
                new Bet(Color.GREEN, nextBets.centsOnZero()));       
    }
    
    private Color determineColor() {
        RouletteResult lastResult = history.getLastResult();
        return lastResult.color() == Color.RED ? Color.BLACK : Color.RED;
    }
    
    @Override
    public void apply(RouletteResult result) {
        history.add(result);

        if (!initialized) {
            if (history.getStreakLength() >= streakLength) {
                initialized = true;
            }
        }
    }
}

Hier wird also eine Historie benötigt, die nicht wirklich viel macht:
Java:
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Deque;

public class History {
    private final Deque<RouletteResult> results;
    
    public History() {
        results = new LinkedList<>();
    }
    
    public History(Deque<RouletteResult> results) {
        this.results = results;
    }
    
    public void add(RouletteResult result) {
        results.addLast(result);
    }
    
    public RouletteResult getLastResult() {
        return results.getLast();
    }
    
    public int getStreakLength() {
        int len = 0;
        
        if (!results.isEmpty()) {
            RouletteResult result = getLastResult();
        
            Iterator<RouletteResult> it = results.descendingIterator();
            while (it.hasNext() && it.next().equalsInColor(result)) {
                len++;
            }
        }
        
        return len;
    }
}
Der zweite Konstruktor kann zum Laden einer zuvor gespeicherten Historie verwendet werden, tatsächlich dient er aber der Testbarkeit der Klasse.

Die Implementierung des Roulette erspare ich mir. Nur so viel: die Methoden können natürlich beim Aufruf ggf. den Browserstart veranlassen. In isGameOver() lässt sich prüfen, ob die Zeit rum ist, der Browser schließen und true zurückgeben. Auch spare ich mir an der Stelle den ExcelReader.

Die Teile werden einfach z. B. beim Start der Anwendung zusammengefügt:
Java:
public class App {
    public static final void main(String[] arg) {
        List<BerndoaTactic.ColorBet> bets = // ... z. B. einlesen aus Datei
        Tactic tactic = new BerndoaTactic(bets, new History(), 7);
        Roulette roulette = new BerndoaRoulette(...);
        new RouletteRobot(roulette, tactic).play();
    }
}

Willst Du zu einem Casino mit anderer Bedienung wechseln? Einfach neue Roulette-Implementierung schreiben und die verwenden. Bei gleicher Bedienung und anderen Layouts bietet es sich an, die Roulette-Implementierung derart zu gestalten, dass ein Layout übergeben werden kann. Willst Du eine andere Taktik ausprobieren? Kein Problem, einfach Tactic implementieren und verwenden. Willst Du verschiedene Taktiken abwechseln? Auch kein Problem: einfach eine Tactic implementieren, die zwischen bestehenden Taktiken wechselt.

Ach, damit ich es nicht vergesse: der Code soll den Spaß nur skizzieren und ist dementsprechend unvollständig und auch nicht getestet, die Taktikimplementierung dürfte im Großen und Ganzen Deiner Beschreibung entsprechen, musst Du aber ggf. anpassen usw.
 

berndoa

Top Contributor
Also ich weiß nicht, je länger ich so grundsätzlich über das Ganze nachdenke umso mehr denke ich dass ich für das OOP Kram schlicht zu blöd bin :-/

So als Beispiel:
Wenns hieße ich sollte was Objektorientiertes bauen, dann würde ich nach den offensichtlichen physischen Objekten des Spiels gehen
(das was man halt sieht und angreifen kann).
Will sagen, es gibt das Spielfeld.
Das wiederum hat oben rechts einen Bereich, die Ergebnisliste.
In der Mitte den Bereich mit den 200 (oder 37 oder so) Wettfeldern.
Unten die Einsatzknöpfe.
sowie unten rechts halt den bereich mit Drehknopf und Co.

Ergebnisliste oben rechts ist halt ne Liste aus Ergebnisfarben (wenn uns die Zahlenwerte mal nicht interessieren).
Der Bereich in der Mitte ist halt ein Feld, das aus einzelnen Wettfeldern besteht.

Genauso der untere Bereich, der wiederum aus den 2 links/rechts-knöpfen.

So eine Hierarchie an physischen Objekten zu bauen mittels Klassen , das kriege ich noch hin, kein Problem.

Aber da endets auch schon.
Diese Meta/virtuellen Sachen und Klassen wie ein Spieler, Tactic und so, wie kommt man da drauf die so zu machen?

Bei den physischen Sachen kann ich mich ja direkt am Spielfeld orientieren, wie man da was unterteilen würde.
Und das 1 zu 1 in Klassen umsetzen.

Aber diese "Logistik" hinter dem Ganzen, Tactic, Farbmanagement, kurzum die "Theorie" und die interaktionen zwischen dem Spielfeld und dem womöglich einzuführenden Spieler/Tactic in irgendein Klassengeflecht zu bauen, ich checks nicht wie man da so richtig draufkommt.
Ich würds, wie auch anfangs getan, ganz plump Alles in eine Methode einer Hauptklasse packen und der Reihe nach abarbeiten lassen,
Schritt 1, Schritt 2, Verzweigung, etc.

Natürlich mit Aufteilung in Methoden und so um Redundanz zu vermeiden und es beser verständlich zu halten.

Aber wie man das nun in "erfundene" theoretische Klassen wie Tactic (es gibt schließlich kein physisches Tactic Objekt irgendwo) und so gießt, keien Ahnung.

Der Spieler macht noch Sinn, den gibts ja physisch und der klickt physisch auf die Buttons des Spielfelds und liest auch Farbwerte vom Spielfeld ab.

Aber jetzt so rein theoretische Klassen wie Tactic und Co., irgendwie will mir nicht so einleuchten wie man auf diese Aufteilung kommt.

Klar, sowas banales wie am Threadanfang erwähnt, dass man statt der 2 Arrays mit Einsätzen halt eine Einsätzeliste macht, die die nötigen Einsätze bei Anruf mitteilen kann, macht Sinn. Ist ja nur etwas sinnhaft die Sachen zusammengefasst damit das Spielfeld nicht aus Tausenden Einzelelelementen besteht, die man easy gruppieren könnte.

Aber darüber hinaus, ich sehe zwar dass es Sinn macht (auch wenn ich vermutlich nie auf die gezeigten Codes käme mit Records und Co.), abr ich käme weder drauf wie oder warum man jetzt diese Klassen wählt oder warum diese Art der Interaktion.

Ich weiß nicht, irgendwo komme ich nicht so auf die generelle Denkweise wie man auf solchen kram grundsätzlich kommt, wie man den theoretischen Aspekt des Spiels (das Ergebnistracking, Strategie, etc.) in ebenso hypotetische Klassen umsetzt.

Das dann zu programmieren ist nochmal ein Thema für sich, aber rein diese Klassenaufteilung schon zu finden....
 

mihe7

Top Contributor
Wenns hieße ich sollte was Objektorientiertes bauen, dann würde ich nach den offensichtlichen physischen Objekten des Spiels gehen
Das wäre z. B. der Ansatz, wenn Du ein Roulette programmieren wolltest. Hier geht es aber um einen Roulette-Spieler (Roboter), der mit irgendeinem Roulette spielen soll.

Das Roulette hatte ich oben nur als Schnittstelle definiert. Wie Du die Klasse(n) dahinter implementierst, bleibt Dir überlassen. Du kannst also durchaus hergehen und das Online-Roulette mit den von Dir genannten Objekten beschreiben.

Diese Meta/virtuellen Sachen und Klassen wie ein Spieler, Tactic und so, wie kommt man da drauf die so zu machen?
Durch Fokus auf das Wesentliche, Perspektivenwechsel, Abstraktion.

Vermutlich stand für Dich die "Fernsteuerung" des Online-Roulettes im Vordergrund, weil das als größtes Problem erschien (und das ist auch nicht ganz falsch, denn, wenn die nicht funktioniert, dann hilft Dir der Rest auch nichts). Damit bist Du darauf fokussiert.

Wenn Du aber einen Schritt zurückgehst und sagst: "Um die Details kümmere ich mich später, worum gehts eigentlich?" Dann findest Du relativ schnell eine Antwort auf die Frage: es geht nicht darum, ein Roulette zu programmieren, es geht darum, Roulette automatisiert zu spielen.

Wer spielt Roulette? Der Roulette-Roboter (Roulette-Computer oder wie auch immer man das bezeichnen möchte). Der Roulette-Roboter steht also im Fokus der Anwendung, nicht das Roulette.

Wie wird gespielt? Hier wieder: nicht im Klein-Klein verlieren, Details kann man später klären. Jetzt kannst Du natürlich auf die Erfahrungen im Online-Casino zurückgreifen: grundsätzlich setzt der Spieler seine Gebote, dann wird die Runde gestartet, die zu einem Ergebnis führt, die den Spieler interessiert.

Wie sollen die Gebote gesetzt werden? Puh, da gibts viele Möglichkeiten. Gleiches Spiel: das sind Details, die erstmal nicht interessieren müssen, der Roboter muss nur irgendwie an die Gebote kommen. Hier sucht man wieder nach einer geeigneten Abstraktion (Name): ah, die Taktik (oder Strategie).

Und so läuft das, natürlich nicht so glatt/linear wie ich es jetzt beschrieben habe. Man wirft den Entwurf ggf. auch mal komplett über den Haufen.
 

berndoa

Top Contributor
Das wäre z. B. der Ansatz, wenn Du ein Roulette programmieren wolltest. Hier geht es aber um einen Roulette-Spieler (Roboter), der mit irgendeinem Roulette spielen soll.

Das Roulette hatte ich oben nur als Schnittstelle definiert. Wie Du die Klasse(n) dahinter implementierst, bleibt Dir überlassen. Du kannst also durchaus hergehen und das Online-Roulette mit den von Dir genannten Objekten beschreiben.


Durch Fokus auf das Wesentliche, Perspektivenwechsel, Abstraktion.

Vermutlich stand für Dich die "Fernsteuerung" des Online-Roulettes im Vordergrund, weil das als größtes Problem erschien (und das ist auch nicht ganz falsch, denn, wenn die nicht funktioniert, dann hilft Dir der Rest auch nichts). Damit bist Du darauf fokussiert.

Wenn Du aber einen Schritt zurückgehst und sagst: "Um die Details kümmere ich mich später, worum gehts eigentlich?" Dann findest Du relativ schnell eine Antwort auf die Frage: es geht nicht darum, ein Roulette zu programmieren, es geht darum, Roulette automatisiert zu spielen.

Wer spielt Roulette? Der Roulette-Roboter (Roulette-Computer oder wie auch immer man das bezeichnen möchte). Der Roulette-Roboter steht also im Fokus der Anwendung, nicht das Roulette.

Wie wird gespielt? Hier wieder: nicht im Klein-Klein verlieren, Details kann man später klären. Jetzt kannst Du natürlich auf die Erfahrungen im Online-Casino zurückgreifen: grundsätzlich setzt der Spieler seine Gebote, dann wird die Runde gestartet, die zu einem Ergebnis führt, die den Spieler interessiert.

Wie sollen die Gebote gesetzt werden? Puh, da gibts viele Möglichkeiten. Gleiches Spiel: das sind Details, die erstmal nicht interessieren müssen, der Roboter muss nur irgendwie an die Gebote kommen. Hier sucht man wieder nach einer geeigneten Abstraktion (Name): ah, die Taktik (oder Strategie).

Und so läuft das, natürlich nicht so glatt/linear wie ich es jetzt beschrieben habe. Man wirft den Entwurf ggf. auch mal komplett über den Haufen.
Hallo,
klar, für mich ist die ganze Sache eine Sequenz von Aktionen, mit einer großen Endlosschleife drin, die durch die Zeitbedingung irgendwann abrupt abgebrochen wird.

Aktuell benötigte Einsätze ablesen, Einsätze sehen, drehen klicken, warten, Ergebnis ablesen,
Ergebnis verarbeiten, Einsätze darauf basierend für Folgerunde vorbereiten, rinse and repeat.
Und an bestimmten Punkten mal die Zeit checken um ggbfls. abrupt Alles zuzumachen.

Gut, und halt ein wenig einmaliger Vorbereitungskram vor dem Spielbeginn.

Daher hatte ich das im Prinzip so 1 zu 1 auch umgesetzt als Folge von verschiedenen Aktionen und Abläufen.
 

mihe7

Top Contributor
Das ist halt der Unterschied zwischen objektorientierter und prozeduraler Programmierung. Aber vielleicht ist nun wenigstens klar geworden, warum ich in meiner ersten Antwort geschrieben habe "man kann nicht einfach Code nehmen und den objekt-orientiert umschreiben (ja, in gewissen Grenzen geht das natürlich), dazu muss man sich schon mit dem zu lösenden Problem beschäftigen."

Bei der OO geht es darum, ein Modell aus Abstraktionen zu finden, die das Problem möglichst allgemein aber konkret genug beschreiben. Dieses Paradigma passt sehr oft sehr gut. Die Anwendung hier ist für den Einstieg vielleicht auch etwas zu schwer (im Sinne von nicht wirklich greifbar) und die Lösungen ggf. auch schon zu fortgeschritten. Da wäre etwas wie ein Monopoly oder ein Kartenspiel mit entsprechender Aufgabenstellung besser geeignet.
 

berndoa

Top Contributor
Das ist halt der Unterschied zwischen objektorientierter und prozeduraler Programmierung. Aber vielleicht ist nun wenigstens klar geworden, warum ich in meiner ersten Antwort geschrieben habe "man kann nicht einfach Code nehmen und den objekt-orientiert umschreiben (ja, in gewissen Grenzen geht das natürlich), dazu muss man sich schon mit dem zu lösenden Problem beschäftigen."

Bei der OO geht es darum, ein Modell aus Abstraktionen zu finden, die das Problem möglichst allgemein aber konkret genug beschreiben. Dieses Paradigma passt sehr oft sehr gut. Die Anwendung hier ist für den Einstieg vielleicht auch etwas zu schwer (im Sinne von nicht wirklich greifbar) und die Lösungen ggf. auch schon zu fortgeschritten. Da wäre etwas wie ein Monopoly oder ein Kartenspiel mit entsprechender Aufgabenstellung besser geeignet.
Ja, wenn ich mir so Übungen aus der Vorlesung angucke sind die ehr so sehr praktisch orientiert wie:
"Es gibt eine Farm.
Auf der Farm leben viele verschiedene Tiere, manche muhen, singen , tanzen, etc. und untershceiden sich in der Beinanzahl.
Und es gibt einen Bauer, der manche davon melken kann.

Bauen Sie ein passendes Konstrukt unter Nutzung von Klassen, interfaces und Vererbung"

So auf dem level sind da die Aufgaben 🙃

Vielleicht sollte ich eines Tages mal an meinem Baccarat Spielchen weitermachen, das wäre vermutlich einfacher umzusetzen :)
Wobei ich dort mein "Verzweigungsproblem" noch nicht wirklich gelöst bekommen habe.
 

Neumi5694

Top Contributor
Ja, wenn ich mir so Übungen aus der Vorlesung angucke sind die ehr so sehr praktisch orientiert wie:
"Es gibt eine Farm.
Auf der Farm leben viele verschiedene Tiere, manche muhen, singen , tanzen, etc. und untershceiden sich in der Beinanzahl.
Und es gibt einen Bauer, der manche davon melken kann.

Bauen Sie ein passendes Konstrukt unter Nutzung von Klassen, interfaces und Vererbung"

So auf dem level sind da die Aufgaben 🙃

Vielleicht sollte ich eines Tages mal an meinem Baccarat Spielchen weitermachen, das wäre vermutlich einfacher umzusetzen :)
Wobei ich dort mein "Verzweigungsproblem" noch nicht wirklich gelöst bekommen habe.
Naja, diese Hühneraufgaben sind für objektorientiertes Denken besser geeignet als Baccarat.
Meine Java-Einführung damals (programmiert hatte ich schon lange vorher) nannte sich "modulare Textverarbeitung".
Man sollte Stationen bauen, die einen bestimmten Eingangstyp erwarteten, was machten und einen bestimmten Typ weitergaben.
Das Ganze wurde dann schrittweise weiter aufgebaut. Letzten Endes hatten wir eine UI (damals noch in AWT, Swing gab's noch nicht), in die per Mausklick Stationen gesetzt und per Drag&Drop verschoben werden konnten.
Die Ausgänge von Stationen konnten per Maus mit den Eingängen anderer verbunden werden. Stationen ohne Typ wie der Zähler bekamen so auch einen Typ zugewiesen.
Es gab da also z.B. die Station Textgenerator. Diese konnte entweder direkt Text weiterliefern oder z.B. als Text den Namen einer Datei an den Filereader(Processor) weiterleiten, der die Datei dann auslas und als Text weitergab. Dann gab's da einen Wort-Splitter, der Eingangstexte in Worte splittete, einen, der Zeichenfilter oder eine Station, die aus Texten Buchstaben machte und Zähler, die die Anzahl an durchlaufenden Elementen mitschrieb und anzeigte. Die Elemente wurden dann hinten wieder weitergeleitet.
Es war auch möglich, an einen Ausgang mehrere Eingänge zu hängen. Auch gab's Stationen mit mehreren Eingängen, aber ich kann mich nicht mehr erinnern, wozu die da waren ... das waren vielleicht die Filter.
Das Ganze dann noch mit mehreren Threads. Jede Station hatte ihren eigenen Thread, der pausierte, bis es ein Eingangssignal gab. Die "Leitungen" zwischen den Stationen sollten auch immer farblich hervorgehoben werden, wenn was durchgeschickt wurde.

Man hat hier also eine art GUI für eine einfache Programmiersprache geschrieben. Das Ganze hat nur bedingt mit Objektorientierung zu tun, aber Begriffe wie Vererbung und Interfaces wurden einem so nahegelegt, aber die Grundsteine sind gelegt, mit den 3 verschiedenen Grundtypen von Stationen (Generator, Processor, Consumer), den Ableitungen davon usw. Es ging davon abgesehen auch z.B. um das Vermeiden endlos langen Spaghetticodes (Nutzen der übergeordneten Klassen für gemeinsamen Code) das Einsetzen von Multithreading, so was war damals noch relativ neu und wenn man streng prozedurales Programmieren gewohnt war, hatte man vielleicht noch nicht viel Bezug dazu.

So was wie Baccarat wird dir dabei helfen, Algorithmen zu entwickeln, aber nicht im Bezug auf Objektorientierung. Dafür sind die Hühneraufgaben besser.
 
Zuletzt bearbeitet:

Neumi5694

Top Contributor
ich weis ja nicht ob ein gewisser jemand ihm das schon mal gesagt hat
Ich gehe davon aus, dass das schon einige gemacht haben :)
Aber er kommt ja immer wieder darauf zurück und sagt trotzdem, er würde gerne objektorientiert programmieren. Dann sollte er sich halt eben an den langweiligen Scheiß in der Schule halten, auch wenn dabei kein "Ergebnis" rauskommt, das er bewundern kann.
 

KonradN

Super-Moderator
Mitarbeiter
Es ist doch alles mehrfach gesagt worden. Alles, was wir sagen wurde aber doch bisher massiv abgelehnt. Anregungen zu einem Vorgehen wurden nicht weiter verfolgt. Ich wüsste nicht, was ständiges wiederholen bringen sollte.
 

temi

Top Contributor
Also ich weiß nicht, je länger ich so grundsätzlich über das Ganze nachdenke umso mehr denke ich dass ich für das OOP Kram schlicht zu blöd bin
Das würde ich jetzt so nicht sagen. Es erfordert zunächst Verständnis für die Sache. Ich selbst habe z. B. auch einige Zeit gebraucht, bis ich seinerzeit verstanden hatte, warum Interfaces sinnvoll sind. Nachdem man es verstanden hat, muss man halt noch üben, um damit umgehen zu können. Das ist so, wie in jedem anderen Handwerk auch.

Insofern, hast du genügend Tipps für Literatur erhalten, um dir die Grundlagen beizubringen und danach in Projekten umzusetzen. Das wird dann mit der Zeit immer besser gelingen.

Und damit ist jetzt auch von meiner Seite alles gesagt.
 

berndoa

Top Contributor
Ich selbst habe z. B. auch einige Zeit gebraucht, bis ich seinerzeit verstanden hatte, warum Interfaces sinnvoll sind.
DAS sehe ich tatsächlich auch nicht im Geringsten ozu die gut sein sollten.
Vererbung? Klar, spart man sich Schreibarbeit weil man die Methode nicht überall reinschreiben muss.
Und man kann sich sicher sein dass jede Ente quaken kann wenn Jede von der Quakklasse erbt.

Aber Interfaces? Klingt für mich primär nach "wir machen ein paar Vorgaben, nur keien Ahnung für wen".
Weil faktisch imp,ementiert das Interface keinen Code.
Es schreibt nur vor "Wenn deine Klasse das Interface implementiert, dann muss es die Methoden a,b,c haben".

Ob jetzt eine Klasse ein interface implementiert oder nicht, macht keinen Unterschied.
Die "erzwungene" Methode muss man so oder so komplett hinshcreiben in der Klasse.

Und wenn man sich selbst einen Reminder machen will "Yo, bei der Klasse will/musss ich noch eine quack() Methode reinbauen", da tuts auch ein kommentar drüber.

Oder als Info für Andere, die später am Code rumpfuschen obwohl ihre Griffel da nix zu suchen haben?
Gut, sie wissen, weil dienKlase das interface implementiert, muss eine Quack Methode drin sein.

Wo man sich dann aber fragt warum man dann nicht einfach statt eines Interfaces eine Oberklasse baut, von der geerbt wird?
Hat man wie erwähnt Code gespart, so macht man nix gut.


Ist wie wenn ein Chef für hunderte Euro eine Werbefläche bucht um ein "hier wird nicht geraucht" mitzuteilen, wo es eine kostenlose Rundmail im Firmennetz auch tun würde.

Was davon hat keiner, eine "Raucherlounge" gibt es mit oder ohne das nicht.

Es wurde nur auf umständlichem Weg eine Regel/Vorshrift mitgeteilt.

In meinen Augen machen Interfaces nur Vorschriften, an wen gerichtet kann man debattieren, aber
eine praktischen Nutzen brignen sie nicht.


Ausser dass man halt überall dort eine ein interface implementierende klasse benutzen kann wo das interface erwartet wird.
gut, aber den Aufwand nicht wert, vermutlich
 

Neumi5694

Top Contributor
Nö, Interfaces sind schon cool.
Bestes Beispiel sind Listen und allgemein Collections.
Eine LinkedList funktioniert vollkommen anders als z.B. eine ArrayList, aber extern kann man auf mit den gleichen Zugriffsmethoden zugreifen, wenn einem egal ist, wie es intern funktioniert.

Wenn du ein for(var e : collection) {...} programmierst, kann dir egal sein, um welche Art von Liste, Set oder was weiß ich was handelt. Wichtig ist nur, dass das, was da steht, iterierbar ist, also das Interface Iterable implementiert.

Ich hab einen Renderer für Objekte, die ein "HasName" Interface implementieren, also eine Methode getName() bieteten. Es ist vollkommen egal, welches Objekt dahintersteht, ich weiß mit Sicherheit, dass diese Methode vorkommt und kann diesem Renderer jedes Objekt zuweisen, das dieses Interface implementiert.

Interfaces machen deinen Code erst vielseitig. Vorher hast du nur spezialisierte Methoden und ziemlich viel Hack.


Es geht nicht darum, dass du die Methode hinschreiben musst, sondern dass jemand, der von außen zugreift, sich darauf verlassen kann, dass diese Methode da ist, auch wenn er deine Klasse gar nicht kennt.

Es ist den Aufwand absolut wert, stell dir mal vor, du müsstes für jede Klasse (mehrere hundert Klassen sind keine Seltenheit, aktuell hat mein Projekt über 1000 Java-Dateien, da sind interne und anonyme Klassen noch nicht mitgezählt) eigene Handler schreiben, anstatt die gemeinsamen Methoden des Interfaces zu nutzen.

Vieles wäre ohne Interfaces gar nicht möglich. Du kennst doch sicher den MouseListener. Dieses Interface muss implementiert werden, damit die Klasse verwendet werden kann, um auf MouseEvents zu reagieren. Die Java-Runtime kennt deine Klasse nicht, aber sie weiß, dass diese Methoden vorhanden sind. Und jetzt nehmen wir noch einen MouseMotionListener hinzu.
Implementiert deine Klasse beide Interfaces, kann sie sowohl für Klickevents als auch für Bewegungsevents genutzt werden.
Das wäre mit Ableitungen alleine nicht möglich, da du nur von einer Klasse ableigen kannst. Sie muss die Interfaces implementieren.
Wie wär's mit Keyboard-Eingaben? Einfach das Interface implementieren.
 
Zuletzt bearbeitet:

mihe7

Top Contributor
Aber Interfaces? Klingt für mich primär nach "wir machen ein paar Vorgaben, nur keien Ahnung für wen".
Weil faktisch imp,ementiert das Interface keinen Code.
Es schreibt nur vor "Wenn deine Klasse das Interface implementiert, dann muss es die Methoden a,b,c haben".
Völlig richtig. Etwas genauer: ein Interface spezifiziert die Methoden inkl. der Vor- und Nachbedingungen (der Vollständigkeit halber sei noch die Klasseninvariante erwähnt, die aus Gründen der Vereinfachung weglasse), wobei das in Java und vielen anderen Sprachen z. T. nur über die Dokumentation möglich ist.

Ein Interface ist bildlich gesprochen ein Vertrag zwischen zwei Vertragspartnern: erfüllt der Aufrufer die Vorbedingungen, hat die Implementierung die Nachbedingung zu erfüllen.

Was bringt das? Entkopplung. Der oben gezeigte RouletteRobot ist völlig unabhängig von Roulette- oder Taktik-Implementierungen.

Du kannst beliebige Roulette-Spiele und Taktiken implementieren und mit dem Roboter verwenden, ohne auch nur eine Zeile im RouletteRobot ändern, hinzufügen oder entfernen zu müssen. Das bedeutet auch, dass man Entscheidungen in die Zukunft schieben kann.

Plugins: sind nichts anderes als Implementierungen eines Interfaces.

Im realen Leben sind wir von Interfaces umgeben: jeder elektr(on)ische Anschluss (Steckdose, Audio, USB, Bluetooth), der Ein-/Ausschalter an Geräten, die Fernbedienung -> nichts anderes als Interfaces.

Nehmen wir Geräte, die sich ein- und ausschalten lassen. Alles, was Du wissen musst: ich kann das Ding ein- und ausschalten. Was intern alles passiert (die Implementierung) braucht Dich nicht zu interessieren.

Beispiel:
Java:
public interface Switchable {
    public void switchOn();
    public void switchOff();
}

Jetzt kannst Du z. B. eine Steuerung bauen, die nach Zeit etwas (ein Switchable) ein- und ausschaltet. Die Steuerung muss nicht wissen, was das Ding intern beim Schalten macht, es muss nicht mal interessieren, worum was es sich genau handelt.

Ob Du also an die Steuerung ein Casino, TV-Gerät oder ein AKW hängst: alles kein Problem.
 

DefconDev

Bekanntes Mitglied
Also ich habe im Prinzip keinen Plan, wie man laut euch euren Clean Code und eure OOP machen soll.
Es ist ja schon in 8 Klassen verteilt, teilweise auch in mehr wenn mans drauf anlegt.
Und ohne die this Verweise sehe ich nicht, wie das funktionieren soll.

yep, von IDE, maven und Co. halte ich nicht viel, notepad++ und konsole tut eigentlich was es soll.
Wozu einem die Uni nötigt, so einen Quark zu benutzen wo man erst mal 20 einstellungen machen muss bevor man eine klasse bauen kann...
keine Ahnung.

Warum ich es mir antue?
Weil ich offensichtlich programmieren will (teilweise wohl auch muss) und mir nicht noch mehr Probleme antun will als die die mir der Kompiler schon zum Lösen entgegen wirft.
Da will ich mich doch nicht in eine IDe und Kram noch einarbeiten müssen den ich eh nur benutzen werde weil die dolle Uni es so will.

Braucht man doch keine IDE dazu, jeder Depp, weiß wie man das Grundgerüst einer Klasse schreibt mit Attributen, (optionaler) Main Methode und (optionalen) Konstruktoren sowie Methoden.

Brauche ich keine IDE, der ich 20 Sachen einstellen muss für jede Kleinigkeit.


geht einem dann halt masslos auf den Sack wenn man nach einer simplen Lösung für bspw. das Schwarzweiss Einlesen eines simplen Zeichens sucht und die google Vorschläge dann anfangen von wegen, man solle eclipse, maven und rotz installieren und die ersten 20 Schritte sich nur drum drehen, irgendeinen Msit in den unnötigen Programmen einzustellen, irgendwelche dependencies und respirotires einzurichten, etc.

Würde meinen geilen Arsch verwetten, dass das auch in stinknormalem Java geht, also wozu sich mit unnötigem Extrraprogrammen rumärgern?

Ausser Leuten heir im Forum sit mir im Übrigen noch keiner begegnet, der auch nur einen Fick auf den "Styleguide" gegeben hat.
Da juckte es bisher keinen ob der Hund nun groß oder klein oder sonstwie geschrieben wurde.

steht es so da, ist es ein Attribut.
Ist ne Klammer dahinter (), ist es ne Methode.
Simple Merkregel.

Genauso nervig wie die Masterhacker Nerds, die meinen man müsste ihr meises Linux, Unix und Whatnix benutzen wo man für jeden Dreck einen Konsolenbefehl braucht.
Du kannst dich glücklich schätzen, dass hier die User sehr geduldig scheinen. Ich könnte auf 10 Seiten deinen ganzen Post grob auseinander nehmen mit dem Verweis was für ein Bullshit im nahezu jedem Satz steht.

Du überzeugt nicht nur durch Unwissenheit sondern glänzt auch noch mit Überheblichkeit. Wenn du programmieren musst, dann darf sich später jeder Entwickler freuen dir nicht über den Weg zu laufen, weil du überall nach dem Studium landen wirst aber sicherlich nicht in der Softwareentwicklung.

Zurück zu deinem Code: hat jemand schon Magic Numbers ins Feld geführt? Da sind auch schon etliche vorzufinden.
 
Y

yfons123

Gast
hat jemand schon Magic Numbers ins Feld geführt?
bist leider schon zu spät ... den zug hast du verpasst :D

Java:
                x=570;y=675;
                break;
              
            case "rechtsdreh":
                x=950;y=675;
                break;

            case "eins0":
                x=630;y=675;
                break;
              
            case "eins1":
                x=695;y=675;
                break;

            case "eins2":
                x=760;y=675;
                break;

            case "eins3":
                x=825;y=675;
                break;
              
            case "eins4":
                x=890;y=675;
                break;
ich möchte nicht die arme sau sein die alles umändern darf wenn man 676 braucht und nicht mehr 675
 

berndoa

Top Contributor
Du kannst dich glücklich schätzen, dass hier die User sehr geduldig scheinen. Ich könnte auf 10 Seiten deinen ganzen Post grob auseinander nehmen mit dem Verweis was für ein Bullshit im nahezu jedem Satz steht.

Du überzeugt nicht nur durch Unwissenheit sondern glänzt auch noch mit Überheblichkeit. Wenn du programmieren musst, dann darf sich später jeder Entwickler freuen dir nicht über den Weg zu laufen, weil du überall nach dem Studium landen wirst aber sicherlich nicht in der Softwareentwicklung.

Zurück zu deinem Code: hat jemand schon Magic Numbers ins Feld geführt? Da sind auch schon etliche vorzufinden.
Tu dir keine Zwang an :-D

Ich hasse nur IDEs, Mavens und anderen unnötigen Müll, ohne den ein Programm genauso gut läuft.
Und man beim Umziehen auf anderen Computer nicht 20 programme nachinstallieren muss nurum ein simples java Programm zu kompilieren und auszuführen.

Un die Sinnhaftigkeit von Interfaces, ausser dass man sich selbst eine "Nach 18 Uhr wird nichts mehr gefressen" Regel mittels Zeituhrschloss am Kühlschrank erzwingt, statt sich einfach im Hinterkopf dran zu halten,
will mir nicht so recht erscheinen.
Wobei man bei einem Zahlenschloss wenigstens eine spürbare Veränderung hat.
Bei Implementieren von interfaces hat man sich keine einzige Zeile Code erspart, shcrieben muss man die ganzen Attribute und MEthoden doch genauso wie ohne Implementieren.
 

berndoa

Top Contributor
bist leider schon zu spät ... den zug hast du verpasst :D

Java:
                x=570;y=675;
                break;
             
            case "rechtsdreh":
                x=950;y=675;
                break;

            case "eins0":
                x=630;y=675;
                break;
             
            case "eins1":
                x=695;y=675;
                break;

            case "eins2":
                x=760;y=675;
                break;

            case "eins3":
                x=825;y=675;
                break;
             
            case "eins4":
                x=890;y=675;
                break;
ich möchte nicht die arme sau sein die alles umändern darf wenn man 676 braucht und nicht mehr 675
Oh my, an ganzen 5 Stellen kommt die selbe Zahl vor, weil die buttons zufällig in der selben Zeile liegen :-D
 

Neumi5694

Top Contributor
Tu dir keine Zwang an :-D

Ich hasse nur IDEs, Mavens und anderen unnötigen Müll, ohne den ein Programm genauso gut läuft.
Und man beim Umziehen auf anderen Computer nicht 20 programme nachinstallieren muss nurum ein simples java Programm zu kompilieren und auszuführen.

Un die Sinnhaftigkeit von Interfaces, ausser dass man sich selbst eine "Nach 18 Uhr wird nichts mehr gefressen" Regel mittels Zeituhrschloss am Kühlschrank erzwingt, statt sich einfach im Hinterkopf dran zu halten,
will mir nicht so recht erscheinen.
Wobei man bei einem Zahlenschloss wenigstens eine spürbare Veränderung hat.
Bei Implementieren von interfaces hat man sich keine einzige Zeile Code erspart, shcrieben muss man die ganzen Attribute und MEthoden doch genauso wie ohne Implementieren.
Für ein 'simples' Javaprogramm reicht Notepad. Für ein gut designtes Java-Programm solltest du zu einer IDE greifen.
Kompilieren lässt sich das Ganze auf dem neuen Computer auch ohne, die IDE hilft dir weder beim Kompilieren noch beim Ausführen. Sie hilft dir beim Design und beim Code.

Noch ein praktisches Beispiel zum Interfaces, das die Sinnhaftigkeit hoffentlich endgültig beschreibt: Wie hast du denn deinen Computer angeschlossen? Hast du im Handbuch nachgeschaut, welche Drähte wohin gehören und bei der Stadtverwaltung nachgefragt, wie man an die Stromleitungen kommt? Hast du dann die Spannung nachgemessen, Wandler eingebaut und die Leitungen verlötet?
Oder hast du einfach deinen Schuko-Stecker an das 230V/50Hz Stromnetz angeschlossen?
Das ist ein Interface. Es ist eine Vorgabe, auf deren Umsetzung du dich verlassen kannst. Du musst zum Anschließen deinen Stromanbieter und den Aufbau seines Firmengebäudes, den Familienstand der Reinigungskräfte nicht kennen, dir reicht zu wissen, dass das eine Steckdose dem gültigen Standard entspricht.

Den Code sparst du nicht beim Implementieren von Interfaces, sondern beim Verwenden der implementierenden Klasse. Und um's Code sparen geht's auch gar nicht. Lies dir meine Beispiele oben nochmal durch. Wie sollte denn ein Mouselistener ohne Interface umsetzbar sein?

Hör endlich mal auf dich querzustellen und probier die Tips einfach mal aus ... oder hör auf Fragen zu stellen, wenn du die Antworten eh nicht annimmst.
 

KonradN

Super-Moderator
Mitarbeiter
Ich hasse nur IDEs, Mavens und anderen unnötigen Müll, ohne den ein Programm genauso gut läuft.
Und man beim Umziehen auf anderen Computer nicht 20 programme nachinstallieren muss nurum ein simples java Programm zu kompilieren und auszuführen.
Sorry, aber wenn man einfach keine Ahnung hat, dann sollte man einfach seine Schnauze halten. Ist Dir das denn nicht peinlich?

Aber Du setzt Dich ja mit nichts auseinander und hast dann ohne auch nur das geringste Wissen eine extrem große Meinung. Dunning-Kruger vom feinsten!

Für die Übersetzung meiner Maven Projekte brauchst Du ausschließlich Java. Sonst nichts. Du musst noch nicht einmal Maven installieren. Wenn man den Maven Wrapper nicht nutzt, dann wäre als zweites Tool Maven zu installieren. Und das war es dann! Daher ist so eine Aussage wie von Dir extrem unverständlich.

Und wenn man ein absoluter Anfänger ist, dann muss man sich auch gar keine Gedanken machen - dann installiert man einfach nur IntelliJ. Also genau ein Programm. Und der Rest kommt von alleine über die sehr gute Fehleranalyse bzw. Führung bei der Erstellung eines Projektes. (Geht bei anderen IDEs auch, wobei das bei Eclipse weniger Anfängerfreundlich ist und bei NetBeans weiss ich es nicht)

Aber an der Stelle verabschiede ich mich von Dir, denn diese Threads von Dir führen zu absolut nichts und daher gratuliere ich Dir herzlich, es auf die Ignore Liste geschafft zu haben.
 

temi

Top Contributor
Mein letzter Tipp an dich: JetBrains (die Entwickler von IntelliJ) arbeiten derzeit an einer neuen und schlanken IDE namens Fleet. Bis die erscheint, kannst du dich intensiv mit der Theorie beschäftigen. Buchtipps dazu wurden dir schon gegeben.

Ansonsten, kann ich nur zustimmen.
hör auf Fragen zu stellen, wenn du die Antworten eh nicht annimmst
 

KonradN

Super-Moderator
Mitarbeiter
unangebracht

wenn dir der thread nicht passt dann antworte nicht darauf
Wenn Du seine Threads etwas verfolgt hast, dann würdest Du wissen, dass ich regelmäßig versucht habe, hilfreiche Antworten zu schreiben. Ich habe garantiert nicht wenig Zeit damit zugebracht. Und seine Reaktionen und Antworten solltest Du dann auch kennen.

Und diese Aussage von Dir ist schlicht dumm:
a) Wenn Du meinen Post bis zum Ende gelesen hättest, dann wüsstest Du, dass diese Aussage schlicht unnötig ist: Ich habe ihn auf ignore gesetzt und somit werde ich nicht weiter Zeit mit seinen Posts verbringen.
b) Könnte ich jetzt das gleiche schreiben: Wenn Dir mein Post nicht passt, dann antworte nicht darauf.
 

Meniskusschaden

Top Contributor
Ich hasse nur IDEs, Mavens und anderen unnötigen Müll, ohne den ein Programm genauso gut läuft.
Und man beim Umziehen auf anderen Computer nicht 20 programme nachinstallieren muss nurum ein simples java Programm zu kompilieren und auszuführen.

Un die Sinnhaftigkeit von Interfaces, ausser dass man sich selbst eine "Nach 18 Uhr wird nichts mehr gefressen" Regel mittels Zeituhrschloss am Kühlschrank erzwingt, statt sich einfach im Hinterkopf dran zu halten,
will mir nicht so recht erscheinen.
Dein Ärger darüber bringt doch nichts. Jedes Problem ist eine Chance. Nutze sie zu deinem Vorteil und vereinbare mit deinem zukünftigen Arbeitgeber schon im Vorfeld, dass du mit notepad entwickelst. Der ist ja auch an höchstmöglicher Entwicklerproduktivität interessiert. Wenn du als Einziger im Team diesen unnützen Kram nicht mitschleppen musst, wirst du dort bald der produktivste Entwickler sein und kannst eine entsprechende Vergütung verlangen.

Oder du machst dich gleich selbständig. Aus deiner hohen Produktivität ergibt sich ja ein Wettbewerbsvorteil, mit dem du Konkurrenten leicht aus dem Feld schlagen kannst.

An der Uni würde ich an deiner Stelle das Gespräch mit den Professoren suchen und ihnen klar machen, dass sie falsch liegen. Man ist da doch konstruktiven Sachargumenten gegenüber meist sehr aufgeschlossen, so dass sie ihren Irrtum bald einsehen und diese Fehlentwicklung beenden werden.

Für private Projekte musst du ja sowieso nichts davon nutzen.
 
Y

yfons123

Gast
Un die Sinnhaftigkeit von Interfaces, ausser dass man sich selbst eine "Nach 18 Uhr wird nichts mehr gefressen" Regel mittels Zeituhrschloss am Kühlschrank erzwingt, statt sich einfach im Hinterkopf dran zu halten,
schau dir mal functional interfaces an und default methoden ( die ansich mehrfach vererbung in java möglich machen )
 

httpdigest

Top Contributor
Am Ende des Tages ist nur eine Sache relevant: "Entweder du kennst Techologie/Methode/Technik/Framework/Tool XYZ, oder du kennst XYZ nicht."
Du kannst dich jetzt fragen, welche Antwort auf diese Frage die bessere ist.
Das einzige, was festgefahrene Meinungen, Gefühle, Befürchtungen und Vorurteile tun, ist, dich am Lernen zu hindern.
Also: Sei immer offen für alles.
 

AndiE

Top Contributor
Für ein 'simples' Javaprogramm reicht Notepad. Für ein gut designtes Java-Programm solltest du zu einer IDE greifen.
Kompilieren lässt sich das Ganze auf dem neuen Computer auch ohne, die IDE hilft dir weder beim Kompilieren noch beim Ausführen. Sie hilft dir beim Design und beim Code.
Ich halte es für kaum machbar, ein Programm ohne IDE zu entwickeln. Ich finde, dass man gerade Laufzeitfehler nicht findet, ohne Debugger. Damit kann ich Breakpoints setzen, Variablen auslesen, und den Code schrittweise ablaufen lassen. Auch wenn ich Code von anderen sehe, hilft mir das, den zu verstehen.
Ich nutze selbst Geany als IDE für Python auf dem RaspberryPI, obwohl es da "nur" die Dateiverwaltung und die Verwaltung der Erstellung gibt.

Ich würde dem TE vorschlagen, dass er man "einfache Anfängerprogramme" wie eine Adressverwaltung mit einer CRUD-Funktionalität erstellt, oder mal selbst eine Roulette-Anwendung, oder nur ein Kniffel-Spiel.

Wenn ich denke, was ich an Geld und Zeit investiert habe, um OOP zu verstehen, gerade vor dem Zeitalter des Internets, dann kann ich @KonradN mitfühlen, auch wenn ich es nicht so drastisch ausdrücken würde.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Queenman Interface Mein Microsoft Visual Studio Code zeigt komische Dinge & Menüs an Allgemeine Java-Themen 9
Tiago1234 Warum hängt sich mein Programm auf? Allgemeine Java-Themen 22
J Mein Frame friert ein beim Uploaden Allgemeine Java-Themen 4
Drachenbauer Wie sorge ich dafür, dass mein Spiel die ini-Datei in der Resourcen-ordner des Projektes schreibt? Allgemeine Java-Themen 5
I File ausführen und mein Programm bearbeiten lassen Allgemeine Java-Themen 11
M Brainstorming für mein Projekt Allgemeine Java-Themen 30
R Wo ist mein Fehler in der Methode DRINGEND Allgemeine Java-Themen 9
R Wo ist mein Fehler in diesem Code Allgemeine Java-Themen 7
M Suche aktuelle Apache Poi Bibliothek zum Einbinden in mein Programm Allgemeine Java-Themen 2
T log4j2 Wo liegt mein Logfile? Allgemeine Java-Themen 3
Thallius Warum läst mein replace die Klammern drin? Allgemeine Java-Themen 10
O Mein JButton Array funktioniert nicht Allgemeine Java-Themen 3
C Durch klicken von Button in GUI wird leeres Fenster geöffnet und nicht mein Spiel "Memory" Allgemeine Java-Themen 13
G Mein PDF Projekt mit iText Allgemeine Java-Themen 2
K Was ist mein Fehler? Allgemeine Java-Themen 2
itwestnet Mein Java-Programm läuft nicht in China Allgemeine Java-Themen 4
Thallius App-Sprache in der App ändern. Wo ist mein Denkfehler? Allgemeine Java-Themen 6
M Mein erstes TicTacToe :-) Allgemeine Java-Themen 3
A Applet Mein Applet verursacht Browserabsturz Allgemeine Java-Themen 8
Ollek MVC - Anwendung auf mein Projekt Allgemeine Java-Themen 18
K Wo ist mein Fehler? Allgemeine Java-Themen 21
J Mein eigener Messenger und dessen Probleme Allgemeine Java-Themen 48
C Hilfe! Mein Java mag nich mehr ganz... Allgemeine Java-Themen 11
F VideoIntro für mein Programm Allgemeine Java-Themen 2
A Wie lasse ich mein Programm als Daemon laufen? Allgemeine Java-Themen 4
A Wie liefere ich mein Java-Programm richtig aus? Allgemeine Java-Themen 10
G Entscheidungsproblem für mein Vorhaben, zwischen Java und C# Allgemeine Java-Themen 35
G Wie kann ich in mein Programm eine Updatefunktion einbauen Allgemeine Java-Themen 3
E Wie bekomme ich mein Image in das Fenster Allgemeine Java-Themen 2
V Beratung zum Bestimmen der "Mittel"(Java,Sql) mein Allgemeine Java-Themen 3
S mit welchem befehl kann ich mein programm autom. schließen Allgemeine Java-Themen 3
R Mein Applet läuft in der IDE aber nicht. Allgemeine Java-Themen 2
M Bitte Testen: Mein Multi-File Editor Allgemeine Java-Themen 30
B Fehler:Mein Applet kann nicht auf zwei txt-Dateien zugreifen Allgemeine Java-Themen 2
C Warum wartet mein thread nicht? Allgemeine Java-Themen 2
F Datei auslesen - wo ist mein Fehler? Allgemeine Java-Themen 9
T läuft mein Programm schon? - wie feststellen Allgemeine Java-Themen 6
T Warum mein such-tool schneller als Windows such-tool? Allgemeine Java-Themen 5
A Wie mach ich, das mein Button schneller reagiert. Allgemeine Java-Themen 13
A mein Frame wird nicht schnell genung aktualisiert Allgemeine Java-Themen 7
G JFrame nimmt mein Image nicht Allgemeine Java-Themen 2
D Mein Bäumchen Allgemeine Java-Themen 6
I Mehrere Klassen mit den selben Daten Allgemeine Java-Themen 5
Zrebna Wie ermittelt man alle testbaren (zu testenden) Klassen in seinem Maven-Projekt? Allgemeine Java-Themen 23
8u3631984 Jacoco Testcoverage bei Abstracten Klassen in verschachtelten Modulen Allgemeine Java-Themen 6
Encera Gleichzeitiges Ausführen und verbinden von 2 Java-Klassen über die Eingabeaufforderung und Eclipse Allgemeine Java-Themen 21
8u3631984 Problem beim Mocken von Record Klassen Allgemeine Java-Themen 4
B Ein Objekt einer Klasse mehreren anderen Klassen zur Verfügung stellen? Allgemeine Java-Themen 6
B Java Reflection Probleme beim wehcselseitigen Referenzieren zweier Klassen/Objekte Allgemeine Java-Themen 14
P9cman java.Lang Klassen fehlen in JRE System Library Allgemeine Java-Themen 1
N abstracte klassen methoden Allgemeine Java-Themen 32
W Klassen Zugriff auf ein Textfile aus allen Klassen. Allgemeine Java-Themen 2
M Klasse durch Klassen Aufteilung verbessern, aber wo? Allgemeine Java-Themen 1
stormyark Problem beim Klassen erstellen Allgemeine Java-Themen 1
M Kann man Annotationen auf Klassen einschränken die ein Interface implementieren? Allgemeine Java-Themen 1
nonickatall Methoden Kann man Klassen/Methoden aus Variablen heraus aufrufen? Allgemeine Java-Themen 6
H Interface PluginSystem ClassNotFound exception für library Klassen Allgemeine Java-Themen 10
L Classpath Zur Laufzeit bestimmte Klassen in Classloader hinzufügen? Allgemeine Java-Themen 4
P Abstrakte Klassen vs. Interface Allgemeine Java-Themen 4
I Klassen aus Jar-Dateien aus anderem Ordner laden Allgemeine Java-Themen 3
D OOP Gemeinsamen ID-Raum für zwei Klassen implementieren Allgemeine Java-Themen 7
B Problem mit meinen Klassen Allgemeine Java-Themen 6
I Array Parameter mit 2 Klassen - NullPointerException Allgemeine Java-Themen 3
F ArrayList`s in Klassen mit Getter/Setter Allgemeine Java-Themen 8
F Code in Klassen bringen Allgemeine Java-Themen 4
J Problem beim Generischen Klassen und Interfaces Allgemeine Java-Themen 2
F Klassen Verwendung abstrakter Klassen Allgemeine Java-Themen 9
W Variablenübergabe über mehrere Klassen Allgemeine Java-Themen 4
B Vererbung Interface und implementierende Klassen Allgemeine Java-Themen 8
D Klassen JLabels in anderen Klassen verwenden. Allgemeine Java-Themen 7
H Klassen LibGDX - Verschiedene Klassen als Value in einer Map Allgemeine Java-Themen 8
J Best Practice Objekt an alle Klassen verteilen ( Discord Bot ) Allgemeine Java-Themen 7
A Anonyme Klassen - Interface Allgemeine Java-Themen 5
ReinerCoder auf Klassen innerhalb eines package zugreifen Allgemeine Java-Themen 22
J Tetris Probleme bei Klassen Allgemeine Java-Themen 14
cool_brivk24 Klassen Klassen Aufruf Fehlgeschlagen Allgemeine Java-Themen 14
S Parametrisierte jUnit 5-Tests mit eigenen Datentypen/Klassen-Objekten als Test-Parameter Allgemeine Java-Themen 0
rentasad Design-Frage - Interfaces, Klassen, statische Methoden Allgemeine Java-Themen 3
S Klassen Abstrakte Klassen Allgemeine Java-Themen 5
T Log4J - Deaktivierung für einzelne Klassen Allgemeine Java-Themen 7
Tommy Nightmare Klassen Globale Klassen erstellen Allgemeine Java-Themen 7
X Klassen aus jar in jar Laden Allgemeine Java-Themen 1
S Klassen Klassen "virtuell" erstellen Allgemeine Java-Themen 5
J Aus mehreren Klassen ein Datei ausführbare machen Allgemeine Java-Themen 6
S equals-Methode bestimmer Klassen abfangen Allgemeine Java-Themen 2
M Klassen Eine Klasse in mehreren Klassen einbinden Allgemeine Java-Themen 11
Sin137 Struktur der Klassen & Package Allgemeine Java-Themen 2
G Klassen und interne Klassen Allgemeine Java-Themen 1
S Klassen übergeben Allgemeine Java-Themen 13
C Klassen und Konstruktor Allgemeine Java-Themen 2
S Classpath Wie kann ich Java-Library Klassen "verstecken"..? Allgemeine Java-Themen 4
A Java speech - 2 Klassen Allgemeine Java-Themen 1
V Wie kann ich die Fragen mit den anderen Klassen verbinden? Allgemeine Java-Themen 1
T Schlüsselworte mehrere public-Klassen in einem Paket Allgemeine Java-Themen 7
V Klassenname von allen Klassen mit einer bestimmten Eigenschaft bekommen Allgemeine Java-Themen 2
B Classpath Eclipse findet importierte Klassen nicht Allgemeine Java-Themen 1
C DBConnection als Methode in mehreren Klassen Allgemeine Java-Themen 4
C Arten von Klassen Allgemeine Java-Themen 3
7 Verbinden von Mehreren Klassen Allgemeine Java-Themen 29
A Klassen ein Interface aufzwingen Allgemeine Java-Themen 4

Ähnliche Java Themen


Oben