OOP Ansätze und Tipps zum Porgrammieren eines Taschenrechners

DaCrazyJavaExpert

Bekanntes Mitglied
Hallo,
ich möchte einen Rechner programmieren. Dafür würde ich gerne ein paar Ansätze und Tipps haben, da ich sowas noch nicht gemacht habe. Ich erhoffe mir dabei auch, ein wenig mehr die Logik Javas zu durchblicken.

Ich habe bereits Das GUI für den Rechner erstellt und auch die Funktion, etwas in ihn eintippen zu können. Die ganze Rechnung/Aufgabe wird in einem String bill gespreichert. Mein nächstes Ziel wäre es, die Funktion einzubauen, dass man mit einem klick auf einen Button eine Zahl oder ein Zeichen aus dem String zu löschen, also sozusagen eins zurückzugehen. - Dazu wäre mein Ansatz, den String in chars zu teilen und den letzten char zu entfernen.
Zudem gibt es noch einen Button, mit dem man die ganze Eingabe löschen kann. Das sollte einfach gehen indem ich den String auf "" setze. So sieht das GUI momentan aus:
CalculatorGUI.PNG (C = ganze Eingabe entfernen; ⌫ = ein zurück/letztes Zeichen löschen)
Danach würde ich dann daran gehen die Eingabe als Rechnung zu berechnen. Also mein Ansatz: >Beim klicken auf dem Button '=' Den Momentanen Inhalt des Textfeldes nehmen und diesen String dann in eine Rechnung zu "machen". Wie genau ich das machen soll, weiß ich noch überhaupt gar nicht. Und ich möchte das ganze natürlich so objektorientiert und so widerverwendbar wie möglich gestalten.
Deshalb wäre ich sehr froh über Hilfe.

Vielen Dank.
 

DaCrazyJavaExpert

Bekanntes Mitglied
Hallo,
ich möchte einen Rechner programmieren. Dafür würde ich gerne ein paar Ansätze und Tipps haben, da ich sowas noch nicht gemacht habe. Ich erhoffe mir dabei auch, ein wenig mehr die Logik Javas zu durchblicken.

Ich habe bereits Das GUI für den Rechner erstellt und auch die Funktion, etwas in ihn eintippen zu können. Die ganze Rechnung/Aufgabe wird in einem String bill gespreichert. Mein nächstes Ziel wäre es, die Funktion einzubauen, dass man mit einem klick auf einen Button eine Zahl oder ein Zeichen aus dem String zu löschen, also sozusagen eins zurückzugehen. - Dazu wäre mein Ansatz, den String in chars zu teilen und den letzten char zu entfernen.
Zudem gibt es noch einen Button, mit dem man die ganze Eingabe löschen kann. Das sollte einfach gehen indem ich den String auf "" setze. So sieht das GUI momentan aus:
Anhang anzeigen 10479 (C = ganze Eingabe entfernen; ⌫ = ein zurück/letztes Zeichen löschen)
Danach würde ich dann daran gehen die Eingabe als Rechnung zu berechnen. Also mein Ansatz: >Beim klicken auf dem Button '=' Den Momentanen Inhalt des Textfeldes nehmen und diesen String dann in eine Rechnung zu "machen". Wie genau ich das machen soll, weiß ich noch überhaupt gar nicht. Und ich möchte das ganze natürlich so objektorientiert und so widerverwendbar wie möglich gestalten.
Deshalb wäre ich sehr froh über Hilfe.

Vielen Dank.

EDIT: Das mit dem Eingabe entfernen und letzes Zeichen aus der Eingabe löschen hab ich schonmal.
 
Zuletzt bearbeitet:

AndiE

Top Contributor
Ich halte den Ansatz für falsch. Ich würde die Rechnung nicht in einen String speichern. Die Auswertung ist recht kompliziert. Die Normale Logik "Zahl OP Zahl" zu programmieren, widerspricht ja dem üblichen Aufruf "Op(Zahl,Zahl)". Um das bewerkstelligen zu können, müssen diese Dinge in der Reihenfolge "Zahl, Zahl, Op" bekannt sein. Ein problem wäre, wie man die Zahl zusammensetzt. Also nicht den String casten, sondern stellenweise anhand der gedrückten Button(0 bis 9 und ,) zusammensetzen.
 

DaCrazyJavaExpert

Bekanntes Mitglied
Ok danke. Also ich bin mir nicht sicher, ob ich dieses Model-View-Controller-Dings verstanden habe, oder ob ich das wesentliche verstanden habe. Soweit wie ich es verstanden habe, empfängt der Controller, als das Bedienelement Daten vom View, welcher in irgendener Weise mit dem Model "zusammenarbeitet". Ich weiß nicht inwiefern was wichtig ist, aber mehr hab ich auch nicht direkt verstanden.
Also als nach meinem Verstädniss: Wenn man auf einen Button klickt, werden Informationen von der View empfangen und (irgendwie) verarbeitet. Das Modul dient als Datenquelle und verfaltet/aufbereitet die Daten. Außerdem ist der View für die Darstellung auf dem Bildschirm zuständig. (???!!!?????)

Und wie meinst du das mit
jede Operation errechnen
?
für jede mögliche Eingabe eine Rechnung erstellen? (Mit irgendeinem Algorythmus oder so?)
Danke
 

DaCrazyJavaExpert

Bekanntes Mitglied
Ich halte den Ansatz für falsch. Ich würde die Rechnung nicht in einen String speichern. Die Auswertung ist recht kompliziert. Die Normale Logik "Zahl OP Zahl" zu programmieren, widerspricht ja dem üblichen Aufruf "Op(Zahl,Zahl)". Um das bewerkstelligen zu können, müssen diese Dinge in der Reihenfolge "Zahl, Zahl, Op" bekannt sein. Ein problem wäre, wie man die Zahl zusammensetzt. Also nicht den String casten, sondern stellenweise anhand der gedrückten Button(0 bis 9 und ,) zusammensetzen.
Darunter kann ich mir leider auch nichts vorstellen. Ich mache es ja, wie gesagt das erste Mal. Meinst du also, ich soll nach jeder eingegebenen Zahl die Zahl nehmen und mit ihr, dem nachfolgenden Operator und der Nachfolgenden Zahl dann rechnen? - Weil dazu kommt ja noch ins Spiel, dass es Punkt vor Strich gibt, Man eventuell mal was falsch eingegeben hat und wieder zurückgehen muss und was ändern muss usw.. Deshalb dachte ich auch an das "Am Ende String nehmen und damit arbeiten" - Da ist sogesehen ja die "richtige" Rechnung ohne irgendwelche Fehler o.ä.
 

AndiE

Top Contributor
Wenn du eingibt 12*3-10=, was passiert dann? Klassischerweise wird nach Eingabe des "-" die Zahl 36 angezeigt und nach Eingabe des "=" 26. Abstrahierend haben wir nun fünf Methoden, die man als add(+), sub(-), div(/), mul(*) und result(=) anlegen könnte. Die Frage ist nun,wie man die in eine Klasse legt und wie der Aufruf festgelegt ist. An dieser Stelle ist Planung notwendig, dann ein Klassenentwurf und dann Tests, ob das so überhaupt funktioniert. Über Zahlen mit Komma oder negative Zahlen würde ich noch gar nicht nachdenken. Auch über Änderungen nicht. Maximal nur "C" (Clear), um die Anzeige auf "0" zu stellen. Aber was würde ein Druck auf Taste "C" bedeuten?
 

JuKu

Top Contributor
Um das bewerkstelligen zu können, müssen diese Dinge in der Reihenfolge "Zahl, Zahl, Op" bekannt sein. Ein problem wäre, wie man die Zahl zusammensetzt. Also nicht den String casten, sondern stellenweise anhand der gedrückten Button(0 bis 9 und ,) zusammensetzen.

Was du meinst ist die "Reverse Polish Notation":
https://de.wikipedia.org/wiki/Umgekehrte_polnische_Notation

@DaCrazyJavaExpert Solange du keine Klammern & Rechenregeln implementieren willst, ist es ziemlich einfach.
Nur nimmst den String, parst ihn (also gehst z.B. Zeichenweise vor, schaust ob es eine Zahl oder ein Operand ist) und rechnest dann direkt.
Falls du aber Klammern & Rechenregeln implementieren willst, solltest du die ganze Rechenoperation am besten in einen Baum umwandeln.
 

truesoul

Top Contributor
Ok danke. Also ich bin mir nicht sicher, ob ich dieses Model-View-Controller-Dings verstanden habe, oder ob ich das wesentliche verstanden habe. Soweit wie ich es verstanden habe, empfängt der Controller, als das Bedienelement Daten vom View, welcher in irgendener Weise mit dem Model "zusammenarbeitet". Ich weiß nicht inwiefern was wichtig ist, aber mehr hab ich auch nicht direkt verstanden.
Also als nach meinem Verstädniss: Wenn man auf einen Button klickt, werden Informationen von der View empfangen und (irgendwie) verarbeitet. Das Modul dient als Datenquelle und verfaltet/aufbereitet die Daten. Außerdem ist der View für die Darstellung auf dem Bildschirm zuständig. (???!!!?????)

Und wie meinst du das mit
?
für jede mögliche Eingabe eine Rechnung erstellen? (Mit irgendeinem Algorythmus oder so?)
Danke

Siehe z. B https://javabeginners.de/Design_Patterns/Model-View-Controller.php
 

JuKu

Top Contributor
Ok danke. Also ich bin mir nicht sicher, ob ich dieses Model-View-Controller-Dings verstanden habe, oder ob ich das wesentliche verstanden habe. Soweit wie ich es verstanden habe, empfängt der Controller, als das Bedienelement Daten vom View, welcher in irgendener Weise mit dem Model "zusammenarbeitet". Ich weiß nicht inwiefern was wichtig ist, aber mehr hab ich auch nicht direkt verstanden.
Also als nach meinem Verstädniss: Wenn man auf einen Button klickt, werden Informationen von der View empfangen und (irgendwie) verarbeitet. Das Modul dient als Datenquelle und verfaltet/aufbereitet die Daten. Außerdem ist der View für die Darstellung auf dem Bildschirm zuständig. (???!!!?????)

Das Ziel des MVC (Model-View-Controller) Prinzips ist eine Logik-Daten-Design Trennung.
Quasi dass du das Design austauschen kannst, ohne etwas an der internen Business Logik zu ändern.

  • Model - Daten
  • View - Darstellung (Design)
  • Controller - Business Logik

Das Model kennt das View nicht und umgekehrt, lediglich die Controller Klasse kennt sowohl das Model, als auch das View.
Es gibt meines Wissens 2 mögliche Implementierungen um Eingaben entgegenzunehmen:
  • Push-Observer
  • Pull Observer

In jedem Fall muss aber das View den Controller informieren, dass jemand auf den Button geklickt hat. Der Controller selbst kennt den Button aber nicht.
 

AndiE

Top Contributor
Nehmen wir mal den normalen Ablauf, dann ist der Taschenrechner eines der ersten Projekte, die man als Programmierer bearbeitet. Ist es da sinnvoll, gleich mit Parser anzufangen? Ich denke, man sollte hier erstmal kleine Brötchen backen.
 

JuKu

Top Contributor
Nehmen wir mal den normalen Ablauf, dann ist der Taschenrechner eines der ersten Projekte, die man als Programmierer bearbeitet. Ist es da sinnvoll, gleich mit Parser anzufangen? Ich denke, man sollte hier erstmal kleine Brötchen backen.

Oh, ich wusste nicht, dass er Anfänger ist.
In diesem Fall sollte er es tatsächlich etwas leichter gestalten.
 

mrBrown

Super-Moderator
Mitarbeiter
Das Ziel des MVC (Model-View-Controller) Prinzips ist eine Logik-Daten-Design Trennung.
Quasi dass du das Design austauschen kannst, ohne etwas an der internen Business Logik zu ändern.

  • Model - Daten
  • View - Darstellung (Design)
  • Controller - Business Logik
Wobei die Business Logik sinnvollerweise ins Model gehört, und eben nicht in den Controller - der ist nur für die Behandlungen von Eingaben zuständig ;)
 

mrBrown

Super-Moderator
Mitarbeiter
Da bin ich mir ehrlich gesagt etwas unsicher. Ich dachte immer, das Model ist wirklich nur für die Daten zuständig.
Wikipedia schreibt dazu ja auch was: https://de.wikipedia.org/wiki/Model_View_Controller#Model
Allerdings glaube ich, dass du recht hast. :D
Ich habe es bisher immer im Controller implementiert, aber wahrscheinlich ist es im Model sinnvoller.
Das Model und Funktionalität zusammengehört, ist doch einer der OOP-Gedanken ;)

Wenn man die Business-Logik im Controller hat, gewinnt man kaum was - außer das man die View in Kleinigkeit anpassen kann , das wäre aber auch ohne Trennung möglich.
Man kann’s nicht vernünftig testet, weil der Controller alles macht.
Man kann nicht vernünftig mehrere Views zu einem Model gleichzeitig haben.
Man kann die View nicht tauschen (zB von Swing zu JavaFx), weil View und Logik untrennbar gekoppelt wären.

Die meisten Texte dazu sind leider unzureichend, Fowler(?) bezeichnet es als das am meisten falsch verstandene Muster ;)
 

AndiE

Top Contributor
Das könnte man in einem Taschenrechner ja gut testen. Die Clickfolge "1","2", "3" sollte ja die Zahl "123" ergeben. Dazu sollte z.B. der ActionListener der Buttons im Controler eine Methode "addDigit(int d)" aufrufen. Diese befindet sich in einem Objekt der Klasse Number und sorgt dafür das die darin angegebene private definierte Zahl result verändert wird. Dann sollte der Aufruf (Number).getResult das Ergebnis 123 ergeben. Number steht in Klammern, weil es ja der Klasse und nicht der Objektname ist.
Wie MrBrown geschrieben hat, könnte man mit "Number.addDigit(2)", "Zahl.addDigit(1)", Number.add(Zahl)" testen , dass "Number.getResult" genau 3(1+2=3) ergibt.
 

DaCrazyJavaExpert

Bekanntes Mitglied
Ok. Wie soll ich denn jetzt anfangen? Hier werden verschiedene Varianten vorgeschlagen, aber was die sinnvollste ist kann ich mir nicht erschließen. Ich hab jetzt erstmal die Rechnung (als String) in ein char-Array umgewandelt um dort die Rechnung Zeichen pro Zeichen durchzugehen.
 

truesoul

Top Contributor
Ok. Wie soll ich denn jetzt anfangen? Hier werden verschiedene Varianten vorgeschlagen, aber was die sinnvollste ist kann ich mir nicht erschließen

Mache doch alle Varianten. Das View brauchst du ja nicht jedes Mal austauschen. Und eigentlich auch nicht den Controller. Da musst du natürlich doch an das MVC halten.

Im übrigen könnte man auch mit dem
ScriptEngineManager die
Rechnung ausführen. Noch eine Variante :)

https://www.java-forum.org/thema/frage-wegen-moeglichem-grouping-hack.179593/page-2#post-1140099


Grüße
 
Zuletzt bearbeitet:

DaCrazyJavaExpert

Bekanntes Mitglied
Mache doch alle Varianten. Das View brauchst du ja nicht jedes Mal austauschen. Und eigentlich auch nicht den Controller. Da musst du natürlich doch an das MVC halten.

Im übrigen könnte man auch mit dem
ScriptEngineManager die
Rechnung ausführen. Noch eine Variante :)

https://www.java-forum.org/thema/frage-wegen-moeglichem-grouping-hack.179593/page-2#post-1140099


Grüße
Hui, alles ziemlich kompliziert. Prüfen ob die Rechnung zulässig ist könnte ich echt mit deiner Variante machen. Die Rechnungen durchführen bekomme ich aber irgendwie immernoch nicht hin. Die Variante von @AndiE hört sich ganz gut an, aber alleine bin ich glaube ich trotzdem noch zu unerfahren dafür.:(

- Also ich würde mich dann gerne an @AndiE 's Variante orientieren, also frage ich dazu dann immermal nach. Bitte nicht zu viel von mir erwarten :/.
 

truesoul

Top Contributor
Hui, alles ziemlich kompliziert. Prüfen ob die Rechnung zulässig ist könnte ich echt mit deiner Variante machen. Die Rechnungen durchführen bekomme ich aber irgendwie immernoch nicht hin. Die Variante von @AndiE hört sich ganz gut an, aber alleine bin ich glaube ich trotzdem noch zu unerfahren dafür.:(

Du kannst aber auch das Ergebnis der Rechnung direkt verwenden mit dem ScriptEngineManager. Fang doch erstmal mit dem Einfachen an. Dann versucht du die Variante die für schwieriger vorkommt.
 

AndiE

Top Contributor
Dann fange doch mit dem "einfachsten" an- Wenn du auf einen Zahlenbutton klickst soll die Zahl plus 2 angezeigt werden. also, du klickst auf "3" und "5" wird angezeigt.
 

DaCrazyJavaExpert

Bekanntes Mitglied
Hey, vorab: Tut mir Leid, dass ich als Ersteller dieses Threads so lange nicht da war, aber es hat zeitlich nicht gepasst. Nunja, jetzt bin ich wieder da und werde die nächsten Wochen auch da sein.
Also ich habe jetzt @AndiE 's "Aufgabe" versucht umzusetzen. An sich klappt es, aber irgendwie wird die Zahl dann 8 mal hinterinander ausgegeben. Also wenn ich bsw. auf 7 klicke wird 8 mal hintereinander die 9 ausgegeben. Mein Code seiht bislang so aus:
Java:
for (JButton numberButton : buttons.getNumberButtons()) { // numberButtons ist ein Stack mit allen Zahlen-Buttons drin.
                numberButton.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        JButton theButton = (JButton) e.getSource();
                        addNumberButtonsAction(theButton);
                    }
                });

private String addNumberButtonsAction(JButton someButton) {
       try {
           String numberFromButtonAsString = someButton.getText();
           System.out.println(numberFromButtonAsString);
           int numberFromButton = 2 + Integer.parseInt(numberFromButtonAsString);
           String numberAsString = String.valueOf(numberFromButton);
           bill += numberAsString;
           this.inputTxtArea.setText(bill);
       } catch (Exception e) {
           this.inputTxtArea.setText("Parsing Error");
       }

       return bill; //Das braucht man Momentan nicht, aber ich habs schonmal vorsichtshalber eingefügt.
   }

Aus irgendeinem Grund wird wie gesagt die Zahl (schon ausgerechnet) 8 mal hintereinander in das Texfeld gesetzt, bei einem einzigen Klick auf auf ein Zahlen-Button.

Danke für die Hilfe
 

AndiE

Top Contributor
Das ist nicht das, wie es funktionieren soll. Wo immer du den Code herhast. Es geht hier um einen Taschenrechner, also um Zahlen. Es soll ungefähr so funktionieren: Button gedrückt->ActionListener aufrufen->Ist die gedrückte Taste, der Button vom "+"->Ja, dann schreibe den int-Wert 3 in das Feld. Und dann auch : bei "-" den wert 6.
 

Ähnliche Java Themen

Neue Themen


Oben