Extending BigDecimal?

8

Ich habe eine Menge Code mit BigDecimal Class und ich hasse die Ungeschicklichkeit der Schnittstelle.

Ich habe den Schmerz bei der Verwendung von BigDecimal s mit Ganzzahlen gemildert, indem ich mit den folgenden Methoden eine Hilfsklasse mit statischen Methoden erstellt habe:

%Vor%

Das ist alles, was ich jetzt brauche, und der Code ist ein wenig lesbarer als zuvor. Ich habe jedoch gelesen, dass statische Methoden eine "schlechte" Sache sind und dass sie nicht den OO-Prinzipien folgen.

Wenn ich BigDecimal jedoch erweitere, würde ich einen neuen Typ definieren und müsste daher alle Methoden neu definieren, um sie mit meinem Objekt zu umhüllen, oder ich kann die Ergebnisse nicht mit dem Augmented verwenden Methoden. Es scheint nicht klug zu sein.

Wie würden Sie dieses Problem angehen?

    
stivlo 25.06.2011, 09:25
quelle

5 Antworten

5

Ich würde es genau so machen, wie Sie es getan haben!

Alle Design-Entscheidungen dieses Typs müssen auf dem Wunsch beruhen, den Code für den nächsten Programmierer, der den Code nach Ihnen übernehmen wird, wartbarer zu machen. Aus diesem Grund machen wir O-O-Design und komponentenbasierte Entwicklung in erster Linie.

Aber angesichts der Syntax von Java ist es wirklich schwierig, eine API für mathematikbasierte Ausdrücke zu erstellen. Ich habe zwei Probleme mit der aktuellen BigInteger API:

  • es ist nicht sehr nah an der üblichen mathematischen Notation
  • es ist asymmetrisch für symmetrische Operatoren wie add und multiplizieren

[Operator-Überladung ist eine der wenigen Funktionen von C ++, die ich in Java vermisse]

Was ist besser lesbar?

%Vor%

oder

%Vor%

Persönlich bevorzuge ich die zweite Version.

Schlimmer sind die Fälle, in denen Zahlen verschiedener Basistypen Teil desselben Ausdrucks sind. ZB

%Vor%

oder

%Vor%

Berücksichtigen Sie auch die großen Unterschiede in den Notationen von den kleinen Änderungen in der entsprechenden mathematischen Notation:

  • (a-b)*c wird in a.subtract(b).multiply(c) oder multiply(subtract(a,b),c) übersetzt
  • c*(a-b) wird in c.multiply(a.subtract(b)) oder multiply(c,subtract(a,b)) übersetzt

Für mich ist es einfacher, die Notation der statischen Methode zu schreiben und zu lesen, als die "reine" O-O-basierte Notation.

    
Tonny Madsen 25.06.2011, 10:05
quelle
4

Erweitern Sie nicht BigDecimal , verwenden Sie eine Wrapper-Klasse (wie Sie) oder ein anderes Framework wie Commons Math.

Dfp ähnelt dem, was Sie möchten - org.apache.commons.math.dfp.Dfp

    
Jon 25.06.2011 09:33
quelle
2

Könnten Sie mir bitte klarstellen, was genau Sie meinen mit "Ich würde einen neuen Typ definieren und somit müsste ich alle Methoden neu definieren, um sie mit meinem Objekt zu umhüllen oder ich werde es nicht sein fähig, die Ergebnisse mit den erweiterten Methoden zu verwenden. "?

  • Wenn Sie most der Methoden aus der BigDecimal-API und Ihre eigenen zusätzlichen Methoden verwenden müssen, würde ich vorschlagen, dass Sie Ihre benutzerdefinierte Klasse von BigDecimal erben. Auf diese Weise müssen Sie keine Wrapper für die BigDecimal-Methoden definieren, die für Sie bereits funktionieren. In diesem Szenario ist Ihre benutzerdefinierte Klasse ein BigDecimal, plus etwas mehr.

  • Wenn Sie nur eine paar -Methoden von der BigDecimal-API benötigen, plus Ihre eigenen zusätzlichen Methoden, dann würde ich vorschlagen, dass Sie nicht von BigDecimal ableiten. Stattdessen verwenden Sie intern ein BigDecimal und delegieren einige der Funktionen, die Ihre benutzerdefinierte API bereitstellt. In diesem Szenario hat Ihre benutzerdefinierte Klasse ein BigDecimal, aber kein BigDecimal.

Dann, um eine BigDecimal-Methode zu umbrechen, um Ihren benutzerdefinierten Typ zurückzugeben:

Mit dieser Funktion würden Sie etwa Folgendes tun:

%Vor%

Mit Delegation (d. h. Komposition) würden Sie tun:

%Vor%

Mit statischen Hilfsmethoden würden Sie tun:

%Vor%     
superjos 25.06.2011 09:34
quelle
0

Wenn Sie eine Klasse erstellen, die eine andere Klasse erweitert (d. h. BigDecimal in Ihrem Fall), hat die untergeordnete Klasse immer noch alle Eigenschaften der übergeordneten (Super-) Klasse. In Ihrem Fall, wenn Sie schreiben:

%Vor%

Alle UsableBigDecimal-Objekte wären immer noch Instanzen von BigDecimal, da es sich um ihre Superklasse handelt. Sie könnten sie wie jedes andere BigDecimal-Objekt verwenden, einschließlich Ihrer statischen Hilfsmethoden.

Statische Utility-Methoden sind meiner Meinung nach durchaus akzeptabel, um im Umgang mit Core-Java-Klassen einen gemeinsamen Code zu verwenden.

    
thkala 25.06.2011 09:33
quelle
-4

Ich würde dieses Problem und das ursprüngliche Problem vergessen und mich an die API von BigDecimal gewöhnen, so wie sie ist. Alles, was du machst, ist, Probleme für dich selbst zu schaffen, wie die Existenz dieser Frage zeigt.

    
EJP 25.06.2011 09:48
quelle