HiveBrain v1.2.0
Get Started
← Back to all entries
principlephpMinor

Design pattern for adapter

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
adapterdesignforpattern

Problem

I wrote a framework and I want to hear the thoughts of other on the design patterns it uses. Every method contains three design patterns - adapters(strategy), intercepting filters, and observers.

A normal class/method in a class looks like this:

class Run extends PVStaticObject{

    public static function goForARun($miles) {

        $return ='I ran '.$miles. ' miles today';

        return $return;
    }
}


With the design patterns the class/method looks like this:

class Run extends PVStaticObject{

    public static function goForARun($miles) {

        if (self::_hasAdapter(get_class(), __FUNCTION__))
            return self::_callAdapter(get_class(), __FUNCTION__, $miles);

        $miles = self::_applyFilter(get_class(), __FUNCTION__, $miles, array('event' => 'args'));

        $return ='I ran '.$miles. ' miles today';

        self::_notify(get_class() . '::' . __FUNCTION__, $miles, $return);
        $return = self::_applyFilter(get_class(), __FUNCTION__, $return, array('event' => 'return'));

        return $return;
    }
}


A brieft explanation, the adapter will completely change the method by calling another method in its place. Its a way of changing the functionality of a class without modifying the core functionality.

Filters modify variables in a method by passing them out to another class's method or anonymous function where they are modified and return. Normal execution of the method continues.

Observers do not have a return and are purely call another class or anonymous function. They are for event drivin programming.

Examples of adding adapters, filters and observers are below.

```
Run::addObserver('Run::goForARun', 'run_observer', function($miles, $return){
echo PVHtml::div('Running '. $miles. ' has caused you to lose 2 pounds', array('style' => 'margin-top:10px;'));
}, array('type' => 'closure'));

Run::addAdapter('Run','goForARun', function($miles){
echo PVHtml::p('Because of the weather, you were not able to run

Solution

You should relearn design patterns. Until you do this, your framework is bound to be messed up and poorly architected, if only because of your flawed axioms.

The Adapter Pattern is for taking class A implements InterfaceA and wrapping it inside a class Adapter so that you can use it with the same API as class B implements InterfaceB. It has nothing to do with executing different code or whatever inside another class.

The Strategy Pattern is meant to reduce cyclomatic complexity (basically, lots of nested if statements). It works like this:

interface BasicLogicI {
    public function execute();
}

class GreetingLogic implements BasicLogicI {
    public function execute() { echo "Hi!\n"; }
}

class DismissLogic implements BasicLogicI {
    public function execute() { echo "Bye!\n"; }
}

class Speaker {
    protected $strategy;

    public function __construct($strategy) {
        $this->changeContext($strategy);
    }
    public function changeContext($strategy) {
        unset($this->strategy);
        $this->strategy = $strategy;
    }
    public function speak() {
        $this->strategy->execute();
    }
}

$speaker = new Speaker(new GreetingLogic);
$speaker->speak();
$speaker->changeContext(new DismissLogic);
$speaker->speak();
// Output: Hi!
//         Bye!

Code Snippets

interface BasicLogicI {
    public function execute();
}

class GreetingLogic implements BasicLogicI {
    public function execute() { echo "Hi!\n"; }
}

class DismissLogic implements BasicLogicI {
    public function execute() { echo "Bye!\n"; }
}

class Speaker {
    protected $strategy;

    public function __construct($strategy) {
        $this->changeContext($strategy);
    }
    public function changeContext($strategy) {
        unset($this->strategy);
        $this->strategy = $strategy;
    }
    public function speak() {
        $this->strategy->execute();
    }
}

$speaker = new Speaker(new GreetingLogic);
$speaker->speak();
$speaker->changeContext(new DismissLogic);
$speaker->speak();
// Output: Hi!
//         Bye!

Context

StackExchange Code Review Q#8637, answer score: 5

Revisions (0)

No revisions yet.