OOP Design Question

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
philentropist
Forum Newbie
Posts: 9
Joined: Wed Jan 16, 2008 7:59 pm

OOP Design Question

Post 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?
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: OOP Design Question

Post 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.
philentropist
Forum Newbie
Posts: 9
Joined: Wed Jan 16, 2008 7:59 pm

Re: OOP Design Question

Post 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).
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: OOP Design Question

Post 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...
philentropist
Forum Newbie
Posts: 9
Joined: Wed Jan 16, 2008 7:59 pm

Re: OOP Design Question

Post 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.
philentropist
Forum Newbie
Posts: 9
Joined: Wed Jan 16, 2008 7:59 pm

Re: OOP Design Question

Post 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: :arrow: 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: :arrow: Posting Code in the Forums to learn how to do it too.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: OOP Design Question

Post 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
ssssss
Forum Newbie
Posts: 17
Joined: Fri Aug 29, 2008 8:34 am

Re: OOP Design Question

Post 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.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: OOP Design Question

Post 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();
(#10850)
philentropist
Forum Newbie
Posts: 9
Joined: Wed Jan 16, 2008 7:59 pm

Re: OOP Design Question

Post 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.
jmut
Forum Regular
Posts: 945
Joined: Tue Jul 05, 2005 3:54 am
Location: Sofia, Bulgaria
Contact:

Re: OOP Design Question

Post 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.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: OOP Design Question

Post 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........
(#10850)
webaddict
Forum Commoner
Posts: 60
Joined: Wed Mar 14, 2007 6:55 am
Location: The Netherlands

Re: OOP Design Question

Post 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........
webaddict
Forum Commoner
Posts: 60
Joined: Wed Mar 14, 2007 6:55 am
Location: The Netherlands

Re: OOP Design Question

Post 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.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: OOP Design Question

Post by josh »

This actually sounds a lot like http://en.wikipedia.org/wiki/Decorator_pattern
Post Reply