localhost
localhost

Reputation: 921

Using Reflection for static object creation

class HueHue {
    private $hue;

    public function show(){
        echo $this->hue;
    }

    public static function parse($string){
        // parse it all
        $HueHue = new HueHue();
        $reflector = new ReflectionClass($HueHue);
        $hue = $reflector->getProperty('hue');
        $hue->setAccessible(true);
        $hue->setValue($HueHue, $parsed_string);
    }
}

Is this "bad"? I really prefer this than to make a public function setHue($parsed_string), and parse() must be static because I hate doing new then setting and getting...

The end game is to just HueHue::parse('something here')->show(); and I really don't want private $hue to be settable.

Any feedback appreciated.

Upvotes: 0

Views: 68

Answers (2)

ircmaxell
ircmaxell

Reputation: 165271

Is this "bad"?

What your doing is not bad. It's not the cleanest thing in the world, but at the same time if it solves the problem, then it's good. I would make @Xeoncross's modification though, as it is a bit cleaner and avoids reflection.

However, I would argue that why you are doing it is bad.

If you're making an object just to format a string for output, you may want to re-think why you are using an object in the first place. If the majority of your usages are:

HueHue::parse($hue)->show();

Then why not just make a single function that skips the object step?

function parseHue($hue) {
    // parse it
    return $parsed_hue;
}

Then to use:

echo parseHue($hue);

Or, if you need the value object for some reason (that's not indicated in your question), then split out the parser into a separate object, and make the queue a constructor parameter.

class Hue {
    private $hue;
    public function __construct($hue) {
        $this->hue = $hue;
    }
    public function show() {
        echo $this->hue;
    }
}

class HueParser {
    public function parse($string) {
        // parse it!
        return new Hue($parsed_hue);
    }
}

The reason for decoupling is that you can now polymorphically switch out the parser. So your unit tests for the consumer of the parser can swap it out for a mock.

Not to mention that it maintains proper separation of concerns, so if you want to update the parser logic (to account for a new format for example), you can do that without changing either the consumer (the one who calls the parser) or the end user (the one who gets the Hue object)...

Upvotes: 5

Xeoncross
Xeoncross

Reputation: 57284

You don't need reflection if it's the same class.

class HueHue {
    private $hue;

    public function show(){
        echo $this->hue;
    }

    public static function parse($string)
    {
        $HueHue = new Static();
        $HueHue->hue = $string;
        return $HueHue;
    }
}

HueHue::parse($hue)->show();

Upvotes: 1

Related Questions