Page 1 of 1
OOP Design Question
Posted: Sat Sep 13, 2008 1:49 pm
by philentropist
Let's say I have a chain a derived classes such as:
Code: Select all
class A {
public function getToken() { return "a"; }
}
class B extends A {
public function getToken() { return "b"; }
}
class C extends B {
public function getToken() { return "c"; }
}
$a = new A();
$b = new B();
$c = new C();
I'm looking for the best way to implement a method that would behave like this:
A::allTokens($a); // returns "a"
A::allTokens($b); // returns "a b"
A::allTokens($c); // returns "a b c"
any ideas?
Re: OOP Design Question
Posted: Sat Sep 13, 2008 3:00 pm
by alex.barylski
Not sure what it is your trying to do...but technically you could accomplish it like so:
Code: Select all
class A{
function callMe()
{
return 'a';
}
}
class B extends A{
function callMe()
{
return 'b '.parent::callMe();
}
}
Not a very nice design though IMHO.
Re: OOP Design Question
Posted: Sat Sep 13, 2008 3:45 pm
by philentropist
Thanks, but that's not exactly what I'm looking for. The point is that I want to place the function in the base class A, so that child classes only need to define their own getToken() function. The goal is to find a design that doesn't rely on a convention (such as using super and appending the return value).
Re: OOP Design Question
Posted: Sat Sep 13, 2008 3:57 pm
by alex.barylski
I'm confused...obviously you are aware of inheritence so whats the problem?
Derive your sub classes from the base class and call the parent::xxx methods...
Re: OOP Design Question
Posted: Sat Sep 13, 2008 4:07 pm
by philentropist
It's a design question, not a howto question. The base class is meant to be part of an API, and the child classes are hypothetical classes that a user of the API would implement. I want the functionality to be achieved without requiring a user of the API to follow any unnecessary conventions.
Re: OOP Design Question
Posted: Sat Sep 13, 2008 4:36 pm
by philentropist
~pickle | Please use [ code=html ], [ code=php ], etc tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:
Posting Code in the Forums to learn how to do it too.
For what it's worth, here's the design I decided to go with
Code: Select all
class A {
private $tokens;
function __construct() {
$tokens = array();
$this->addToken('a');
}
protected function addToken($token) {
$tokens[] = $token;
}
public function getTokens() {
return $tokens;
}
}
class B extends A {
function __construct() {
parent::__construct();
$this->addToken('b');
}
}
class C extends B {
function __construct() {
parent::__construct() {
$this-addToken('c');
}
}
It doesn't behave exactly as I described, but works for what I needed and doesn't require people writing sub classes to do anything too confusing.
~pickle | Please use [ code=html ], [ code=php ], etc tags where appropriate when posting code. Your post has been edited to reflect how we'd like it posted. Please read:
Posting Code in the Forums to learn how to do it too.
Re: OOP Design Question
Posted: Sat Sep 13, 2008 9:46 pm
by josh
You could use the observable pattern so the parent class can just fire off an "event" and have the child classes attach themselves to the trigger, so the base class doesn't have to know about the other classes
Re: OOP Design Question
Posted: Mon Sep 15, 2008 8:24 am
by ssssss
Wouldn't this work?
Code: Select all
function getAllTokens()
{
$tokens = $parent::getAllTokens();
$tokens[] = $this->getToken();
return $tokens;
}
The idea smells a little funny, but it's technically possible.
Re: OOP Design Question
Posted: Mon Sep 15, 2008 12:21 pm
by Christopher
Code: Select all
class Toker {
protected $tokens = array();
public function addToken($token) {
$this->tokens[] = $token;
}
public function getTokens() {
$str = '';
foreach ($this->tokens as $token) {
$str .= $token->getToken();
}
return $str;
}
}
class A {
public function getToken() { return "a"; }
}
class B {
public function getToken() { return "b"; }
}
class C {
public function getToken() { return "c"; }
}
$toker = new Toker();
$toker->addToken(new A());
$toker->addToken(new B());
$toker->addToken(new C());
echo $toker->getTokens();
Re: OOP Design Question
Posted: Tue Dec 09, 2008 12:20 pm
by philentropist
Thanks arborint! I think this is the "right way" to do what I wanted with OO design. I think I'll go an extra step and make Toker a singleton so that the user doesn't need to bother instantiating it.
Re: OOP Design Question
Posted: Tue Dec 09, 2008 1:48 pm
by jmut
As you say your developing API I would suggest think from this users point of view...how will API be used...what is best interface to it.
Don't bother for implementation at first.
Re: OOP Design Question
Posted: Tue Dec 09, 2008 5:09 pm
by Christopher
philentropist wrote:I think I'll go an extra step and make Toker a singleton so that the user doesn't need to bother instantiating it.
Nooooooooooooooooooooooooooooooooooooooo........
Re: OOP Design Question
Posted: Mon Dec 15, 2008 5:05 am
by webaddict
philentropist wrote:Thanks arborint! I think this is the "right way" to do what I wanted with OO design. I think I'll go an extra step and make Toker a singleton so that the user doesn't need to bother instantiating it.
That's a horrible reason to adapt the Singleton pattern, or worse yet, not a reason at all. Keep in mind that static functions have their downfalls and you shouldn't introduce them into your software without considering alternatives. Global access comes with a cost: the disability to test, because of the (extremely tight) coupling.
The only thing Singleton is good for, is limiting the number of instances, and to be honest: I think it's even doing a bad job at that. Limiting the number of instances could (and probably should) be done using a Factory or a Builder, without the problems that are inherent to static functions.
Or, in short:
arborint wrote:Nooooooooooooooooooooooooooooooooooooooo........
Re: OOP Design Question
Posted: Mon Dec 15, 2008 5:19 am
by webaddict
arborint wrote:Code: Select all
public function getTokens() {
$str = '';
foreach ($this->tokens as $token) {
$str .= $token->getToken();
}
return $str;
}
Wouldn't this be a simpler implementation:
Code: Select all
public function getTokens() {
return implode( '', $this->tokens );
}
EDIT: Oh my, I'm very mistaken. You're calling the method, of course, which implode will not do. Sorry 'bout that.
Re: OOP Design Question
Posted: Mon Dec 15, 2008 6:37 am
by josh