0
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.

2 Answers 2

5

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)...

Sign up to request clarification or add additional context in comments.

4 Comments

The class actually parses a string into an array, which will be manipulated by other HueHue methods. I probably won't need to have different parsers, but maybe it's a good idea to decouple them if only as an offering to the OOP gods. :)
@localhost: It's not about being an offering to the gods. It's more about gaining the benefits that separation of concerns brings. I mentioned the function mainly because some people are afraid of them (they think everything must be OOP or else), and I wanted to throw that out there. But I do strongly thing that statics should be avoided in the vast majority of cases. And in your case, there's really not much benefit to having the parser statically on the class (it's not a cross-cutting concern), so the benefits of extracting the parser are pretty significant.
Well, I did separate the parser, but I'm keeping the parse() method as static, because I prefer to HueParser::parse('...') to $p = new HueParser; $p->parse('...');
@localhost: you shouldn't be doing new right before parsing anyway. That should be external to your class, and passed in as a dependency. That you can swap it out...
1

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();

1 Comment

Oh, that solves it. Now if it was returning another class, would it be ok to use Reflection? I guess using it in some sort of Factory class?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.