# Statische Klassen oder neue Instanz einer Klasse nutzen?



## WeirdAl (20. Jun 2007)

Hi,
bislang habe ich immer ein Package mit statischen Utility-Klassen gehabt, die ich dann in verschiedenen anderen Klassen aufgerufen habe. Jetzt frage ich mich, ob ich diese statischen Klassen nicht wieder "nicht statisch" machen sollte und mir bei Bedarf eine Instanz dieser Klasse in meinen "normalen" Klassen erzeugen sollte. Quasi würde ich static rauswerfen und überall den statischen Aufruf durch Komposition ersetzen. 

Meine Gedanken bzw. Fragen dazu:
- Wenn ich dies durchgängig in Methodenaufrufen (also lokal) machen würde, könnte ich doch den Heap etwas entlasten, weil die Lebensdauer der "Utility"-Instanz auf den Stack beschränkt ist. Ich weiss jedoch nicht genau, ob/wann statische Klassen auf dem Heap erzeugt werden.
- Ich weiss nicht (mehr) genau wie man statische Klassen in UML darstellen kann. Wird dies evtl über eine Assoziation  dargestellt? Wenn dies so wäre, würde sich beim Design ja nicht sehr viel ändern.

Ehrlich gesagt fallen mir schon keine Fragen mehr dazu ein . Ich würde nur gerne Wissen, ob dieser Ansatz humbug ist oder dem Gedanken der OOP entspricht.

Cu
Alex


----------



## SlaterB (20. Jun 2007)

was ist denn jetzt die Frage?
ob deine Klasse nun statisch oder nicht ist, scheint jedenfalls keinen Unterschied zu machen..


----------



## WeirdAl (20. Jun 2007)

Meine Frage ist eigentlich:

Ist es sinnvoll den Code anzupassen (static->instanzierte Klasse) oder isses egal. 
Ich bin gerade am Code refactory dran und überlege daher, ob ich mit nicht statischen im OOP Sinne "flexibler" bin oder ob es keinen Unterschied macht.

Ich hoffe mein Problem wird deutlich 


P.S.: Ne Nebenfrage wäre noch, wie eine statische Klasse in einem UML-Klassendiagramm dargestellt wird?(mit einer Assoziation?)

Cu
Alex


----------



## Beni (20. Jun 2007)

Wenn deine Utility-Klasse Einzelmethoden enthält (wie etwa "Math.max"), würde ich sie statisch lassen.

Oder enthalten deine Utility-Klassen Variablen? Macht Vererbung Sinn? Dann wäre zumindest die Möglichkeit für die Instanziierung passend.


----------



## WeirdAl (20. Jun 2007)

Hi,
zurzeit habe ich eine JSFUtil Klasse die Objekte in die verschiedenen Scopes (sessionScope zB) schreibt, bestimmte Werte in dem Scope sucht usw. 
Dann habe ich statische Klassen die nur für das erstellen/updaten/löschen von Objekten über Hibernate zuständig sind, sowie eine statische "Emailklasse" die ich mit Emailklasse.sendMail(text) benutze.

Meine statischen Klassen enthalten public Variablen, die jedoch als final deklariert sind. Ich greife normalerweise nur über spezielle Methoden auf diese Klassen zu und benutze Paramater, um die oben genannten "Funktionen" durchzuführen.

Cu
Alex


----------



## schalentier (21. Jun 2007)

IMHO (!) sind saemtliche statische Methoden/Klassen Zeugen fuer schlechtes OOP Design. Demnach wuerd ich die wegmachen, besonders wenn es deiner Ansicht nach prinzipiell egal ist. Natuerlich gibt es Faelle, wo der Einsatz dennoch sinnvoll sein kann, das sind jedoch immer Zugestaendnisse bei denen man vom OOP Gedanken abrueckt, um eine Sache effizient oder kurz (im Sinne von LOCs) zu machen. 

Z.b. die Klasse Math is so ein Nicht-OOP Konstrukt, was jedoch sehr sinnvoll sein kann. Besser waere es, wenn die Methoden aus der Klasse direkt an den Zahlen (Int, Double, etc) haengen wuerden. 

Man sieht es ja schon an der Namensgebung. JSFUtil ist absolut nichtssagend, wobei jedoch eine vernuenftige Klasse so benannt sein sollte, das die Aufgabe/Funktion bereits beim Lesen des Namen klar ist. 

Wieso ist das Schreiben/Lesen/Suchen in einen Scope nicht in einer Klasse "Scope"? Mit Hibernate kenn ich mich nicht sonderlich gut aus, aber waeren die Erstell/Update/Loesch-Sachen nicht ein perfekter Einsatz fuer eine Factory? Und eine Email wuerd ich in einer Klasse Email verschicken:

```
class Email {
  String body;
  String receiver;
  String sender;

  public void send();
}
```

nur so meine Gedanken dazu ;-)


----------



## WeirdAl (21. Jun 2007)

Huhu 
JSFUtil steht für JavaServer Faces Utility und beinhaltet nur Methoden die direkt/indirekt mit dem FacesContext (spezieller ServletContext) zu tun haben. Daher der "kryptische" Name der jedoch im JSF Projekt durchaus einen Sinn macht.

Meine Emailklasse sieht im Prinzip genauso aus, nur das mein send static ist. Ich glaube bei Beginn des Projektes hatte ich wohl "Angst" Instanzen einer Klasse zu erstellen und hab daher viele statische Klassen und Methoden erstellt.

Ich glaube jetzt wird mir langsam klar, was ich wirklich wissen will:
Wieso rücken statische Methoden/Klassen vom OOP Gedanken ab?
Unflexibler wird der Code ja dadurch nicht, da die Aufgaben entweder in einer instanziierten Klasse oder einer statischen Klasse gekapselt sind. 

Es gäbe wohl Probleme mit statischen Variablen sobald mehrere Klassen schreiben und lesend auf diese Variable zugreifen würden, aber wenn man nur statischen Methoden nutzt um Daten in eine DB/Email oder sonstwohin zu schreiben dann dürfte das eigentlich kein Problem sein.

Cu
Alex


----------



## SlaterB (21. Jun 2007)

alle Operationen in den Datenklassen zu haben ist ein organisatorischer und programmstruktureller Albtraum,
man stelle sich vor, den Code von Collections.sort in jeder Listen-Klasse zu wiederholen,
oder auch die ganzen mathematischen Operationen in den verschiedenen Zahl-Klassen

es gibt immer die Situation, in der eine bestimmte hochwertige Logikklasse die Kontrolle über dumme kleine Datencontainer hat,

statt nur die Math-Klasse könnte es in 10 Libraries 20 andere hochkomplexe Klassen geben, die noch viel kompliziertere Datenoperation ausführen,
sollten die und alle jemals zu erfindenen Operationen alle in Double eingebaut werden?..

also externe Klassen,
da bleibt dann allein die Frage, ob man eine Instanz bildet oder nicht,
in vielen Fällen ist es unumgänglich/ sinnvoll/ toll die Instanzen zu haben,

in manchen einfach sinnlos,
in diesen kann man immer noch das Objekt erstellen, niemand hindert einem daran,
oder einfach Operation statisch machen, was ganz eindeutig aussagt:
'Objekt nicht nötig, rufe Operation an der Klasse auf'

sauer, einfach, fertig


----------



## schalentier (21. Jun 2007)

Eine Klasse namens Util ist nichtssagend. I.A. liegen in solch einer Klasse Methoden rum, die eigentlich woanders besser aufgehoben waeren. Besser waere in deinem Falle doch, wenn die Methoden irgendwie direkt am FacesContext haengen, oder? Das meinte ich. Mir ist klar, manchmal geht das nicht, besonders wenn man irgendwelche Frameworks verwendet, die das Ableiten von einigen Klassen unmoeglich machen.



> Wieso rücken statische Methoden/Klassen vom OOP Gedanken ab?



Man kann statische Methoden in einer abgeleiteten Klsse nicht ueberschreiben. Demnach ist das Ableiten von Klassen mit vielen statischen Methoden sogutwie unmoeglich. Das fuehrt dann unweigerlich zu Klassen, die aus einer Sammlung von statischen Methoden bestehen, die sehr stark an prozeduralen Code erinnern, da man zunehmen darauf verzichet, sich Gedanken ueber OO Design zu machen (Ableitungsstrukturen mit wiederverwendbarem Code). 

Ausserdem sind statische Methoden (fast) zustandslos (ausser man verwendet statische Variablen um Zustaende zu speichern). Um das zu erreichen, wird der Zustand komplett ueber die Parameter uebergeben. Tjo, und da stell ich mir die Frage wozu das? Um bei deinem Fall zu bleiben, muesste deine statische Mailsend Methode wie folgt aussehen:


```
class Mail {
 public static void send( String to, String from, String betreff, String body, String attachment );
}
```

Naja und das ist IMHO einfach haesslich ;-) Denn da wo du das verwendest musst du die ganzen Parameter irgendwie erzeugen, verarbeiten oder einfach nur speichern. Aber genau dafuer waere doch die Klasse Mail zustaendig.

Ich finde, wenn man OO programmiert, muss man auch OO denken. In meiner Vorstellung ist eine Mail ein Ding, mit verschiedenen Eigenschaften (Sender, Empfaenger, etc) und der Moeglichkeit, dieses Ding zu verschicken. Was soll dann eine statische Methode in diesem Bild sein? Im uebrigen kann man nicht nur Mails verschicken, sondern z.b. auch InstantMessages. Wie wuerdest du mit statischen Methoden genau das modelieren? Das geht imo nicht. OO waere:


```
interface Sendable {
  public void send( Address receiver );
  public void send( List<Address> receivers );
}

class EMail implements Sendable {..}
class InstantMessage implements Sendable{..}
```

Oder seh ich was falsch? Ich weiss, du hast bei dir nur und zu 99% fuer immer ausschliesslich Emails... aber OO lebt eben davon, dass man seinen Code (zumindest theoretisch) wiederverwenden kann.


----------



## schalentier (21. Jun 2007)

SlaterB hat gesagt.:
			
		

> man stelle sich vor, den Code von Collections.sort in jeder Listen-Klasse zu wiederholen,
> oder auch die ganzen mathematischen Operationen in den verschiedenen Zahl-Klassen



Wieso? Die sort Methode koennte genauso in der abstraktesten Collections-Klasse stecken.



			
				SlaterB hat gesagt.:
			
		

> sollten die und alle jemals zu erfindenen Operationen alle in Double eingebaut werden?..



Nicht in Double, aber in einer abstrakten Klasse (Number). 



			
				SlaterB hat gesagt.:
			
		

> in manchen einfach sinnlos,
> in diesen kann man immer noch das Objekt erstellen, niemand hindert einem daran,
> oder einfach Operation statisch machen, was ganz eindeutig aussagt:
> 'Objekt nicht nötig, rufe Operation an der Klasse auf'
> ...



Ja, ich sag ja, manchmal ist das bestimmt sinnvoll, aber es ist nicht OO. Weil es nix mit einem Objekt zu tun hat, sondern weil es eine im "Raum schwebende" Methode ist.


----------



## SlaterB (21. Jun 2007)

gegen Vererbung usw. ist wirklich nix zu sagen,
außer vielleicht dem Spruch, nix auf Vorrat zu bauen 

aber für ein anderen Punkt möchte ich nochmal auf die Alternative hinweisen:
die Email ist eine Email, sie weiß nix über das Senden,

was ist, wenn es in verschiedenen Frameworks verschiedene Sende-Logik gibt?
und statt Internet vielleicht auch mal ein ganz anderes Übertragungssystem?

wenn schon, dann doch bitte separate Klasse

```
MyEmailSender implements Sendable (oder eher Sender) {
     public void send(EMail, List<Address> receivers ); 
}
```


> Wieso? Die sort Methode koennte genauso in der abstraktesten Collections-Klasse stecken.

wozu gibt es dann ein Interface List, wenn eh alle Listen von AbstractList ableiten?
jede eigene Klasse, die nicht von AbstractList ableitet, wäre aufgeschmissen

wenn die Operation sort(AbstractList list) heißen würde, 
klar, dann kann sie auch gleich als sort() in AbstractList eingefügt werden


----------



## schalentier (21. Jun 2007)

Jepp, hast vollkommen Recht. Ich wollte nur zeigen, warum statische Methoden IMHO schlecht sind. Und OO zu programmieren, bedeutet immer den Spagat zwischen zuviel und zuwenig zu schaffen irgendwie. Ich fahr derzeit ziemlich gut mit einfach anfangen, keine statischen Methoden verwendet (wenn moeglich) und zeitnah zu refaktorisieren... Gelobt sein mein tolles Refaktorisierungswerkzeug 

Und das mit Collections.sort liegt doch nur daran, dass es in Java keine Mehrfachvererbung (oder Mixins) gibt. Demnach ist das nur deshalb so geloest, weil es anders nicht geht. Das hat aber nix mit OO zu tun, sondern ist ein ziemlich teuflicher Workaround ;-)


----------

