Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

1

03.02.2017, 23:15

Pattern für Package Interaktion

Moin. Ich wurde heute vor folgendes Problem gesetzt und bräuchte ein paar Tipps, wie/ob sich das schön lösen lässt. Das Beispiel ist abgeändert aber semantisch äquivalent.
Zunächst gibst es ganz unten dieses package:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
<?php

interface CreatureCondition
{
    public function fulfillsCreature(Creature $creature): bool;
}

interface Creature
{
    public function fulfills(CreatureCondition $condition): bool;
}


Darauf folgen diese beiden packages:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php

interface HumanCondition extends CreatureCondition
{
    public function fulfillsHuman(Human $human): bool;
}

class Human implements Creature
{
    public function fulfills(CreatureCondition $condition): bool
    {

    }
}

// ----

interface AnimalCondition extends CreatureCondition
{
    public function fulfillsAnimal(Animal $animal): bool;
}

class Animal implements Creature
{
    public function fulfills(CreatureCondition $condition): bool
    {
        
    }
}


Der untere "Layer" bzw. das package mit Creature darf/soll kein Wissen über die möglichen packages darüber haben. Die packages Human bzw. Animal wissen von dem Creature package (sie erweitern es ja). Nun sollen aber Animal bzw. Human wissen, dass sie die konkreten fulfillsHuman bzw. fulfillsAnimal Methoden aufrufen sollen. Wie lässt sich das schön lösen? Geht das überhaupt? Wir sind in PHP, da geht viel "dreckiges" aber ich würde es gerne sauber halten, also keine PHP-Magic oder Upcasts oder dergleichen (wenn es sich vermeiden lässt). Aber mir fällt nur ein, dass das man bereits im Creature package ein Visitor-interface implementiert und damit die oberen packages Animal und Human kennen müsste. Bin für jede Idee offen.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

04.02.2017, 08:18

Mir würde da spontan nur ein Mediator einfallen, der alle Parteien kennt.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

3

04.02.2017, 10:45

Aber könnte der Mediator als eigenes packages existieren? Dann wäre es 'ne Idee.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

04.02.2017, 10:50

Klar kann er. Er muss sich halt als Interface präsentieren und kennt alle involvierten Parteien. Alle anderen kennen ihn aber nur unter dem ohnehin bekannten Interface.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

5

04.02.2017, 11:08

Da der Mediator aber alle Parteien kennt würden die Benutzung des Mediators wiederum dafür sorgen, dass alle voneinander Wissen, oder nicht? Genauso könnte ich doch einen Visitor benutzen, oder überseh' ich was?
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

04.02.2017, 12:38

Nein, es wissen nicht alle voneinander, denn niemand kennt den Mediator. Alle anderen kennen nur das ohnehin public Interface. Ich dachte das hätte ich bereits gesagt. Nur der Mediator kennt alle.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

7

04.02.2017, 13:09

Hattest du gesagt ja, aber vllt. versteh' ich das nur noch nicht ganz. Wie würde denn der Ablauf dann sein? Ich stell' es mir nämlich grad so vor: Der Human würde in fulfills einen Human Mediator initialisieren - der wiederum das HumanCondition-Interface implementiert - mit sich (Human) als Instanz und der Instanz des CreatureCondition-Interface. Aber das kann es nicht sein, oder? Die Mediator-Code-Beispiele im Netz helfen mir leider wenig weiter. :/

Edit:
Also ich verstehe schon was du meinst, aber mein Problem ist noch, wie der Mediator dann weiß, dass es sich dabei um eine HumanCondition & einen Human handelt. Wie soll das hergeleitet werden?
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Architekt« (04.02.2017, 13:32)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

04.02.2017, 13:34

Human initialisiert gar nix, es bekommt einen Mediator übergeben in Form eines Interfaces. Deswegen kennt keines deiner Modelle die konkrete Implementierung des Mediators, sondern eben nur die ohnehin bekannten Interfaces.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

9

04.02.2017, 13:55

Ok. Dennoch braucht das interface des Mediators ja eine konkrete (fulfills) Methode die man aufruft. Also z.B. so:

Quellcode

1
2
3
4
interface CreatureMediatorInterface
{
    public function fulfills(CreatureConditionInterface $condition): bool;
}


Dann kann der Human z.B. folgendes machen:

Quellcode

1
2
3
4
    public function fulfills(CreatureConditionInterface $condition): bool
    {
        return $this->getMediator()->fulfills($condition);
    }


Es bleibt die Frage: Wie findet der Mediator raus, dass es sich um eine HumanCondition handelt?
Ich hab' mal meinen Code als Gist angelegt: https://gist.github.com/Dgame/24d1aea946…f9e63cbedd3562d
Es bleibt halt immer das Problem, dass die Condition nicht weiß, dass die Creature ein Human ist <=> bzw. dass Human nicht weiß, dass es sich um eine HumanCondition handelt.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

10

04.02.2017, 14:16

Du musst Dein Condition-Interface so gestalten, dass man beim Aufruf nicht wissen muss, um welche Condition es sich handelt oder die Aufrufe nicht durch die eigentlich zu prüfenden Objekte ausführen lassen. Mit Interfaces verschleiert man die Zyklen ja einfach nur. Finde ich nicht besonders toll.

Warum muss denn Deine Creature-Klasse etwas von der Condition wissen?

Werbeanzeige