patternphpMinor
Workaround for overloaded constructor in PHP
Viewed 0 times
overloadedphpconstructorforworkaround
Problem
I have a class whose purpose is to display a comment. I'd like to be able to instantiate it by passing a
So here's the two methods for instantiating a
I'm moderately satisfied, although it's not near as intuitive as an overloaded constructor. Any thoughts on improving this?
Comment object if I happen to have it available, or just the values if that's what I have available at the time. Unfortunately PHP doesn't allow overloaded constructors, so here's the workaround I came up with.class CommentPanel extends Panel {
//Private Constructor, called only from MakeFrom methods
private function CommentPanel($text, $userName, $timestamp) {
parent::Panel(0, $top, System::Auto, System::Auto);
// Render comment
}
public static function MakeFromObject(Comment $comment) {
return new CommentPanel($comment->text, $comment->User->nickname, $comment->last_updated_ts);
}
public static function MakeFromValues($text, $userName, $timestamp) {
return new CommentPanel($text, $userName, $timestamp);
}
}So here's the two methods for instantiating a
CommentPanel:$cp = CommentPanel::MakeFromObject($comment);
// or...
$cp = CommentPanel::MakeFromValues($text, $user, $last_updated_ts);
// but not
$cp = new CommentPanel(); //Runtime errorI'm moderately satisfied, although it's not near as intuitive as an overloaded constructor. Any thoughts on improving this?
Solution
Given that php allows optional parameters and doesn't require type checking of parameters that are passed in, you can sort of "fake" an overloaded constructor.
something like this:
This method will allow for a more consistent API and one that is perhaps more familiar to Java and C++ developers.
Also, I'm not positive which version of PHP you're targeting, but I believe in the current version, uses __construct instead of the class name as the constructor. I'm not sure if this is preferred but the documentation does say that it checks for __construct first and then the class name style constructor, so I would guess that using __construct() instead of CommentPanel() would reduce runtime ever so slightly. I'm not 100% sure on that though, that's just my understanding. Please correct me if I'm wrong :)
something like this:
class CommentPanel extends Panel {
public function __construct($text_or_comment, $username=null, $timestamp=null) {
if (is_string($text_or_comment) {
$this->textConstructor($text_or_comment, $username, $timestamp);
}
else { // assume that it's a comment since it's not a string ... there are better ways to handle this though
$this->commentConstructor($text_or_comment);
}
}
private function textConstructor($text, username, $timestampe) { /* . . . */ }
private function commentConstructor(Comment $comment) { /* . . . */ }
}This method will allow for a more consistent API and one that is perhaps more familiar to Java and C++ developers.
Also, I'm not positive which version of PHP you're targeting, but I believe in the current version, uses __construct instead of the class name as the constructor. I'm not sure if this is preferred but the documentation does say that it checks for __construct first and then the class name style constructor, so I would guess that using __construct() instead of CommentPanel() would reduce runtime ever so slightly. I'm not 100% sure on that though, that's just my understanding. Please correct me if I'm wrong :)
Code Snippets
class CommentPanel extends Panel {
public function __construct($text_or_comment, $username=null, $timestamp=null) {
if (is_string($text_or_comment) {
$this->textConstructor($text_or_comment, $username, $timestamp);
}
else { // assume that it's a comment since it's not a string ... there are better ways to handle this though
$this->commentConstructor($text_or_comment);
}
}
private function textConstructor($text, username, $timestampe) { /* . . . */ }
private function commentConstructor(Comment $comment) { /* . . . */ }
}Context
StackExchange Code Review Q#504, answer score: 8
Revisions (0)
No revisions yet.