2010-04-11 5 views
7

Ich lerne viel über Designmuster, wenn ich ein eigenes System für meine Projekte erstelle. Und ich möchte Sie zu einer Designfrage fragen, auf die ich keine Antwort finden kann.Zwei Objekte mit Abhängigkeiten füreinander. Ist das schlecht?

Derzeit baue ich einen kleinen Chat-Server-Sockets verwenden, mit mehreren Clients. Im Moment habe ich drei Klassen:

  1. Person-Klasse, die Informationen wie Nick, Alter und einem Raum-Objekt enthält.
  2. Zimmer-Klasse, die Informationen wie Raumname, Thema und eine Liste von Personen zur Zeit in diesem Raum hält.
  3. Hotels-Klasse, das eine Liste von Personen und eine Liste der Zimmer auf dem Server.

ich ein Diagramm habe es zu verdeutlichen:

ich eine Liste von Personen, die auf dem Server der Hotel-Klasse, weil es schön wäre, um zu verfolgen, wie viele es gleich online ist jetzt (ohne durch alle Räume iterieren zu müssen). Die Personen leben in der Hotelklasse, weil ich gerne nach einer bestimmten Person suchen würde, ohne die Zimmer zu durchsuchen.

Ist das schlechte Design? Gibt es einen anderen Weg, es zu erreichen?

Danke.

Antwort

4

Die gegenseitige Abhängigkeit Problem unter den Klassen, streng genommen, können mit Schnittstellen (abstrakte Klassen, wenn Sie die Sprache beispielsweise C++ oder Python) gelöst werden IRoom und IPerson; in Pseudo-Code

interface IPerson 
    IRoom getRoom() 
    // etc 

interface IRoom 
    iter<IPerson> iterPerson() 
    // etc 

das macht nur das Schnittstellen gegenseitig voneinander abhängig - das tatsächliche Implementierungen der Schnittstellen benötigen hängen nur von den Schnittstellen.

Dies gibt Ihnen auch viel Spielraum in Bezug auf die Umsetzung, wenn Sie kreisförmige Referenzschleifen vermeiden wollen (die ein Ärgernis sein können z.B.in CPython durch Verlangsamen von Garbage Collections) - Sie könnten schwache Referenzen, eine zugrunde liegende relationale Datenbank mit einer typischen "one to many relationship" -Tabelle usw. verwenden. Und für den ersten einfachen Prototyp können Sie verwenden, was in der von Ihnen gewählten Sprache am einfachsten ist (wahrscheinlich einfach, und ach notwendigerweise kreisförmig, Referenzen [[Zeiger in C++]] mit einem Person Bezugnahme auf ein Room und ein Room zu einem list<Person>).

+1

Ich sehe "gegenseitige Abhängigkeit" ist das Wort, das ich suchte. Für den Rekord schreibe ich das in Java. Der Interface-Ansatz scheint interessant zu sein, macht aber die Lösung nicht viel unterschiedlicher, aber ich verstehe Ihren Standpunkt. Danke für deinen Kommentar. –

+2

@Kasper, Punkt ist, gibt es kein wirkliches Problem mit Abhängigkeiten von _interfaces_ mit (einschließlich dem gegenseitigen ist) - es ist vor allem Abhängigkeiten von _concrete_ Software, die Sie wirklich vermeiden wollen (zum Beispiel im Fall von „Loops“). Die Freiheit, mit einer schnellen und schmutzigen Implementierung zu beginnen und später zu einem solideren zu wechseln, beschleunigt auch die Entwicklung und Wartung von Software-Prototypen und -Iterationen. –

9

Ich mag es nicht. Ein Hotel enthält Zimmer und Zimmer enthalten Menschen. Menschen enthalten keine Räume, sie gehören ihnen an.

Sie müssen nicht unbedingt wiederholen Sie Ihre Gastzählimpuls zu bekommen. Sie können einfach eine laufende Zählung ($ Hotel-> total_guests) behalten und sie ändern, während sie sich ändert.

+0

Ich verstehe, was Sie sagen, dass es einen Fehler in meiner Logik gibt, danke, dass Sie darauf hingewiesen haben! Ich dachte jedoch, dass eine HashMap, die den Benutzernamen und das Person-Objekt enthält, viel schneller wäre, um nach einem Benutzer zu suchen, als durch Rooms zu iterieren. –

+4

Ich weiß Ihre Lust auf Millisekunden zu schätzen, da ich diese Leidenschaft teile - aber eine tolle OOP ist das schnellere/sauberere Lesen und Schreiben von Code, nicht die schnellere Ausführungszeit. Ich würde vorschlagen, Sie versuchen es in beide Richtungen und Zeit - die Unterschiede werden wahrscheinlich nicht so groß sein, wie Sie denken. (Wenn Sie dies tun, bitte posten Sie Ihre Ergebnisse für uns!) –

+0

Sie haben mich! Dieser Kommentar über Lust auf Millisekunden ist genau richtig. Sie haben mir etwas zum Nachdenken gegeben, danke :) –

1

In einem größeren System, wäre es schlecht sein, aber da von dem, was ich Ihre Anwendungen verstehen, diese drei Klassen nur gemeinsam verwenden, ist es ein Problem, nicht viel. Stellen Sie sicher, dass die Mitgliedsvariablen der Person so benannt werden, dass sie einen Verweis auf einen Raum und nicht auf eine Instanz enthalten.

Außerdem, es sei denn, es ist aus Performance-Gründen (z. B. Sie haben eine große Anzahl von Räumen), wäre es wahrscheinlich sauberer, eine Eigenschaft oder Getter, die über die Räume iterieren und sammeln die Personen, anstatt sie zu cachen das Hotel.

+0

Für das Protokoll, ich stimme zu, dass sie als Eigentum des Hotels Caching ist wahrscheinlich nicht der beste Weg, um darüber zu gehen. Persönlich würde ich auch iterieren;) –

+0

Wie würden Sie die Mitgliedsvariablen in Person nennen, also wäre es mehr wie eine Referenz? Angenommen, ich habe eine große Anzahl von Benutzern und muss nach einem einzelnen Benutzer suchen. Was wäre der beste Weg? Ich weiß, dass ich redundante Informationen in Referenzen aufbewahre. Diese Klassen werden nur zusammen verwendet (Es gibt ein paar mehr, aber nicht viele). –

0

Gegenseitige Abhängigkeit ist in seinem eigenen Recht nicht schlecht. Manchmal erfordert die Datennutzung es.

ich darüber nachdenke, in einer anderen Art und Weise. Es wird einfacher sein, Code zu pflegen, der im Allgemeinen weniger Beziehungen hat - gegenseitige Abhängigkeit oder nicht. Halte es einfach so einfach wie möglich. Die einzige zusätzliche Schwierigkeit bei Ihrer Situation besteht darin, dass es manchmal ein Problem mit dem Check und dem Ei gibt, während Sie Sequenzen erstellen und löschen. Du hast mehr Links zum Buchladen.

Wenn Sie gefragt sind, ob Sie in diesem Fall eine Liste von Personen, die auf ein Hotel brauchen, ich glaube, es gibt zwei Antworten. Ich würde damit beginnen, dass Ihre Objekte (im Speicher) diese Beziehungen liefern, aber Sie brauchen KEINE zusätzliche Join-Tabelle zwischen Personen und Hotels in der Datenbank. Wenn Sie Hibernate verwenden, wird automatisch ein effizienter Join für Sie generiert, wenn Sie nach den Personen in einem Hotel fragen (es wird Hotels auf rooms.hotel_id für Sie beitreten).