Versionen von Plugins.Spezifikation-components

Unwichtige Korrekturen ausblenden - Änderungen im Wiki Quelltext

 
 
20.05.2008 13:07 Uhr von mlunzena -
Zeilen 71-73 hinzugefügt:

Singleton-Instanz

Zeilen 80-82 hinzugefügt:

Komponenten anmelden

Zeilen 92-94 hinzugefügt:

Komponenten abmelden

Zeilen 104-106 hinzugefügt:

Komponenten eines Komponenteninterfaces finden

Zeilen 120-122 hinzugefügt:

Mitteilung an alle Komponenten eines Komponenteninterfaces

 
 
20.05.2008 13:02 Uhr von mlunzena -
Zeile 124 bearbeitet:
geändert in:
 
 
20.05.2008 13:02 Uhr von mlunzena -
Zeile 124 bearbeitet:
geändert in:
 
 
20.05.2008 13:00 Uhr von mlunzena -
Zeile 73 bearbeitet:
  $manager = Studip_ComponentManager::instance();
geändert in:

$manager = Studip_ComponentManager::instance();

Zeilen 79-80 bearbeitet:
  $manager = Studip_ComponentManager::instance();
  $manager->register('ExampleComponent');
geändert in:

$manager = Studip_ComponentManager::instance(); $manager->register('ExampleComponent');

Zeilen 88-89 bearbeitet:
  $manager = Studip_ComponentManager::instance();
  $manager->deregister('ExampleComponent');
geändert in:

$manager = Studip_ComponentManager::instance(); $manager->deregister('ExampleComponent');

Zeilen 97-98 bearbeitet:
  $manager = Studip_ComponentManager::instance();
  $components = $manager->components('ExampleComponent');
geändert in:

$manager = Studip_ComponentManager::instance(); $components = $manager->components('ExampleComponent');

Zeilen 100-105 bearbeitet:
  # use those components
  $result = array();
  foreach ($components as $component) {
    $result[] = $component->exampleMethod(42);
  }
  […]
geändert in:
  1. use those components

$result = array(); foreach ($components as $component) {

  $result[] = $component->exampleMethod(42);

} […]

Zeilen 111-112 bearbeitet:
  $manager = Studip_ComponentManager::instance();
  $manager->signal('TodoComponent', 'todoAdded', array($arg1, $arg2, $arg3));
geändert in:

$manager = Studip_ComponentManager::instance(); $manager->signal('TodoComponent', 'todoAdded', array($arg1, $arg2, $arg3));

 
 
20.05.2008 13:00 Uhr von mlunzena -
Zeilen 94-115 bearbeitet:

Um alle Komponenten zu erhalten, die ein bestimmtes Komponenteninterface implementieren,

geändert in:

Um alle Komponenten zu erhalten, die ein bestimmtes Komponenteninterface implementieren, sendet man #components an den Komponentenmanager:

(:source lang=php linenum:)
  $manager = Studip_ComponentManager::instance();
  $components = $manager->components('ExampleComponent');

  # use those components
  $result = array();
  foreach ($components as $component) {
    $result[] = $component->exampleMethod(42);
  }
  [...]

Gelegentlich will man an allen Komponenten eines Komponenteninterfaces nur eine Methode aufrufen, ohne dass man deren Rückgabewert benötigen würde – wenn man den Komponenten also nur etwas "mitteilen" will. Für diesen Fall kann man #signal senden:

(:source lang=php linenum:)
  $manager = Studip_ComponentManager::instance();
  $manager->signal('TodoComponent', 'todoAdded', array($arg1, $arg2, $arg3));
 
 
20.05.2008 11:02 Uhr von mlunzena -
Zeilen 53-94 hinzugefügt:

Der Komponentenmanager definiert u.a. folgende Methoden:

(:source lang=php linenum:)
<?php

class Studip_ComponentManager {

  static function instance();

  function register($component);
  function unregister($class);

  function components($interface_name, $filter = NULL);
  function signal($interface_name, $method, $args = array());
}

Die Klassenmethode #instance liefert die Singleton-Instanz des Komponentenmanagers:

(:source lang=php linenum:)
  $manager = Studip_ComponentManager::instance();

An dieser Instanz kann dann eine Komponente mittels ihres Namens registriert werden:

(:source lang=php linenum:)
  $manager = Studip_ComponentManager::instance();
  $manager->register('ExampleComponent');

Achtung: Es muss sichergestellt werden, dass der Quellcode der benannten Komponente bereits geladen ist. Da der Komponentenmanager die Komponente nicht untersuchen kann.

Auf ähnliche Weise kann eine Komponente auch wieder beim Komponentenmanager abgemeldet werden:

(:source lang=php linenum:)
  $manager = Studip_ComponentManager::instance();
  $manager->deregister('ExampleComponent');

Auch hier gilt, dass der Quellcode der Komponente geladen sein muss.

Um alle Komponenten zu erhalten, die ein bestimmtes Komponenteninterface implementieren,

 
 
20.05.2008 10:52 Uhr von mlunzena -
Zeile 17 hinzugefügt:
Zeilen 37-38 bearbeitet:

Dieses Komponenteninterface repräsentiert die "Steckdose", in die sich eine Komponente "einstöpseln" kann. Das "Einstöpseln" geschieht durch das Schreiben einer Klasse, die dieses Interfaces implementiert ("class ExampleComponent implements Studip_PortalComponent"). Diese Klasse muss noch beim im Folgenden beschriebenen Komponentenmanager registriert werden.

geändert in:

Ein Komponenteninterface definiert eine Menge von Operationen, die eine Komponente ausführen können muss. (Beispiel: Einen Text für eine Box innerhalb der Stud.IP-Homepage liefern.)

Idealerweise werden Komponenteninterfaces eine feine Granularität aufweisen. Ein Gegenbeispiel ist das implizite Interface der alten Homepage-Plugins.

Komponenteninterfaces müssen ihrerseits das Markerinterface "Studip_Component" implementieren, damit der Komponentenmanager in die Lage versetzt wird, automatisch zwischen normalen Interfaces und Komponenteninterfaces unterscheiden zu können. Es ist ja immer möglich, dass eine Komponente auch Interfaces implementiert, die nichts mit der Komponentenarchitektur zu tun haben.

Komponenten

Komponenteninterfaces repräsentieren die "Steckdose", in die sich eine Komponente "einstöpseln" kann. Das "Einstöpseln" geschieht durch das Schreiben einer Klasse, die dieses Interfaces implementiert ("class ExampleComponent implements Studip_PortalComponent"). Ausserdem muss diese Klasse – die Komponente – beim weiter unten beschriebenen Komponentenmanager registriert werden.

Zeilen 51-56 bearbeitet:

Der Komponentenmanager ist für zwei Aufgaben zuständig. Zum einen können bei ihm Komponenten angemeldet und abgemeldet werden, zum anderen kann man über ihn alle Komponenten erhalten, die ein bestimmtes Komponenteninterface ("Steckdose") implementieren, um dann an diesen die im Komponenteninterface deklarieren Methoden aufzurufen. Da man nur Komponenten erhält, die dieses Komponenteninterface implementieren, kann man sicher sein, dass diese Methoden auch tatsächlich zur Verfügung stehen, da der Compiler dieses zusichert — schliesslich muss eine Komponente ja das Komponenteninterface implementieren ("implements").

  • Wir brauchen ein Interface (Studip_Component) zur Kennzeichnung von Komponenteninterfaces.
  • Ein Komponenteninterface definiert eine Menge von Operationen, die ein Plugin ausführen können muss, wenn es eine solche Komponente sein möchte. (Beispiel: Einen Text für eine Box innerhalb der Stud.IP-Homepage liefern.)
  • Diese Komponenteninterfaces sollten eher feingranular sein (Gegenbeispiel: Homepage-Plugin mit seinen zahlreichen Konfigurationsmöglichkeiten.).
geändert in:

Der Komponentenmanager ist für zwei Aufgaben zuständig. Zum einen können bei ihm Komponenten angemeldet und abgemeldet werden, zum anderen kann man über ihn alle Komponenten erhalten, die ein bestimmtes Komponenteninterface ("Steckdose") implementieren, um dann an diesen die im Komponenteninterface deklarieren Methoden aufzurufen. Da man nur Komponenten erhält, die dieses Komponenteninterface implementieren, kann man sicher sein, dass diese Methoden auch tatsächlich zur Verfügung stehen, da der Compiler dieses zusichert.

TODO

 
 
20.05.2008 10:44 Uhr von mlunzena -
Zeilen 17-18 bearbeitet:

Extension Points werden in PHP durch Interfaces abgebildet. Damit wird eine Schnittstelle sichergestellt, über die beide Seiten kommunizieren können. Ein solches Interface sieht beispielweise so aus:

geändert in:

Der Komponentenmanager

Extension Points werden in PHP durch Interfaces abgebildet. Damit wird eine Schnittstelle sichergestellt, über die beide Seiten kommunizieren können. Ein solches Komponenteninterface sieht beispielweise so aus:

Zeile 36 bearbeitet:

Dieses Interface repräsentiert die "Steckdose", in die sich eine Komponente "einstöpseln" kann. Das "Einstöpseln" geschieht durch das Schreiben einer Klasse, die dieses Interfaces implementiert ("class ExampleComponent implements Studip_PortalComponent"). Diese Klasse muss noch beim im Folgenden beschriebenen Komponentenmanager registriert werden.

geändert in:

Dieses Komponenteninterface repräsentiert die "Steckdose", in die sich eine Komponente "einstöpseln" kann. Das "Einstöpseln" geschieht durch das Schreiben einer Klasse, die dieses Interfaces implementiert ("class ExampleComponent implements Studip_PortalComponent"). Diese Klasse muss noch beim im Folgenden beschriebenen Komponentenmanager registriert werden.

 
 
20.05.2008 10:43 Uhr von mlunzena -
Zeilen 34-37 bearbeitet:

Dieses Interface repräsentiert die "Steckdose", in die sich eine Komponente "einstöpseln" kann. Das "Einstöpseln" geschieht durch das Schreiben einer Klasse, die dieses Interfaces implementiert ("class ExampleComponent implements Studip_PortalComponent"). Diese Klasse muss noch bei der Komponentenarchitektur registriert werden. (siehe TODO)

Jedes Plugin-Paket muss genau eine Plugin-Klasse enthalten (siehe Bestandteile). Diese Plugin-Klasse…

geändert in:

Dieses Interface repräsentiert die "Steckdose", in die sich eine Komponente "einstöpseln" kann. Das "Einstöpseln" geschieht durch das Schreiben einer Klasse, die dieses Interfaces implementiert ("class ExampleComponent implements Studip_PortalComponent"). Diese Klasse muss noch beim im Folgenden beschriebenen Komponentenmanager registriert werden.

Der Komponentenmanager

Der Komponentenmanager ist für zwei Aufgaben zuständig. Zum einen können bei ihm Komponenten angemeldet und abgemeldet werden, zum anderen kann man über ihn alle Komponenten erhalten, die ein bestimmtes Komponenteninterface ("Steckdose") implementieren, um dann an diesen die im Komponenteninterface deklarieren Methoden aufzurufen. Da man nur Komponenten erhält, die dieses Komponenteninterface implementieren, kann man sicher sein, dass diese Methoden auch tatsächlich zur Verfügung stehen, da der Compiler dieses zusichert — schliesslich muss eine Komponente ja das Komponenteninterface implementieren ("implements").

Zeilen 46-47 hinzugefügt:

Jedes Plugin-Paket muss genau eine Plugin-Klasse enthalten (siehe Bestandteile). Diese Plugin-Klasse…

 
 
20.05.2008 10:19 Uhr von mlunzena -
Zeilen 33-34 hinzugefügt:

Dieses Interface repräsentiert die "Steckdose", in die sich eine Komponente "einstöpseln" kann. Das "Einstöpseln" geschieht durch das Schreiben einer Klasse, die dieses Interfaces implementiert ("class ExampleComponent implements Studip_PortalComponent"). Diese Klasse muss noch bei der Komponentenarchitektur registriert werden. (siehe TODO)

 
 
20.05.2008 10:08 Uhr von mlunzena -
Zeilen 1-35 hinzugefügt:

Integration/Komponentenarchitektur

(:toc anchors=visible:)

Um das Problem zu lösen, Stud.IP an bereits vorhandenen Stellen, also in seiner Kernfunktionalität, zu erweitern, kommt die im folgenden beschriebene Komponentenarchitektur zum Einsatz.

Diese Architektur kann sinnbildlich so erklärt werden, dass Stud.IP aus einer Menge an Komponenten besteht.

Eine Komponente ist ein funktionales Subsystem, dass einen Service im Kontext von Stud.IP anbietet. Beispiele: ein Fotoalbum für Benutzer, ein Newsfeed-Aggregator, ein Prüfungssystem usw. Der Stud.IP-Kern soll in diesem Zusammenhang der Einfachheit halber als eine einzelne Komponente gelten.

Jeder dieser Komponenten hat die Möglichkeit, "Steckdosen" (Extension Points) anzubieten, in die sich wiederum andere Komponenten "einstöpseln" können. Das erlaubt es einer Komponente, die Funktionalität einer anderen zu erweitern, ohne dass die erweiterte Komponente überhaupt wissen muss, dass es diese sie erweiternde Komponente überhaupt gibt. Erforderlich ist nur, dass die eine Komponente ihre "Steckdosen" (Extension Points) zur Verfügung stellt und nutzt und andere Komponenten sich in diese "Steckdosen" (Extension Points) einstöpseln können.

Grundsätzlich bietet zuallererst nur das Kernsystem solche Extension Points an. Jedes weitere installierte Plugin erhält aber die Möglichkeit, eigene Extension Points hinzuzufügen.

Extension Points werden in PHP durch Interfaces abgebildet. Damit wird eine Schnittstelle sichergestellt, über die beide Seiten kommunizieren können. Ein solches Interface sieht beispielweise so aus:

(:source lang=php linenum:)
<?php

interface Studip_PortalComponent extends Studip_Component {

  function showOverview($unauthorizedview = TRUE);

  function hasAdministration();

  function hasUnauthorizedView();

  function hasAuthorizedView();
}

Jedes Plugin-Paket muss genau eine Plugin-Klasse enthalten (siehe Bestandteile). Diese Plugin-Klasse…

 
 
16.05.2008 10:02 Uhr von 131.173.75.110 -
Zeilen 17-32 bearbeitet:

Extension Points werden in PHP durch Interfaces abgebildet. Damit wird

geändert in:

Extension Points werden in PHP durch Interfaces abgebildet. Damit wird eine Schnittstelle sichergestellt, über die beide Seiten kommunizieren können. Ein solches Interface sieht beispielweise so aus:

(:source lang=php linenum:)
<?php

interface Studip_PortalComponent extends Studip_Component {

  function showOverview($unauthorizedview = TRUE);

  function hasAdministration();

  function hasUnauthorizedView();

  function hasAuthorizedView();
}
 
 
15.05.2008 15:37 Uhr von mlunzena -
Zeilen 1-20 hinzugefügt:

Integration/Komponentenarchitektur

(:toc anchors=visible:)

Um das Problem zu lösen, Stud.IP an bereits vorhandenen Stellen, also in seiner Kernfunktionalität, zu erweitern, kommt die im folgenden beschriebene Komponentenarchitektur zum Einsatz.

Diese Architektur kann sinnbildlich so erklärt werden, dass Stud.IP aus einer Menge an Komponenten besteht.

Eine Komponente ist ein funktionales Subsystem, dass einen Service im Kontext von Stud.IP anbietet. Beispiele: ein Fotoalbum für Benutzer, ein Newsfeed-Aggregator, ein Prüfungssystem usw. Der Stud.IP-Kern soll in diesem Zusammenhang der Einfachheit halber als eine einzelne Komponente gelten.

Jeder dieser Komponenten hat die Möglichkeit, "Steckdosen" (Extension Points) anzubieten, in die sich wiederum andere Komponenten "einstöpseln" können. Das erlaubt es einer Komponente, die Funktionalität einer anderen zu erweitern, ohne dass die erweiterte Komponente überhaupt wissen muss, dass es diese sie erweiternde Komponente überhaupt gibt. Erforderlich ist nur, dass die eine Komponente ihre "Steckdosen" (Extension Points) zur Verfügung stellt und nutzt und andere Komponenten sich in diese "Steckdosen" (Extension Points) einstöpseln können.

Grundsätzlich bietet zuallererst nur das Kernsystem solche Extension Points an. Jedes weitere installierte Plugin erhält aber die Möglichkeit, eigene Extension Points hinzuzufügen.

Extension Points werden in PHP durch Interfaces abgebildet. Damit wird

Jedes Plugin-Paket muss genau eine Plugin-Klasse enthalten (siehe Bestandteile). Diese Plugin-Klasse…

 
 
15.05.2008 11:32 Uhr von mlunzena -
Zeile 0 gelöscht:
Zeilen 6-7 hinzugefügt:
 
 
26.02.2008 15:44 Uhr von mlunzena -
Zeilen 1-6 hinzugefügt:
  • Wir brauchen ein Interface (Studip_Component) zur Kennzeichnung von Komponenteninterfaces.
  • Ein Komponenteninterface definiert eine Menge von Operationen, die ein Plugin ausführen können muss, wenn es eine solche Komponente sein möchte. (Beispiel: Einen Text für eine Box innerhalb der Stud.IP-Homepage liefern.)
  • Diese Komponenteninterfaces sollten eher feingranular sein (Gegenbeispiel: Homepage-Plugin mit seinen zahlreichen Konfigurationsmöglichkeiten.).
  • Die abstrakten Legacy-Plugins müssen diese implementieren. Vorteilhafterweise würde man dann nicht nur ein Komponenteninterface pro Legacy-Plugintyp haben, sondern viele. (Beispiel: Das Homepage-Plugin könnte und sollte >3 von solchen Komponenteninterfaces implementieren.)
  • Derzeit enthalten die Legacy-Plugins Zustand, über den Punkt, an dem sie eingebunden werden. So existieren zum Beispiel für das AbstractStudipStandardPlugin die Methoden #getId und #setId, die wohl die Veranstaltungs- bzw- Einrichtungs-ID enthalten. Dieser Zustand sollte - sofern nötig (vielleicht sollte man das immer machen?) - explizit als Parameter in den Methoden, die in den Komponenteninterfaces deklariert werden, vorgesehen sein.

 

 

Quelle: Basis-Wiki-Hilfe | Letzte Änderung: 20.05.2008 13:07 Uhr, mlunzena | Local view: Basis-Hilfe