S
S
SuperKozel2012-01-02 08:26:14
PHP
SuperKozel, 2012-01-02 08:26:14

How would you implement such an architecture within PHP?

For clarity, I will explain, this is with regards to the card game.
There is an object to which another object can be attached, and the associated object changes the characteristics and behavior of the first object. And deleting this associated object returns it to its original state.
A banal example: there is a weapon card, you can apply a boost card to it, or a card that allows you to put it on bypassing the game rules (rewrites the $itemCard->canEquip($player) method).
There is an idea for a head-on solution, but I hope knowledgeable people will suggest a more elegant solution.

Answer the question

In order to leave comments, you need to log in

8 answer(s)
M
mayorovp, 2012-01-02
@mayorovp

The modifier object must have a combine method that will return the combined object. The combined object must have a method that separates it again.
In other words, you need something like this:

A
Anatoly, 2012-01-02
@taliban

If you have worked with zend, then look at how the decorators on the form are arranged there. You can also look at the original “decorator” pattern, although in this case the Zend craft is more suitable, it will solve your problems by 100%.

A
Alexei_987, 2012-01-04
@Alexei_987

sorry for Ctrl + Enter :)
you need to create an interface:

interface IDecorable {
  /**
   * @return IDecorable
   */
  removeDecorator(IDecorable $decorator);
}

the object being decorated must implement the interface using a stub:
  //....
  /**
   * @return IDecorable
   */
  removeDecorator(IDecorable $decorator) {
      return $this;
  }
  //...

and all decorators can be inherited from an abstract decorator in which there will be such an implementation of this interface:
  //....
  /**
   * @var IDecorator
   */
  private $decorableObject;
  /**
   * @return IDecorable
   */
  removeDecorator(IDecorable $decorator) {
    if($decorator == $this) {
      return $this->decorableObject;
    }
    $decorable = $this->decorableObject->removeDecorator($decorator);
    if($decorable != $this->decoratedObject) {
       $this->decoratedObject = $decorable;
    }
    return $this;
  }
  //...

Thus, objects can be used as follows:
$decorated = $decorated->removeDecorator($decorated); 

Such code can remove the topmost object decorator or return the object itself if it has no decorators.
To remove an arbitrary decorator from the chain, you need to pass this decorator or a decorator with similar properties as a parameter:
$decorated = $decorated->removeDecorator($someOtherDecorator); 

N
nocach, 2012-01-02
@nocach

You can do something like this:
Suitable if changes to card properties mainly affect only attributes (add, subtract, etc.)
in this case $modifier->apply($card) will directly change the values ​​of the card (for example, add +5 to damage) $mofidier->revert($card) again directly returns the values ​​to the starting point (subtract -5 from damage).
The advantage of this solution is that there is no rhombus problem. If the cards are very different in the set of attributes, then the Modifier can be made similar to the Visitor pattern.
True, there may be a problem with percentage modifications (a +20% damage card plus a +5 damage card will give the wrong result), but this can be bypassed by modifying the ModifiebleSupport logic.

K
kuzemchik, 2012-01-03
@kuzemchik

The students did the Munchkin game as a semester work. Such bonuses were already considered a function of the table, and the indicators themselves were delivered via a common interface. Accordingly, the bonus card itself received at the input the card on which the bonus was applied, and returned its personal bonus applicable in a particular case (including deciding whether it can be applied to the current card or not).

A
andrew_tch, 2012-01-03
@andrew_tch

How about a simple EventDispatcher / EventListener? We have the GetCardPropeties event, which calls the table or card and modifies the event's flags depending on the context.
And yes, this solution does not depend on PHP)

A
Alexei_987, 2012-01-04
@Alexei_987

Hello. I think that nevertheless the problem can be solved using the usual decorator pattern.
The only difference is that you need to be able to remove decorators from an object.
To solve this problem, I would suggest to implement the following solution:

R
red_pilot, 2012-01-07
@red_pilot

It's a strategy pattern, isn't it?
en.wikipedia.org/wiki/Strategy_ (design_pattern)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question