Ankündigung

Einklappen
Keine Ankündigung bisher.

Klassenschnittstellen

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Klassenschnittstellen

    Hallo,

    ich bin dabei ganz grob nach den Vorbild Facebook-Neuigkeiten (persönliche Startseite) bestimmte Aktionen als "News" (Streams) zu posten. Ein Stream kann eine News, ein Benutzerstatus, das Anlegen/Bearbeiten eines Teams/Gruppe etc. sein. Ein Stream definiert sich also sowohl nach verschiedene Klassen/Datenbanktabellen als auch Aktionen.

    Beispiel:
    - Benutzer [B1] hat das Team [T1] erstellt.
    - Firmennews (von [B2]): "großartige Neuigkeiten" ([mehr...])
    - Im Gruppenforum [FG1] wurde ein neues Topic [FT1] von [B3] angelegt.
    - [B4] hat die Gruppe [G2] wurde bearbeitet.

    Die eckigen Klammern symbolisieren Hyperlinks. Folgendes Layout habe ich dabei gewählt, es funktioniert auch. (Was mir nicht gefällt erläutere ich gleich, daran schließt sich dann auch meine Frage nach dem besten Softwareentwurf dafür an.)



    Uploaded with ImageShack.us

    für Beispiel 1 (oben) also:
    Code:
    stream
    id = 1
    user_id = 123 (Session-User-ID)
    type = "team.insert"
    text = "%s hat das Team %s erstellt."
    
    stream_var (1:n zu stream)
    stream_id = 1
    type = "db-table"
    key = "team"
    value = 456 (Team-ID)
    text = '<a href="/team/view/456">Super Team</a>'
    Per sprintf() wird dann der Text zusammengesetzt:
    "[Chriz] hat das Team [Super Team] erstellt.";

    Dazu habe ich einfach meiner News-/Team-/Benutzer/.. Klasse ein Interface verpasst, so dass es "Streamable" wird. Nun gefällt mir das aus mehreren Gründen nicht.

    1.) Jede Klasse, die ich Streamable machen möchte, muss erweitert werden. Das widerspricht meiner Meinung nach dem Single-Responsibility-Prinzip (wobei mir der Gedanke kam, dass Interfaces im Allgemeinen diesem Prinzip widersprechen). Wäre ein Decorator/Proxy ein besseres Designpattern, um die Verbindung zwischen einer beliebigen Klasse und einem Streameintrag herzustellen?

    2.) Durch das Interface muss ich ja nun den Inhalt des Streamtextes definieren. Um es schön zu formatieren benötige ich HTML. HTML in Klassen ist schlecht.

    3.) Jede Änderung, jeder Statuswechsel, jede News erzeugt nicht nur einen Eintrag in der eigenen Tabelle, sondern auch in "stream" und "stream_var". Das ist inkonsistent, vor allem wenn ich nun News bearbeite, muss ich ja gleichzeitig auch den Eintrag im Stream wiederfinden und aktualisieren (Content ändern oder als "obsolete" markieren). Kann ich zwar, gefällt mir aber nicht.

    Was für ein Datenbankmodell ist denn sinnvoll und wie kann ich beliebige Klassen mit dem Stream koppeln, ohne die Abhängigkeiten per Interfaces so dämlich zu erhöhen?

    Am liebesten wäre es mir, wenn die Ausgabe eines Streameintrages über einen View/ein Template laufen würde, so dass Änderungen am Template auch rückwirkend Einfluß haben. Sollte ich dazu den Template-Pfad in der Stream-Tabelle speichern?

    Warum ich übrigens stream_var verwendet habe ist, damit ich später die "Einzelteile" noch kenne, sprich das ich keine Statusmeldungen von Kollegen bekomme, die für mich garnicht relevant sind. Das heißt ich brauche zwingend die Informationen darüber welche Variablen an dem Stream beteiligt sind, so dass ich später die Ausgabe filtern kann.

    Edit: Achso wichtig, was ich noch vergessen hatte und *für* die Felder "Text" spricht ist das eine doppelt gestreamte Änderung (B1 hat T1 geändert, danach hat B2 T1 umbenannt) ja nun dort die Änderung von B1 rückwirkend mit dem neuen Titel versehen wird, wenn ich den Text des Streams nur stumpf "verlinke". Das ist natürlich nicht gewünscht. Eine Versionierung von Änderungen allerdings auch nicht. Hm schwierig.
    "Mein Name ist Lohse, ich kaufe hier ein."


  • #2
    1.) Also dem Single-Responsibility-Prinzip widersprechen Interfaces nicht generell. Ist eben genau wie bei allem anderen eine Frage der Verwendung. Bsp. das Interface Serializable (gibt's das in PHP überhaupt? *grübel*), würde ja auch niemand als Verstoß gegen das Prinzip werten (oder?).

    2.) Die Alternative wäre doch meines Erachtens, dass die Klasse ein Stream-Widget (oder Komponente oder wie man es auch immer nennen mag) zurück gibt. Verschiedene Widget-Typen dann über Vererbung. Dann hättest du das HTML (falls du überhaupt so viel davon brauchst) wenigstens in nur in den Widget-Klassen und nicht in deinen Daten-Klassen. Und Micro-Templates könntest du auch benutzen.

    3.) Wieso ist das Inkonsistent? Mit was? Es gibt nun mal nur zwei Möglichkeiten: Letzten Stream suchen und aktualisieren (Race Condition?) oder eben immer einen neuen anlegen. Ich persönlich würde zu letzterem tendieren, da auch wenn es in jedem Meeting heißt "Wir brauchen keine Versionierung", fragt irgendwann doch jemand, ob denn der Verlauf aufgezeichnet wurde. Das hättest du mit den Streams sauber abgehandelt.

    Zum Rendering via Template siehe 2). Ich benutze bei mir immer einen komponentenbasierten Ansatz. Kommt wahrscheinlich daher, da dass bei Desktop-Programmierung schon immer so war

    Kommentar


    • #3
      Hallo mquadrat,

      danke für deine Antwort. Was ist denn bei dir ein Widget? Eine Helferklasse?

      Ich habe es jetzt so gelöst, dass das Interface nur eine Beschreibung und einen Dump anfordert, keine Darstellung. Die übernimmt ein Template. Im Moment funktioniert das gut und ich bin auch zukünftig relativ flexibel, hoffe ich zumindest.
      "Mein Name ist Lohse, ich kaufe hier ein."

      Kommentar


      • #4
        Ich suche dafür noch die richtige Bezeichnung Eine Klasse, deren einziger Zweck es ist ein Control zu rendern (bei Webseiten halt als HTML).

        Bei der Desktop-Programmieren schimpft sich sowas immer Komponente. Daraus kann man sich dann theoretisch via Composite-Pattern einen ganzen View zusammen basteln.

        Kommentar

        Lädt...
        X