PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : An die OOP-Fetischisten- & Dogmatiker: Freie Funktionen!?


Gast
2006-03-31, 20:03:53
Was spricht aus OOP-Sicht gegen Freie Funktionen?
(Vielleicht täusche ich mich, aber ich hab oft den Eindruck dass für OOP-Puristen Freie Funktionen das neue goto sind...)

MadMan2k
2006-03-31, 20:19:50
bei OOP gibts keine funktionen mehr sondern nur methoden und diese gehören nunmal zu einem objekt...

Gast
2006-03-31, 20:24:26
bzw Funktionen, die zu einer Klasse gehören.

Monger
2006-03-31, 20:27:48
Gib ein Beispiel. Falls du den Mischmasch à la C++ meinst: da ist der Namespace von freien Funktionen einfach unbekannt.

Dadurch dass du dir mit deinen Headern deine Funktionen sonstwoher holst, ist gar nicht zu überblicken in welchem Kontext jetzt welche Funktion steht.

Wenn du Methoden nur innerhalb von Klassen zulässt, hat sich das Problem gegessen: eine Methode ist IMMER einem bestimmten Objekt zugehörig, und die Definition dieses Objekts ist garantiert einzigartig.


Im übrigen widerspricht es halt der OOP Vorstellung, dass ALLES in der Welt ein Objekt ist. In Java ist z.B. selbst eine Klasse ein Objekt. Eine Eigenschaft oder ein Verhalten ohne dazugehöriges Objekt ist irgendwie sinnfrei. Wenn du "laufen" sagst, musst du auch sagen, was dies tut.

Gast
2006-03-31, 20:31:22
toll, und was ist mit Sortieralgorithmen oder einem stinknormalen abs oder sqrt??

Monger
2006-03-31, 20:37:52
toll, und was ist mit Sortieralgorithmen oder einem stinknormalen abs oder sqrt??

Ein Sortieralgorithmus ist halt immer ein Objekt, dass die Eigenschaft hat andere Objekte in ihrer inneren Struktur zu beeinflussen - in dem Fall sortiert es halt. Und abs und sqrt sind Verhaltensweisen eines Objektes, was mathematische Funktionen verarbeiten kann - wie halt eben die Math Klasse (die wie gesagt in Runtime selbst ein Objekt ist).


Wie gesagt: A bewirkt B. Ohne Verursacher keine Ursache. Nach OOP Sicht gibt es keine Aktion, die völlig ohne Kontext existieren kann. Es könnte ja sein, dass der Sortieralgorithmus oder die mathematischen Funktionen nicht in jedem Kontext gültig sind.

Gast
2006-03-31, 20:50:06
http://www.cuj.com/documents/s=8042/cuj0002meyers/

Marscel
2006-03-31, 20:53:02
Ich persönlich finde es übersichtlicher und auch logischer.

Coda
2006-03-31, 21:07:52
Ich finde es überhaupt nicht logischer, dass eine Sortierfunktion für generische Container in den Containern enthalten sein muss.

Irgendwo hört der Spaß mit OOP auch auf.

Genau das gleiche mit Sachen wie abs usw. Es macht einfach keinen Sinn das in eine Klasse statt einem Namespace zu verpacken.

Gast
2006-03-31, 21:08:52
Ich finde es überhaupt nicht logischer, dass eine Sortierfunktion für generische Container in den Containern enthalten sein muss.

Irgendwo hört der Spaß mit OOP auch auf.

Genau das gleiche mit Sachen wie abs usw. Es macht einfach keinen Sinn das in eine Klasse statt einem Namespace zu verpacken.
full ack!

Monger
2006-03-31, 21:15:59
Genau das gleiche mit Sachen wie abs usw. Es macht einfach keinen Sinn das in eine Klasse statt einem Namespace zu verpacken.

Mal andersrum gefragt: was hat es denn für Vorteile, Funktionen aus Klassen rauszuholen?

Und ein Namespace ist ja im Grunde auch nichts anderes als ein leichtgewichtiges Objekt. Die Syntax sieht halt dafür ein bißchen anders aus.

Gast
2006-03-31, 21:16:43
Mal andersrum gefragt: was hat es denn für Vorteile, Funktionen aus Klassen rauszuholen?
Es ist logischer.

Coda
2006-03-31, 21:17:24
Nun, als Sprachmittel ist es doch viel schöner. Man braucht kein Objekt instanzieren usw. Ich bin nun wirklich ein Fan von OOP, aber man sollte sich schon noch vor Augen führen wo es denn nun Sinn macht und wo nicht.

Bei den STL-Algorithmen hat es eben wenig Sinn gemacht und deshalb wurde es auch so implementiert. Die Leute denken sich schon was dabei.

Die main-Funktion mit Klasse in Java und .NET finde ich auch nicht wirklich schön gelöst.

Monger
2006-03-31, 21:18:18
Es ist logischer.

Wie wäre es mit mehr als drei Worten Erklärung? ;)

WARUM ist es logischer? Imo ist es nichts anderes als (schlechte) Gewohnheit, nicht in Klassen und Objekten zu denken.

Nun, als Sprachmittel ist es doch viel schöner. Man braucht kein Objekt instanzieren usw.
Das ist ein Argument. Ist allerdings kein Problem von OOP, sondern der Sprache. Dass vorallem Java in der Hinsicht noch sehr klobig ist, ist mir auch klar.

Coda
2006-03-31, 21:20:19
Imo ist es nichts anderes als (schlechte) Gewohnheit, nicht in Klassen und Objekten zu denken.
Nein ist es nicht. std::sort auf Iteratoren ist in C++ zehnmal mächtiger als wenn man das Ganze auf die Containerklassen beschränkt hätte. Ich definier mir nen neuen Containertyp, definier nen random-access Iterator dafür und das Ding läuft.

Wenn ich dafür extra von ner Basisklasse ableiten müsste und dann noch die genau gleichen Membernamen verwenden müsste, etc. dann hätte ich viel mehr von der Kapselung verloren nach außen.

Ja das ganze hätte man auch in eine Klasse "algorithms" packen können. Aber wozu? Es ist nunmal kein Objekt, es ist einfach nur ein simpler Namespace.

Ich muss aber dazu sagen, dass solche Situationen wirklich nicht oft vorkommen.

Monger
2006-03-31, 21:28:01
Ich muss aber dazu sagen, dass solche Situationen wirklich nicht oft vorkommen.

Das ist es halt. OOP geht üblicherweise davon aus, dass Programme unheimlich komplex und groß sind. Deshalb optimiert man dahingehend, extrem große Datenstrukturen effizient verwalten zu können, und nimmt dabei halt etwas Overhead bei den Sonderfällen (kleine Strukturen) in Kauf. Das ist bestimmt nicht für alle Fälle sinnvoll, für das Gros der PC Anwendungen aber eben doch.

Xmas
2006-03-31, 21:28:48
Genau das gleiche mit Sachen wie abs usw. Es macht einfach keinen Sinn das in eine Klasse statt einem Namespace zu verpacken.
Der Meinung bin ich auch, allerdings macht es letztlich auch kaum einen Unterschied ob man nun static-Methoden in Klassen oder Funktionen in Namespaces packt.

Coda
2006-03-31, 21:30:16
Klar, aber es gibt unter C++ eben die Namespaces und dann sollte man sie auch benützen, vor allem weil man auch noch Klassen mit reinnehmen können die zu dem Konzept passen (wäre mit Subklassen zwar auch möglich, aber doch langsam etwas unübersichtlich).

Zum Beispiel neigen ziemlich viele dazu Millionen von Singletons in C++ anzulegen was dann nen ziemlicher Mess wird anstatt paar Funktionen in Namespaces zu packen :rolleyes: (Natürlich nur wenn es Dinge sind die ohne Daten auskommen).

HellHorse
2006-03-31, 23:25:06
oder einem stinknormalen abs oder sqrt??
OMG sowas ist doch nicht frei!!!!11111einself
Das gehört auf die Instanzseite der Number (resp. ArithmeticValue) Klasse!
(Wobei man darüber diskutieren kann, ob das ein Trait/Mixin/Modul/... sein sollte)

toll, und was ist mit Sortieralgorithmen
Collection Superklasse resp auch wieder Trait/Mixin/Modul/...
In Fällen wo das nicht geht, kann man es immer noch als Objekt kapseln.

ScottManDeath
2006-03-31, 23:50:28
Mhmm, ich finde Sin(3.0) dann doch irgendwie eleganter als 3.0.Sin().

Insbesondere bei Funktionen, wo es zwei gleichberechtigte Parameter gibt, sind freie Funktionen eleganter, IMHO.

Vector a;
Vector b;

float s = a.Dot(b); // hääääässslich
float t = Vector.Dot(a, b); // besser, mag ich aber nicht, muss ich in C# aber so machen :(
float l = Dot(a, b); // am schönsten


Import von statischen Klassen in den Namespace wurde leider bei C# 2.0 rausgekickt :(

Trap
2006-04-01, 17:35:49
Im Common Lisp Objekt-System gibt es nur freie Funktionen. Das liegt vor allem daran, dass alle Methoden multi-dispatch haben und damit jede Zuordnung einer Methode zu einer Klasse sehr willkuerlich waere (alle Parameter sind gleichberechtigt, wie im Beispiel im Post drueber).

Edit: Toll, jetzt landet es auf der naechsten Seite, soviel zum "Post drueber"...

Marscel
2006-04-01, 19:55:57
Genau das gleiche mit Sachen wie abs usw. Es macht einfach keinen Sinn das in eine Klasse statt einem Namespace zu verpacken.

Du hast zwar recht, bei PHP5 gibts leider keine Namespaces, ich hoffe bei Version 6 wirds dann anders aussehen. :rolleyes:

Gast
2006-04-01, 20:22:37
PHP ist nur was für langhaarige Frickler.

Gast
2006-04-01, 21:42:04
Ein Sortieralgorithmus ist halt immer ein Objekt, dass die Eigenschaft hat andere Objekte in ihrer inneren Struktur zu beeinflussen - in dem Fall sortiert es halt. Und abs und sqrt sind Verhaltensweisen eines Objektes, was mathematische Funktionen verarbeiten kann - wie halt eben die Math Klasse (die wie gesagt in Runtime selbst ein Objekt ist).Du überinterpretierst ...
Wenn ein Objekt nur existiert um freistehende Funktionen zu vermeiden, also keine eigenen Memberdaten hat, sondern nur einen Typen, dann hast du's mit dem OOD übertrieben. Spätestens dann. IMO.

Wie gesagt: A bewirkt B. Ohne Verursacher keine Ursache. Nach OOP Sicht gibt es keine Aktion, die völlig ohne Kontext existieren kann. Es könnte ja sein, dass der Sortieralgorithmus oder die mathematischen Funktionen nicht in jedem Kontext gültig sind.Der Kontext freistehender Funktionen ergibt sich aus den Typen ihrer Parameter.

sqrt(int), was leider ANSI-Standard-C ist AFAIK, ist noch ein schlechtes Beispiel. sqrt(unsigned int) wäre ein gutes.

Die Ursache eines Aufrufs einer freistehenden Funktion ist weil der Programmierer das in dem Moment und an der Stelle so haben wollte ...

-zecki

ScottManDeath
2006-04-01, 21:47:16
Im Common Lisp Objekt-System gibt es nur freie Funktionen. Das liegt vor allem daran, dass alle Methoden multi-dispatch haben und damit jede Zuordnung einer Methode zu einer Klasse sehr willkuerlich waere (alle Parameter sind gleichberechtigt, wie im Beispiel im Post drueber).

Edit: Toll, jetzt landet es auf der naechsten Seite, soviel zum "Post drueber"...

Also bei meiner Anzeigeeinstellung stymmt das ;)

Multi Dispatch wäre so oder so praktisch, egal ob nun als Methode oder freie Funktion.

Es gibt ja auch Funktionen, die mehr als 2 gleichberechtigte Parameter haben, wie z.B. Min für 4 Parameter. 3.Min(4,5,6) macht mich dann nicht so an....

maximAL
2006-04-01, 22:23:26
Wenn ein Objekt nur existiert um freistehende Funktionen zu vermeiden, also keine eigenen Memberdaten hat, sondern nur einen Typen, dann hast du's mit dem OOD übertrieben. Spätestens dann. IMO.
vorteile wie polymorphie bleiben auch ihne memberdaten bestehen.
zb. sortieralgos - unterschiedliche algos, die von einem sort-objekt erben.

übrigens ist "in C++ ist das blöd" ein reichlich schlechtes argument gegen irgendeinen aspekt von OOP...

Gast
2006-04-01, 23:22:34
vorteile wie polymorphie bleiben auch ihne memberdaten bestehen.
zb. sortieralgos - unterschiedliche algos, die von einem sort-objekt erben.

übrigens ist "in C++ ist das blöd" ein reichlich schlechtes argument gegen irgendeinen aspekt von OOP...Aber was ist denn bitte ein Sortier-Objekt? Kann ich davon mehrere in einem Container speichern? Will ich sowas können?

Möglicherweise kannst du eine Klasse deklarieren mit der du irgendwie sortieren kannst, aber das Sortier-Objekt, also die Instanz, ist dadurch immer noch nur ein leerer Typ.

-zecki

HellHorse
2006-04-02, 11:28:47
Aber was ist denn bitte ein Sortier-Objekt?
A SequenceableCollectionSorter is an object that sorts collections via a function of two arguments, contained in its sortBlock. It's original purpose is to provide for maintaining Lists in sorted order, but it is adaptable for use with any kind of collection. putSelector and atSelector aren't needed for collections that responds to at: and at:put:.

Instance Variables:
collection <SequenceableCollection> The collection to be sorted
sortBlock <BlockClosure> The function for sorting the elements of the collection (the block returns true if the first argument sorts to before or at the same place as the second argument)
atSelector <Symbol | nil> Used for #at: message
putSelector <Symbol | nil> Used for #at:put: message
sizeSelector <Symbol | nil> Used for #size message


Object Reference:
A SequenceableCollectionSorter makes the sorting capabilities of a SortedCollection available to any sequenceable collection. A List uses a SequenceableCollectionSorter to implement its sorting abilities. With other types of collections, such as OrderedCollection, the application is responsible for creating the sorter and choosing when to use it.
A sorter is typically created by sending #on: to this class, with the underlying collection as the argument. The default sorting order is ascending order, as defined by the block [ :a :b | a <= b]. To specify an alternate sort block, send #sortBlock: to the sorter, with a custom sorting block as the argument.
Creating a sorter on a collection does not automatically cause the collection to be sorted. To perform the sort, send #sort to the sorter. The underlying collection's elements are moved during a sort -- that is, a copy of the collection is not created for sorting purposes.
Some types of collections do not support the protocol that is expected by a sorter, so the sorter is able to adapt. For example, when the underlying collection does not use #at: to access the element at a particular index, you can use #atSelector: to register the alternative method name. Similarly, #putSelector: can be used to register an alternate for #put:, and #sizeSelector: for #size.

maximAL
2006-04-02, 12:21:54
Aber was ist denn bitte ein Sortier-Objekt? Kann ich davon mehrere in einem Container speichern? Will ich sowas können?
bei sortier-objekten vielleicht nicht unbedingt relevant. gehtst du aber eine stufe höher, kann es sehr wohl sinn machen, verschiedenste algos für die weitere verarbeitung zu speichern (sortieren, mappen etc.) und dann alle hintereinander weg abzuarbeiten.

Gast
2006-04-02, 12:50:35
Komisch genau den gleichen Thread gibt es auch in einem anderen Forum: http://www.c-plusplus.de/forum/viewtopic-var-t-is-142565.html

Xmas
2006-04-02, 15:01:42
bei sortier-objekten vielleicht nicht unbedingt relevant. gehtst du aber eine stufe höher, kann es sehr wohl sinn machen, verschiedenste algos für die weitere verarbeitung zu speichern (sortieren, mappen etc.) und dann alle hintereinander weg abzuarbeiten.
Wobei man aber auch sagen muss, dass man dies genausogut mit Funktionspointern erreichen könnte.

MadMan2k
2006-04-02, 17:48:10
Wobei man aber auch sagen muss, dass man dies genausogut mit Funktionspointern erreichen könnte.
hast du dir mal Gobject angeguckt? Das kann sogar exceptions mit ANSI-C mitteln nachahmen...