Reputation: 3651
I want to implement the strategy design pattern using php:
interface dummy_function {
public function render();
}
class a implements dummy_function {
public function render() {
echo "class a\n";
// I want to acess x_main::dummy like: echo parent::dummy
}
}
class b implements dummy_function {
public function render() {
echo "class b\n";
// I want to acess x_main::dummy like: echo parent::dummy
}
}
class x_main {
public $dummy = "hello world";
public function setX_Function( dummy_function $funcname ) {
$this->x_function = $funcname;
}
public function render() {
$this->x_function->render();
}
}
$test = new x_main();
$test->setX_Function( new a() );
$test->render();
Inside my classes I want to access to some methods and variables defined in the main class. Unfortunatelly "parent" does not work to access contents from the class "x_main" inside the implementation classes.
A way i found is to give $this as parameter to the method "render", like:
class x_main {
[...]
public function render() {
$this->x_function->render( $this );
}
}
class a implements dummy_function {
public function render( $mainclass ) {
echo "class a\n";
echo $mainclass->dummy;
}
}
The next way i testest is to set the variable from the class main direcly into the implemented function, like:
class x_main {
[ ... ]
public function setX_Function( dummy_function $funcname ) {
$this->x_function = $funcname;
$this->x_function->dummy = $dummy;
}
}
class a implements dummy_function {
public function render() {
echo "class a\n";
echo $this->dummy;
}
}
Both solutions work, but I feel a bit confused if that's the best way to implement my desired idea. It looks extremly like a workaround but not like a real OO-programming.
I'm looking forward for your ideas.
Upvotes: 0
Views: 112
Reputation: 522382
Rehashing the comments above:
The two classes aren't related in any way, they certainly don't have a parent relationship. One object holding an instance of another object does not mean these two objects are in any sort of relationship with one another. You simply need to explicitly pass data into your dummy_function instance; e.g.:
public function render(array $data).
Response:
In my first solution I put the whole mainclass as parameter to the render function. So this is a solution that will work in any case. But if there is definitivly no relationship between these two objects I prefer my second solution by setting the parameters directly with
$this->x_function->dummy = $dummy;
Sorry to tell you that you're wrong there. Implicitly setting a property on an object is in no way a defined interface. And I'm not using this word in the sense of PHP's interface
keyword, I mean this in the broader sense of specifying how two pieces of code can interact and cooperate.
You've done a good job of specifying and using an interface
for the render()
function, this greatly decreases code coupling and increases flexibility and testability. Now you're destroying this again by using undefined and brittle property assignments.
You need to make the passing data into render
aspect part of your interface specification. For example:
interface dummy_function {
public function render(array $data);
}
Or:
interface dummy_function {
public function setData(array $data);
public function render();
}
Or better:
interface DummyData {
/**
* @return string
*/
public function getDummyData();
}
interface DummyRenderer {
public function render(DummyData $data);
}
With this you're:
string
)render()
can get access to such data (it'll receive a DummyData
object which has a getDummyData()
method)You don't need to guess what property names are involved or what structure the passed object has.
Upvotes: 2