Jump to content

accessing methods of outer class from methods in inner class...


Hall of Famer

Recommended Posts

Well the title may seem a bit confusing, but heres an example:

 

<?php
class User{
   public $uid;
   public $username;
   protected $password;
   protected $email;
   public $usergroup;
   public $profile;
   

  public function __construct($id){
      // constructor code inside
  }

  public function getemail(){
      return $this->email;
  } 
   
  public function getusergroup(){
      return $this->usergroup;
  }

  public function getprofile(){
      $this->profile = new UserProfile($this->uid);
  }
}

class UserProfile(){
   protected $avatar;
   protected $bio;
   protected $gender;
   protected $favcolor;
   

  public function __construct($id){
      // constructor code inside
  }

  public function formatavatar(){
      // avatar formatting code inside
  }

  public function formatusername(){
      // format username?
  } 
}
?>

 

As you can see, the User class(an outer class) has a property called Profile, which can be instantiated as a UserProfile object(an inner class). The two objects have distinct functionalities, but there are times when the UserProfile object needs to access property and methods from the user object. I know its easy for outer class to access methods from inner class by using the single arrow access operator twice, but how about the other way around?

 

Lets say from the above example the userprofile can format the username displayed to the screen by adding a sun to the left of the username if the usergroup is admin, a moon if the usergroup is mod, and nothing if its just a member. The usergroup property is stored in the outer class, and can be accessed with this $user->getusergroup() method only. I know I can always do the hard way by passing a user object to the method's argument, but is there an easier way for the inner class UserProfile to access properties/methods for outerclass User? If so, how can I achieve that?

Link to comment
Share on other sites

Shouldn't the UserProfile know whose profile it is? A bidirectional association: User has a profile, UserProfile has a user.

 

You are absolutely right, this is what I am trying to achieve. Are you suggesting that I need to instantiate a user object inside the UserProfile class' constructor?

Link to comment
Share on other sites

That's actually a tricky question with many answers. If you're pulling information from a database then the generic answer is "when you do so is when you set up the User and/or UserAccount objects" (like in getprofile() or a constructor).

 

But hold on a second. Why is the UserProfile dealing with the username? Why not have the User class do that? That's where the information is, after all.

Link to comment
Share on other sites

@requinix:

 

I see, now this sounds a bit complicated. The User profile object is only instantiated and used in a page called profile.php, while the user object is used everywhere.  So yeah the $user->getprofile() method is only called in script file profile.php, while it should not be invoked anywhere else since it will only be a waste of memory.

 

And well, you are right ideally the User class should handle username formatting, not the UserProfile class. So perhaps it is not really a good example here, but in  occasions it is definitely possible that an inner class needs to access properties/methods and I was wondering if there are easier ways to handle that.

 

@MrMarcus:

 

Oh my mistake, thanks for pointing it out.

Link to comment
Share on other sites

There are a few ways you could approach this.  The easiest would be inheritance.  Child classes have access to all of their parent's public and protected members.  You could also try the Decorator pattern (look it up), since a UserProfile is really something that wraps a User.

Link to comment
Share on other sites

There are a few ways you could approach this.  The easiest would be inheritance.  Child classes have access to all of their parent's public and protected members.  You could also try the Decorator pattern (look it up), since a UserProfile is really something that wraps a User.

 

I see what you mean, I will go with inheritance then. In fact I already incorporate some decorators in my script. The Friend  and Banned decorators are good examples. I also coded child classes like Admin and Mod as inheritance. The problem I had before is that I couldnt envision UserProfile as child class as User(though ironically, I had not such problem with Admin and Mod classes).

 

And thanks for your advice.

Link to comment
Share on other sites

I don't get why you have a UserProfile at all... It has no id, so it's not an entity.  It wraps data which I feel should belong to the User object, and it's only responsibilities are formatting. IMO, at best, your UserProfile IS a View. But since this formatting is part of your domain these should also be in your User class. Just like the below function would:

 

public function getFullName() {
  return $this->getTitle() . '. ' . $this->getFirstname() . ' (' . $this->getAlias() . ') ' . $this->getLastName();
}

 

If you have a requirement that states that you always should address the user with it's full name. Admin and Mod are Special Case's of User so these should inherit from User (but since PHP does not support method overloading, it's better to make these responsibilities also part of User and just check with isModerator() and isAdmin() of some sort). I also fail to see how Friend and Banned could be Decorators? Banned could be a Value Object that tells how the user was banned (perm, temp) and how long (in case of temp) but not a Decorator. And Friend should be just an instance of a User as element in a _friends property array.

 

$user1->isFriendsWith($user2);

//implementation
public function isFriendsWith(User $u) {
  Assert::true(!$this->equals($u));
  return $this->_friends->contains($u);
}

Link to comment
Share on other sites

I don't get why you have a UserProfile at all... It has no id, so it's not an entity.  It wraps data which I feel should belong to the User object, and it's only responsibilities are formatting. IMO, at best, your UserProfile IS a View. But since this formatting is part of your domain these should also be in your User class. Just like the below function would:

 

public function getFullName() {
  return $this->getTitle() . '. ' . $this->getFirstname() . ' (' . $this->getAlias() . ') ' . $this->getLastName();
}

 

If you have a requirement that states that you always should address the user with it's full name. Admin and Mod are Special Case's of User so these should inherit from User (but since PHP does not support method overloading, it's better to make these responsibilities also part of User and just check with isModerator() and isAdmin() of some sort). I also fail to see how Friend and Banned could be Decorators? Banned could be a Value Object that tells how the user was banned (perm, temp) and how long (in case of temp) but not a Decorator. And Friend should be just an instance of a User as element in a _friends property array.

 

$user1->isFriendsWith($user2);

//implementation
public function isFriendsWith(User $u) {
  Assert::true(!$this->equals($u));
  return $this->_friends->contains($u);
}

 

Well not really, the user profile class has methods that display certain portion of profile page content when invoked. But yeah formatting should be handled as methods for user class.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.