Müssen Objekte in OOP eine Entität darstellen?

82

Muss ein Objekt eine Entität darstellen?

Mit einer Entität meine ich so etwas wie ein Product, Motorein ParkingLotusw., ein physisches oder sogar ein klares nicht-physisches konzeptuelles Objekt - etwas, das gut definiert ist, wobei einige Kerndaten eindeutig zum Objekt gehören, und einige Funktionen / Methoden das funktioniert eindeutig auf den kerndaten.

Zum Beispiel kann ich ein Objekt von a haben Demon, eine Entität an sich, eine imaginäre vielleicht und nicht physisch, aber dennoch eine Entität

Kann ein Objekt nur eine Sammlung von Methoden sein , ein gemeinsamer Satz von Prozeduren, die mit einem gemeinsamen Ziel verbunden sind?

Beispiel: Kann eine Klasse aufgerufen werden MotorOperationsoder MotorActions, wenn es keine Entität gibt, aber Methoden in der Klasse tun Dinge wie

  • getMotorDataFromHTMLForm ()
  • getMotorManufacturers ()
  • selectMotorFromUserRequirements ($ requirements)
  • canMotorCanHandleOperatingConditions ($ conditions)
  • computePowerConsumptionForMotor ($ id)

Eine Klasse wird in der Regel als zentral für das Objekt + definierte Datenoperationen definiert. So kann es für a Motoreinige Motorvariablen geben, die sich auf Motorspezifikationen beziehen, und es kann Vorgänge geben, die diese Daten kombinieren, um etwas zu erzeugen.

In meinem Fall ist es eher so, als hätte ich eine Klasse mit Operationen für Daten + Daten, die durch die Klasse geleitet werden. Es gibt keine Daten, die sich auf "Motoroperationen" konzentrieren, außer temporäre Daten, die durch die Klasse geleitet werden.

Frage

Können Klassen entitätslose Objekte darstellen? Wenn nicht, warum sind sie schlecht / unvollständig / nicht OOP-zentriert? Gibt es Möglichkeiten, wie sie konzeptionell geändert / verbessert werden müssen, um mit OOP übereinzustimmen?

Dennis
quelle
2
+1. Aber würde "ja" bedeuten, dass es eine Entität darstellen muss, oder würde es bedeuten, dass sie entitätslose Objekte darstellen können?
Panzercrisis
1
Das erste, was mir in den Sinn kommt: java.awt und seine "Op" -Klassen (z. B. docs.oracle.com/javase/7/docs/api/java/awt/image/… ), wenn Sie das meinen. Es stellt eine Operation dar. Jetzt bin ich mir nicht sicher, ob es eine gute Übung ist (sie sieht komisch und hässlich aus), aber sie ist in der Java-Standardbibliothek enthalten, und Java ist OOP. Hauptsächlich.
Luke
1
Nein, tut es nicht, aber das heißt nicht, MotorActionsoder MotorOperationssind gute Ideen oder nicht.
user253751
1
Diese Frage könnte von einer weiteren Spezifikation der Dose profitieren .
Reinierpost
3
@ Tennis Ich habe wirklich das Gefühl, dass du die falschen Fragen stellst. Erstens, weil es keine definitive Definition von OOP gibt, zweitens, weil Paradigmen nur ein Mittel zum Zweck sind. Die einzigen wichtigen Fragen sind: "Erleichtert das Schreiben von Code das Nachdenken über die Richtigkeit?" und "Erleichtert das Schreiben von Code auf diese Weise die Wiederverwendung?"
Doval

Antworten:

109

Nein , ein Objekt muss keine Entität darstellen.

In der Tat würde ich argumentieren, dass wenn Sie aufhören, Objekte als physikalische Einheiten zu betrachten, Sie endlich die Vorteile erhalten, die OOP verspricht.

Dies ist nicht das beste Beispiel, aber das Design der Kaffeemaschine ist wahrscheinlich der Punkt, an dem das Licht für mich aufleuchtete.

Objekte handeln von Nachrichten. Es geht um Verantwortlichkeiten. Es geht nicht um Autos, Benutzer oder Befehle.

Ich weiß, dass wir OO auf diese Weise unterrichten, aber es wird nach einigen Versuchen deutlich, wie grundlegend frustrierend es ist, herauszufinden, wohin die Dinge gehen, wenn Sie versuchen, MVC, MVVM oder MVWhatever auszuführen. Entweder werden Ihre Modelle lächerlich aufgebläht oder Ihre Controller. Aus Gründen der Navigationsfähigkeit ist es gut zu wissen, dass sich alles, was Fahrzeuge berührt, in der Datei Vehicle.ext befindet. Wenn es sich bei Ihrer Anwendung jedoch um Fahrzeuge handelt, befinden sich zwangsläufig 3000 Zeilen Spaghetti in dieser Datei.

Wenn Sie eine neue Nachricht senden müssen, haben Sie mindestens ein neues Objekt und möglicherweise ein Paar davon. In Ihrer Frage zu einem Bündel von Methoden würde ich argumentieren, dass Sie möglicherweise über ein Bündel von Nachrichten sprechen. Und jeder könnte sein eigenes Objekt sein, mit seiner eigenen Aufgabe. Und das ist in Ordnung. Es wird offensichtlich, wenn Sie Dinge aufteilen, die wirklich, wirklich zusammen sein müssen. Und du hast sie zusammengefügt. Sie legen jedoch nicht jede Methode sofort in eine vage passende Schublade, wenn Sie OO genießen möchten.

Sprechen wir über Taschen voller Funktionen

Ein Objekt kann nur eine Sammlung von Methoden sein und trotzdem OO sein, aber meine "Regeln" sind ziemlich streng.

  1. Die Sammlung sollte eine einzige Verantwortung haben, und diese Verantwortung kann nicht so allgemein sein wie "Tut Sachen für Motoren". Ich mache vielleicht so etwas wie eine Fassade auf Serviceebene, aber ich bin mir sehr bewusst, dass ich aus Gründen der Navigierbarkeit / Entdeckung faul bin, nicht weil ich versuche, OO-Code zu schreiben.

  2. Alle Methoden sollten sich auf einer einheitlichen Abstraktionsebene befinden. Wenn eine Methode Motor-Objekte abruft und eine andere Pferdestärke zurückgibt, liegt das wahrscheinlich zu weit auseinander.

  3. Das Objekt sollte auf der gleichen Art von Daten arbeiten. Dieses Objekt macht Sachen mit Motoren (Start / Stopp), dieses macht Sachen mit Kurbellängen, dieses erledigt die Zündsequenzierung, dieses nimmt eine HTML-Form an. Diese Daten können möglicherweise Felder auf dem Objekt sein und sie scheinen zusammenhängend zu sein.

Ich baue im Allgemeinen Objekte dieser Art, wenn ich Transformationen oder Kompositionen durchführe oder mich nur nicht um die Veränderbarkeit sorgen möchte.

Die Fokussierung auf Objektverantwortung führt mich zum Zusammenhalt. Es muss eine gewisse Kohäsion geben, um ein Objekt zu sein, aber es muss weder Felder noch sehr viel Verhalten geben, damit es ein Objekt ist. Wenn ich ein System bauen würde, das diese 5 Motormethoden benötigt, würde ich mit 5 verschiedenen Objekten beginnen, die diese Dinge tun. Da ich Gemeinsamkeiten gefunden habe, habe ich entweder angefangen, Dinge zusammenzuführen oder allgemeine "Hilfs" -Objekte zu verwenden. Das bewegt mich in offene / geschlossene Fragen - wie kann ich diese Funktionalität extrahieren, damit ich diese bestimmte Datei nie wieder ändern muss, sie aber trotzdem bei Bedarf verwende?

Objekte handeln von Nachrichten

Felder sind für ein Objekt kaum von Bedeutung - das Abrufen und Setzen von Registern verändert die Welt außerhalb des Programms nicht. Die Zusammenarbeit mit anderen Objekten erledigt die Arbeit. Die Stärke von OO besteht jedoch darin, dass wir Abstraktionen erstellen können, sodass wir nicht über alle Details gleichzeitig nachdenken müssen. Abstraktionen, die lecken oder keinen Sinn ergeben, sind problematisch, daher denken wir (vielleicht zu viel) darüber nach, Objekte zu schaffen, die unseren mentalen Modellen entsprechen.

Leitfrage: Warum müssen diese beiden Objekte miteinander sprechen?

Stellen Sie sich das Objekt als ein Organ in einer Person vor - es hat einen Standardzweck und ändert das Verhalten nur, wenn es eine bestimmte Nachricht empfängt, die es interessiert.

Stellen Sie sich ein Szenario vor, in dem Sie sich auf dem Zebrastreifen befinden und ein Auto schnell kommt. Als Gehirnobjekt erkenne ich einen Stressor. Ich fordere den Hypothalamus auf, Corticotropin freisetzendes Hormon zu senden. Die Hypophyse erhält diese Nachricht und setzt das kortikotrophe Hormon der Nebenniere frei. Die Nebennieren erhalten diese Nachricht und erzeugen Adrenalin. Wenn das Muskelobjekt diese Adrenalin-Botschaft empfängt, zieht es sich zusammen. Wenn das Herz die gleiche Nachricht erhält, schlägt es schneller. Es gibt eine ganze Reihe von Akteuren, die mit dem komplexen Verhalten des Sprints auf der anderen Straßenseite befasst sind, und es kommt auf die Botschaften an. Das Gehirnobjekt weiß, wie es den Hypothalamus dazu bringt, den Alarm auszulösen, aber es weiß nicht, welche Kette von Objekten das Verhalten letztendlich auslösen wird. Ebenso hat das Herz keine Ahnung, woher Adrenalin kommt,

In diesem ( vereinfachten ) Beispiel muss das Nebennierenobjekt nur wissen, wie man ACTH einnimmt und Adrenalin produziert. Dazu braucht es keine Felder, aber es scheint mir trotzdem ein Objekt zu sein.

Wenn unsere Anwendung nur zum Sprinten über die Straße konzipiert ist, benötige ich möglicherweise nicht die Hypophyse und die Objekte der Nebenniere. Oder ich brauche nur ein Hypophysenobjekt, das nur einen kleinen Teil dessen leistet, was wir konzeptionell als "Hypophysenmodell" betrachten könnten. Diese Konzepte existieren alle als konzeptionelle Einheiten, aber es ist Software und wir können den AdrenalineSender oder MuscleContractor oder was auch immer herstellen und uns nicht viel über die "Unvollständigkeit" unseres Modells sorgen.

Steve Jackson
quelle
4
Ich bin mit dem tatsächlichen Inhalt dieser Antwort einverstanden, aber ich habe das Gefühl, dass die Frage dadurch falsch verstanden wird. Insbesondere beinhaltet die Frage in Entität "oder ein Konzept, etwas, das gut definiert ist". Gegenbeispiele dazu sind " MotorOperationsoder MotorActions". Aufgrund dessen bin ich ziemlich zuversichtlich, dass sowohl das Originaldesign als auch das Design der letzten Klasse aus dem CoffeeMaker-Beispiel unter die Definition des OP von "Representating a Entity" fallen
Ben Aaronson,
1
Die postmoderne Systemarchitektur DCI bewältigt dies ohne die extremen Abstraktionen, die von strukturbegeisterten Ingenieuren erzeugt werden. Der Computer sollte überlegen, was der Benutzer denkt, und nicht umgekehrt. fulloo.info/doku.php?id=what_is_dci
ciscoheat
@BenAaronson Ich habe das Gefühl, dass Sie sich mit genügend konzertierten Anstrengungen zu diesem Objekt als zusammenhängendem Konzept entwickeln können, aber ich habe die Tendenz gefunden, dass sich eine Einheit darauf konzentriert, Dinge zusammenzudrängen, die getrennt sein sollten. Wesen fördern Grenzen in unseren Namen, was gut ist, aber sie bringen auch diesen Begriff der Richtigkeit / Vollständigkeit mit sich, der dazu neigt, weh zu tun. In den lächerlichsten Ausdrücken bin ich für ein FirstNameValidator-Objekt und gegen ein Name-Objekt, das auch die Validierung für Vor- und Nachnamen durchführt.
Steve Jackson
1
Ein weiteres gutes Beispiel: ericlippert.com/2015/04/27/wizards-and-warriors-part-one
Moby Disk
2
Bei Objekten geht es um Nachrichten - Steve Jacksons Antwort - das ist absolut richtig. MOP ist nicht das, was mit "Messaging" gemeint ist, wie es der Vater von OO Alan Kay gedacht hat, der sagte, die große Idee sei Messaging . Und außerdem tut es mir leid, dass ich den Begriff "Objekte" für dieses Thema vor langer Zeit geprägt habe, weil es viele Leute dazu bringt, sich auf die geringere Idee zu konzentrieren.
Radarbob
21

Können Klassen entitätslose Objekte darstellen? Wenn nicht, warum sind sie schlecht / unvollständig / nicht OOP-zentriert? Gibt es Möglichkeiten, wie sie geändert / verbessert werden müssen?

Kurz gesagt, Sie können alles tun, aber dieses spezielle Szenario würde gegen die OOP-Prinzipien verstoßen :)

Was Sie beschreiben, wird manchmal als "Utility" -Klasse bezeichnet - normalerweise ein Zeichen für Code-Geruch. Sie möchten vermeiden, Klassen zu erstellen, um einige Methoden zusammenzuhalten.

Nicht jedes Objekt in Ihrer Anwendung muss mit einer realen Entität wie einem Motor oder einem Auto verknüpft sein. Das sind Geschäftsobjekte. In Ihrer Anwendung werden Sie wahrscheinlich viele Ihrer Geschäftsobjekte verwenden. Für andere Vorgänge, die nicht zu Geschäftsentitäten gehören, wie die von Ihnen aufgelisteten, ist jedoch eine stärkere Trennung erforderlich.

Sie sollten sich die gängigen Architekturmuster ansehen - eines davon ist MVC (Model-View-Controller) .

Wenn ich die von Ihnen mit MVC aufgelisteten Methoden verteilen würde, würde ich Folgendes tun:

Klasse anzeigen:

  • GetMotorDataFromHTMLForm ()

Modellklasse (Motor im Wesentlichen):

  • GetMotorManufacturer ()
  • CanMotorHandleOperationConditions ()
  • CalculatePowerConsumption ()

Steuerungsklasse (MotorsController):

  • GetAllMotors ()
  • GetMotorById ()
  • GetMotorByUserRequirements ()

Anscheinend verwenden Sie PHP. Ein gutes MVC-Framework zum Anschauen ist Laravel . In ihren Beispielen veranschaulichen sie gut, wozu welche Methoden gehören.

Eine weitere, allgemeinere Informationsquelle für die Entscheidung, wo die Methoden hingehören, sind die GRASP- und SOLID- Prinzipien.

Alexus
quelle
Vielen Dank. Im Wesentlichen scheint mir das, was ich habe, eine Controller-Klasse mit ein paar eingemischten Verunreinigungen (Modell, Ansicht usw.) zu sein. Heißt das , dass , wenn ich umbenennen MotorOperationszu MotorsControllerund reinigen Sie es ein wenig, meine Sammlung von Funktionen in Einklang mit OOP sein wird?
Dennis
@ Tennis, Nicht unbedingt, werfen Sie einen Blick auf meine Methodensammlung unter den einzelnen Klassen. Controller ist keine Klasse, die alles enthält :) Es ist die Klasse, die Operationen auf Ihren Modellen ausführt, und nicht mehr. Die einzigen Abhängigkeiten eines Controllers sind im Allgemeinen direkt DAL (Data Access Layer) oder Dienste, die Ihnen den Zugriff auf DAL ermöglichen. Sie möchten niemals über den Controller auf View zugreifen (Beispiel: getMotorDataFromHTMLForm). Stattdessen sollte Ihre View diejenige sein, die vom Controller abhängig ist.
Alexus
2
Können Sie erläutern, warum eine UtilsKlasse ein Beispiel für Codegeruch ist? Nur neugierig, da ich es genossen habe, zufällige Util-Funktionen in einer UtilsKlasse zu verpacken, anstatt nur eigenständige Funktionen zu sein ... meiner Erfahrung nach macht es Code ein bisschen lesbarer, aber meine Erfahrung ist begrenzt.
HC_
3
@HC_ Eine Utils-Klasse entspricht einem Ordner "Misc" in Ihrer Bildersammlung. Es zeigt an, dass Sie faul waren, Ihren Objekten Verantwortlichkeiten richtig zuzuweisen / möglicherweise fehlende Objekte und Utils zu verwenden, um dies zu kompensieren. Es gibt einen Raum für Util-Klassen, insbesondere mit statischen Funktionen und Erweiterungen für andere Klassen. Bevor Sie jedoch eine solche Sammlung erstellen, prüfen Sie, ob Sie sie in Ihre richtigen OOP-Klassen einbinden können eine Methode. Aber in Zukunft müssen Sie mehr hinzufügen und die Utils-Klasse wird zu einem größeren Durcheinander.
Alexus
Am Ende habe ich oft eine Utils-BIBLIOTHEK, aber normalerweise versuche ich, meine Utils-Klassen ein bisschen aussagekräftiger zu gruppieren und zu benennen. Heutzutage gibt es viele Open-Source-Bibliotheken mit "allgemeinen Hilfsprogrammen", die bereits allgemeine Hilfsprogramme enthalten, die die meisten Leute benötigen. Daher würde ich mich ein wenig umschauen, bevor ich meine eigenen schreibe.
Guy Schalnat
15

Können Klassen entitätslose Objekte darstellen?

Kann? Ja. Sollte? Wahrscheinlich nicht - oder zumindest nicht, wie Sie Dinge ausdrücken.

Objekte sind eigentlich am besten, wenn sie kein physisches Objekt direkt darstellen, da die Realität so selten gut auf den Code abgebildet wird. Sie müssen jedoch ein zusammenhängendes Konzept oder Codeobjekt darstellen. Sie müssen eine einzige zusammenhängende Verantwortung darstellen.

Nur eine Reihe tangential zusammengehöriger Funktionen zu bündeln, ist ein Namespace oder ein Modul - kein Objekt im OOP-Sprachgebrauch. Diese können nützlich sein, aber sie sind nicht gleich und erfordern eine andere Art der Verwendung / des Denkens, um effektiv damit zu arbeiten.

Telastyn
quelle
3
bundling a bunch of tangentially related functions together is a namespace: das klingt eher nach prozeduralem als nach objektorientiertem Paradigma.
Dennis
@dennis - genau (oder funktional, wenn Sie es ein Modul nennen). Das Mischen von Paradigmen kann mächtig sein. Oder es kann furchtbar chaotisch sein.
Telastyn,
Oder beides :) - - - - -
Alexus
@Dennis: Oder auch nicht - nur tangential zusammenhängende Funktionen zu bündeln, ist in jedem Paradigma eine zweifelhafte Praxis.
Sdenham
Ich habe es mit Code zu tun, der als prozedurale Codebasis begann. Irgendwann wurde versucht, es in OOD umzuwandeln, aber meistens wurden Klassen erstellt, um "Funktionen und Methoden zu halten", ohne dass ein tatsächliches OO-Design vorhanden war. Ich habe eine ganze Reihe solcher Dinge entdeckt, die versuchen, die Kluft zwischen den Paradigmen zu überbrücken, aber weder in der einen noch in der anderen sind
Dennis
11

Eine Klasse sollte etwas modellieren - sonst ist es sinnlos. Was modelliert wird, kann jedoch keine physische "Sache" sein; Stattdessen kann es sich um eine Darstellung handeln, die nicht „real“ ist, sondern zur Steuerung des zu modellierenden Systems benötigt wird. In einem Ampelsteuersystem könnten Sie beispielsweise eine Art ControlSignal-Klasse haben, die ein Signal darstellt, das von einem Teil des Systems an einen anderen gesendet wird, um anzuzeigen, dass eine Aktion ausgeführt werden muss. In der "realen Welt" können diese Signale aus elektrischen Impulsen bestehen, die über Kabel von einer Box zur anderen übertragen werden. Der Prozess des Modellierens von etwas, das nicht als konkretes Objekt "real" ist, wird als "Verdinglichung" bezeichnet.

Viel Glück.

Bob Jarvis
quelle
Ja, genau das hätte ich gesagt. Eine Klasse ist nichts anderes als ein Modell für ein Substantiv . Das ist es. Nicht mehr, nicht weniger. Eine Klasse ist ein Substantiv und Methoden sind Verben (oder Nachrichten, wenn Sie es vorziehen). Ein Junior-Ingenieur, der in diesen einfachen Begriffen denkt, kann einen langen Weg zurücklegen, bevor diese Analogien zusammenbrechen (im Gegensatz zu dem Versuch, vorzutäuschen, Klassen seien Beschreibungen physikalischer Objekte - eine Analogie, die bei fast Ihrem ersten Projekt zusammenbricht).
Calphool
7

Nr. (Titel bearbeitet, um die entgegengesetzte Frage zu stellen!)

z.B:

Public class MyRepository
{
    public MyObject GetObject(string id)
    {
        //get data from the DB and build an object
    }
}

oder

Public class MyService
{
    public MyObject3 ProcessData(MyObject1 obj1, MyObject2 obj2)
    {
         //perform a process which is not a sole responsiblity of obj1 or obj2
    }
}

Im Allgemeinen ist es jedoch das Ideal hinter OOP, sich von zu entfernen

public struct Car
{
    public Wheel[] Wheels;
}

public int CountWheelsOnCar(MyCarStruct car)
{
   return car.Wheels.Length;
}

zu

public class Car
{
    private Wheel[] wheels;
    Public int CountWheels()
    {
        return this.wheels.Length;
    }
}
Ewan
quelle
Meinen Sie damit, dass sie Objekte ohne Entität darstellen können? (Siehe den Kommentar, den ich zu der Frage hinterlassen habe.)
Panzercrisis
3
Ich habe OO wohl zu lange programmiert - als ich mir MyRepository ansah, stellte ich mir sofort eine Glasschüssel mit einem Haufen Münzen und Mist auf meiner Kommode vor. Greifen Sie nach einem Cent oder einem Knopf ...
Bill K
@pan ja, wie der Service und das Repo in meinem Beispiel
Ewan
@bill du verrückter alter Narr !!! Das ist die MyButtonAndOrPennyBowl-Klasse! saubere Codierung ftw
Ewan
1
Ihr zweites Beispiel sieht für mich wie eine Funktion aus, die als ein Objekt verkleidet ist, das (meiner Meinung nach) nicht für sich gerechtfertigt ist, obwohl es möglicherweise eine andere Rechtfertigung gibt (z. B. wenn Funktionen keine erstklassigen Entitäten in der Sprache sind). )
sdenham
5

Ich denke, dass es hilfreich ist, etwas in der realen Welt zu visualisieren, wenn man Klassen codiert, aber nicht notwendig ist.

Abhängig davon, wie wörtlich Sie sein möchten, haben viele Objekte, mit denen wir arbeiten, überhaupt keine physischen Darstellungen. Betrachten Sie zum Beispiel die MVC-Architektur. In der realen Welt gibt es weder ein Modell noch einen Controller, obwohl diese im Allgemeinen durch Klassen dargestellt werden. Die drei zusammen repräsentieren oft etwas, aber nicht immer - aber wie gesagt, Sie könnten wahrscheinlich eine Anpassung in etwas erzwingen, wenn Sie wirklich wollen (und sich etwas vorstellen können, das hilft! Ich visualisiere die meisten Objekte auf irgendeine Weise - nur nicht alles Sie würden jemals in der realen Welt sehen).

Meistens sind diese "Regeln", die Sie über OO erfahren, nur Richtlinien, die Sie in das Denken in OO einführen sollen, und nicht unbedingt Dinge, über die Sie sich Sorgen machen, wenn Sie sie einmal täglich zum Codieren verwenden.

Übrigens ist OO selbst kein Allheilmittel und es hilft Ihnen beim ersten Versuch, eine Lösung zu programmieren, nicht viel, aber ich denke, wenn es richtig gemacht wird, ist es eine wirklich fantastische Möglichkeit, Code so zu organisieren, dass es mehr kann später leicht verständlich. Das Schreiben von wartbarem Code ist wahrscheinlich eine der schwierigsten Aufgaben in der Softwareentwicklung und in vielen Fällen (alles, was fortlaufendes Debuggen / Warten erfordert) bei weitem die wichtigste.

Bill K
quelle
5

Muss ein Objekt eine Entität darstellen?

Frage: Welche Einheit Loggervertritt eine?

Nicht metaphorisch - wörtlich.

Bei der Erklärung von OOP ist es hilfreich, Objekte mit Analogien zur physischen Welt zu erklären.

Alan Kay - einer der Väter von OOP - schrieb Folgendes:

[...]

Die ursprüngliche Konzeption hatte die folgenden Teile.

  • Ich dachte an Objekte, die wie biologische Zellen und / oder einzelne Computer in einem Netzwerk sind und nur mit Nachrichten kommunizieren können
  • Ich wollte Daten loswerden.

[...]

OOP bedeutet für mich nur Messaging, lokale Aufbewahrung und Schutz

Verstecken des Staatsprozesses und extreme Spätbindung aller Dinge.

fast unglaubliche HW-Architektur. Mir wurde klar, dass die

Zell- / Ganzcomputer-Metapher würde Daten loswerden

Quelle

Aus diesem Grund werden Objekte am besten als verstanden

  • Autarke Objekte, die Daten kapseln / verstecken

  • Kommunikation mit anderen Objekten über Nachrichten

Können Klassen entitätslose Objekte darstellen?

Auf jeden Fall: Denken Sie an Math


In Bezug auf Ihr Beispiel:

Beispiel: Kann eine Klasse als MotorOperations oder MotorActions bezeichnet werden, wenn keine Entität vorhanden ist, die Methoden in der Klasse jedoch ähnliche Aufgaben ausführen?

  • getMotorDataFromHTMLForm ()

  • getMotorManufacturers ()

  • selectMotorFromUserRequirements ($ requirements)

  • canMotorCanHandleOperatingConditions ($ conditions)

  • computePowerConsumptionForMotor ($ id)

Um zu entscheiden, wo diese Methoden zu setzen, haben Sie einen Blick nehmen an responsibilities: wer für was respnsible ist .

getMotorDataFromHTMLForm ()

Der Kontext eines solchen Verfahrens wäre die Konstruktion eines Motorobjekts . Es liegt nicht in der Verantwortung des Motors, sich aus Daten zu erstellen, die über ein Formular abgerufen werden . Es sind mindestens zwei Objekte beteiligt; Einer ist der Motor und der andere ist der Schöpfer des Motors .

getMotorManufacturers ()

Der typische Kontext, in dem man eine solche Methode schreiben würde, ist a service.

selectMotorFromUserRequirements ($ requirements)

Dies würde auch in einem service-Kontext verwendet

canMotorCanHandleOperatingConditions ($ conditions)

Dies ist eine Frage an ein motor-Objekt

computePowerConsumptionForMotor ($ id)

Auch dies ist eine Frage, die sich ein Motor am besten stellt.


tl; dr

Die Metapher objectsals physikalisch Objekte ist ärgerlicher als hilfreich.

Thomas Junk
quelle
Wow, deine Antwort haucht OOP Leben ein! Ich muss sagen, dass ich nicht physisch als Ende des Ganzen gedacht habe. Die Absicht meiner Frage war eher, "Muss ein Objekt ein Objekt thingmit Daten sein, bei dem Daten eindeutig zu dem Objekt gehören und Funktionen, die eindeutig auf die Daten wirken, die zu dem Objekt gehören ". Logger ist in diesem Fall zwar keine physische Sache, aber ein Konzept, das dem eines "physischen Logbuchs" ähnelt. Ob es hat Daten , den Kern in seinen Zustand ist, und nicht nur vorübergehende darauf, dass bei der Umsetzung und Auslegung abhängen kann .. und ist mehr so , wo meine Frage würde ..
Dennis
Aber ja, Antworten mussten meine körperliche Voreingenommenheit ansprechen
Dennis
3

Ja, das kannst du. Sie erstellen jedoch im Wesentlichen eine Klasse, die dieselbe Funktionalität wie eine prozedurale Bibliothek bietet. Der einzige Grund dafür ist, dass Ihre Sprache keine prozeduralen Module enthält (z. B. Java oder Ruby).

In einer Sprache mit prozeduralen Modulen (ich denke, PHP hat prozedurale Module) können Sie auch nur ein prozedurales Modul verwenden.

Sie können Ihre Klasse auch neu entwerfen, damit eine Instanz der Klasse ein zusammenhängendes Objekt darstellt.

Aber benutze die OO-Notation nur, wenn sie dir zusätzliche Kraft verleiht, nicht nur, um OO zu sein!

Jonathan Cast
quelle
3

In den Wörtern des Laien

  • Was Sie beschreiben, wird Utility-Klasse genannt.
  • Es hat keinen Status, was bedeutet, dass Sie nie mehrere Instanzen davon benötigen werden
  • Alle Methoden sind statisch, dh Sie müssen alles als Parameter übergeben

Es gibt solche Klassen, zum Beispiel das Java SDK verfügt über die Collections-Klasse, die ausschließlich aus statischen Methoden besteht, die Sammlungen verarbeiten oder zurückgeben.

Die Antwort wäre also nein, nicht alle Klassen müssen von einer Domänenentität modelliert werden.

Andererseits sind solche Klassen nur wenige oder sollten es nur wenige in einem Programm sein, das in einer OOP-Sprache erstellt wurde, da die wahre Kraft von OOP in Polymorphismus und Kapselung liegt.

Es wäre, als würde man ein Flugzeug benutzen, um von einem Ort zum anderen zu fliegen, und nicht, indem man es auf Autobahnen herumfährt. Flugzeuge haben Räder wie Autos, aber sie sollen fliegen.

Tulains Córdova
quelle
2

Nein, eine Klasse repräsentiert lediglich etwas, das instanziiert werden kann, Mitglieder hat und von dem geerbt werden kann.

In der Tat kann Ihre Sprache statische Klassen haben, die nicht einmal mehr als einmal instanziiert werden.

.NETMath ist ein großartiges Beispiel für eine "professionelle" Klasse, die keine Entität repräsentiert (es sei denn, Sie möchten eine philosophische Vorstellung davon haben, was Mathematik ist ...) und die auch einen legitimen Anwendungsfall einer solchen Klasse darstellt. Es hat nur Methoden und 2 Felder (beide repräsentieren einzelne Konstanten).

Die Klassenhierarchie einer ähnlichen Bibliothek Math.Netgruppiert mathematisch / numerische Methoden nach Typ in Klassen. Hier repräsentieren Klassen keine Entität, sondern eine logische Kategorie.

Ich selbst schaffe oft (statische) Klassen, die nichts anderes sind als eine Menge verwandter (statischer) Funktionen oder eine Reihe von Konstanten, die bequemerweise an einer zentralen Stelle gruppiert sind. Ich würde nicht behaupten, dass dies gutes Design ist, aber manchmal ist es die einfachste Lösung.

Super
quelle
1
Die Tatsache, dass die mathematikbezogenen Methoden in .NET / BCL als statische Methoden in eine separate Klasse gestellt werden, ist keine Notwendigkeit oder Entwurfsüberlegung, sondern die Folge der Tatsache, dass in C # keine freistehenden Methoden vorhanden sind. In C ++ könnten solche Funktionen einfach in einem Namespace zusammengefasst werden.
Vlad
1

Die Antworten auf Ihre Fragen hängen letztendlich davon ab, wie genau man Begriffe wie "Klasse" und "Entität" definiert. Sie haben letztere gut definiert und dabei sowohl physische als auch konzeptionelle Entitäten zugelassen. Aber der Begriff "Klasse" für Puristen wird immer "eine Fabrik zum Instanziieren von Objekten mit einer bestimmten internen Repräsentation" sein, und für Pragmatiker umfasst der Begriff jene Java- oder C ++ - Dinge, die von Puristen verachtet werden. Das Gleiche gilt für den Begriff "OOP", den Pragmatiker für Java und C ++ halten, aber für Puristen, was Alan Kay mit "objektorientiert" meinte habe C ++ im Sinn "] ( Also, was * hat * Alan Kay wirklich mit dem Begriff" objektorientiert "gemeint? ).

Wenn Sie die pragmatistische Ansicht vertreten, können Sie Ihre instanzlosen Dienstprogrammklassen akzeptieren. Aber die puristische Sichtweise ist interessanter. Laut Kay ging es bei OOP immer mehr um die Botschaften als um die Klassen. Also zu deinen Fragen:

Können Klassen entitätslose Objekte darstellen?

Klassen klassifizieren Objekte. Klassen sind per Definition diejenigen Entitäten, an die Sie eine Nachricht senden new, um beispielsweise ein Objekt zu erzeugen. Ein Objekt ist eine Entität aus einer Klasse. Klassen existieren, um Objekte herzustellen und tatsächlich zu klassifizieren. Das ist, was Klassen tun. Klassen machen Objekte. Wir verwenden Klassen, um Objekte zu klassifizieren. Wenn C also nur ein Bündel von Methoden ist , die keine Instanziierung oder Unterklassen zulassen, können keine Objekte durch C klassifiziert werden, sodass C keine Klasse ist.

Wenn nicht, warum sind sie schlecht / unvollständig / nicht OOP-zentriert?

Sie sind nicht schlecht. Nenn sie einfach nicht Klassen. Ein Bündel von Methoden ist OOP-fähig: etwas, an das Sie eine Nachricht senden könnten, um eine Methode aufzurufen, aber es ist keine Klasse, es sei denn, sie kann ein Objekt instanziieren. Kennst du Ruby? In Ruby ist ein Modul ein Bündel von Methoden. Eine Klasse ist ein Modul, das Objekte instanziieren kann. An einem Modul ist nichts Schlimmes . Aber das, was eine Klasse von einem Modul unterscheidet (in reinen OOP-Begriffen), ist, dass eine Klasse Instanzen haben kann. Ein Modul ist nur ein paar Methoden. Die Verwirrung ist, dass C ++ und Java und andere Sprachen den Begriff "Klasse" sowohl für die Klasse als auch für das Modul verwenden .

Um sich eines Ihrer konkreten Beispiele anzusehen, fragen Sie nach einer MotorOperationsKlasse, an die Sie die Nachricht computePowerConsumptionForMotormit Argument senden können id. Ist das schlecht? Zumindest verstößt es nicht gegen das Tell Don't Ask-Prinzip . Haben wir haben einen Motor Klasse machen und sie die senden powerConsumptionNachricht? Vielleicht nicht 100% der Zeit, aber vielleicht führt der Versuch, solche Dinge zu tun, zu netten Einsichten über Ihren Code. Oder es kann zu einer Explosion kleiner Klassen führen, was schlecht wäre.

Gibt es Möglichkeiten, wie sie konzeptionell geändert / verbessert werden müssen, um mit OOP übereinzustimmen?

Wenn es Ihnen wichtig ist, OOP durchzuführen, sollten Sie nach Möglichkeiten suchen, ein System in Komponenten zu zerlegen, die miteinander kommunizieren, indem Sie Nachrichten aneinander senden. Das ist genau das, was OOP ist , oder zumindest, was der Coiner des Begriffs im Sinn hatte. Dienstprogrammklassen sind in dieser Ansicht nicht OOP. Aber für manche Menschen sind sie vielleicht.

Der Versuch, aus Millionen von lebenden, atmenden und aus Klassen instanziierten Objekten ein ganz großes System zu machen, könnte für einige Projekte funktionieren. Wenn Sie jedoch künstliche, falsch klingende Klassen erstellen, sollten Module eingeführt werden. Versuchen Sie, Klassen hervorzuheben und Module zu verwenden, wenn instanziierbare Klassen lächerlich wären.

TL; DR-Methodenpakete sind nicht immer schlecht. Versuchen Sie zunächst, instanziierbare Klassen zu verwenden. Greifen Sie nur bei Bedarf auf "Module" zurück.

Ray Toal
quelle
0

Nehmen Sie die angegebenen Beispiele:

getMotorDataFromHTMLForm()
selectMotorFromUserRequirements($requirements)

Diese sehen aus wie "Factory" -Methoden, die ein MotorObjekt zurückgeben würden. Die zweite impliziert, dass Sie entweder ein neues Objekt erstellen, um die Anforderungen zu erfüllen, oder dass Sie über eine Datenbank oder eine speicherinterne Sammlung von Motoren verfügen, die Sie untersuchen. In diesem Fall sollte dies eine Methode sein. Oder es könnte eine Methode für das Anforderungsobjekt sein.

getMotorManufacturers()

Woher holst du sie? Das ist es, wofür dies eine Methode sein sollte.

canMotorCanHandleOperatingConditions($conditions)
computePowerConsumptionForMotor($id)

Diese scheinen Methoden zu sein Motor.

pjc50
quelle
Ja. es ist ein "Bündel von möglicherweise nicht verwandten Methoden" (kurz BOPUM). Ich stimme den Werks- und Motorkommentaren zu. getMotorManufacturersist es, alle Motorhersteller aus der Datenbank zurückzugeben. Ich bin mir nicht sicher, wohin das führt. Ich werde einige Zeit brauchen, um diese BOPUM zu entwirren und die Dinge dorthin zu bringen, wo sie gebraucht werden.
Dennis,
Ich komme getMotorManufacturersaus der Datenbank. Datenbank kann keine Methode haben ... Derzeit habe ich ein DataMapper-Muster, das die Datenbank abfragt, ein Array initialisiert und mit Motor Objects (die auch Herstellerinformationen enthalten) auffüllt und dieses Array dann an den Aufrufer zurückgibt. Der Anrufer ist meine MotorOperationsKlasse, die wiederum von einer ProductSelectionKlasse aufgerufen wird (die einen Algorithmus enthält, der zur Auswahl von Motoren verwendet wird, und die geladenen Motorinformationen sind die Daten für diesen Algorithmus)
Dennis
0

Ein Objekt ist eine Sammlung von Methoden und Daten, die eine hohe Kohäsion aufweisen. Sie gehören in eine Klasse, weil sie eng miteinander verbunden sind und der Zustand erhalten bleibt.

Dies gilt unabhängig davon, ob Sie im Voraus ein großes Design verwenden und versuchen, alles zu modellieren, oder ob Sie ein neues Design erstellen, bei dem Sie das Objekt iterieren und so weiterentwickeln, dass es den jeweiligen Anforderungen des Systems entspricht.

Wenn Sie keinen Grund haben, den Status beizubehalten, haben Sie wahrscheinlich keinen Grund, ein Objekt zu instanziieren, was bedeutet, dass es wahrscheinlich keinen Grund gibt, eine Klasse zu haben. Es sei denn, die von Ihnen verwendete Sprache kann keinen anderen Namespace als class definieren. In welcher Klasse sollte es gut sein, denn es wäre idiomatisch.

Ich kann mir keine negativen Aspekte vorstellen, wenn ich Klassen auf diese Weise verwende, die nicht typisch sind. Sie laden unnötige Kosten und Komplexität ein, indem Sie einen "Namespace" instanziieren müssen. Jeder, der diesen Code unterstützt, wird sich fragen, wo die Daten zusätzliche kognitive Belastung kosten (höchstwahrscheinlich einmalige Kosten pro Person). Es ist eine ungewöhnliche Verwendung ohne zusätzlichen Wert.

dietbuddha
quelle