1

I'm developing a sort of plugin in Php about posts, comments and likes. So i will have an Object for Post, Comment and Like.

This classes has a bunch of properties that describe the class it self, an small example of the Post class can be.

class Post
{
    protected $infoPost;

    protected $postId;

    protected $content;

    protected $poster_type;

    protected $poster_id;

    protected $likes;

    protected $comments;

    // and more but you got the idea

    public function __construct($postId,
                                $poster_type = null,
                                $poster_id = null,
                                $content = null,
                                $likes = null,
                                $comments = null)

           $this->postId = $postId;
           $this->poster_type = $poster_type;
           $this->poster_id = $poster_id;
           $this->content = $content;
           $this->likes = $likes;
           $this->comments = $comments;

}

Now the class called Wall will be responsible to instantiate and fill the properties of the objects Post, Comment, Like.

I'm injecting the repositories as dependency just for the purpose of this example, on the real class will be injected top classes with the repository as dependency. And even was better to extract this to an interface. This is a ugly class but I want to keep it simple and focus on properties.

class Wall
{

    protected $postRepo;

    protected $commentRepo;

    protected $likeRepo;

    protected $post;

    protected $content;

    protected $likes;

    protected $comments;

    public function __construct(PostRepository $postRepo,
                                CommentRepository $commentRepo,
                                LikeRepository $likeRepo)
    {
           $this->postRepo = $postRepo; 
           $this->commentRepo = $commentRepo;
           $this->likeRepo = $likeRepo;
    }

    // Return Post Object
    public function createPost($postId,$posterType,$posterId)
    {
       $postOrmObject = $this->postRepo->create($postId,$posterType,$posterId);
       $post = new Post($postOrmObject->id,$postOrmObject->posterType,$postOrmObject->posterId);
       $this->post = $post;
       $post->setInfoPost($postOrmObject);
       return $post;
    }

    // Return Content Object
    public function createContent($postId,array $contentInfo)
    {
       $contentOrmObject = $this->contentRepo->create($postId,$content)
       $content = new Content($contentOrmObject->postId,$contentInfo);
       $this->content = $content;

       if ($this->post instanceof Post)
       {
          // here where I change the property
          $this->post->setContent($content);
       }

       return $content;
    }

    public function getPost()
    {
       return $this->post;
    }
}

So at this point I know that the properties of those objects should be dynamically but at the same time protected because only 1 class has the responsibility to change it, but to others classes may be useful to get the data of that property.

Ok, well, set getters and setters at this point, but then having 10 properties, I came a cross to have 20 methods more on my class and I want to avoid that as well.

Another way is set magic methods __get and __set but it seem the same things that set public properties and maybe is more efficient as well.

Arrived at this point I came with a couple of questions. When i'm talking about properties I'm referring to Post, Comment, Like Objects not the Wall Class

1) There is any other solution that permit to the class Wall to edit those properties but still maintain the protected visibility of this properties and not having setters and getters? Will make sense to use reflection?

2) do you think is better to set those properties public? If yes why?

3) When do you determinate when is appropriate to use a specific visibility of the property in a class? (Just want to compare my thought with your)

Fabrizio Fenoglio
  • 5,767
  • 14
  • 38
  • 75

1 Answers1

1

1) The way to have dynamic protected (or private for that matter) values is by using an array. protected $data = array(); Then you can use the __set and __get methods on the protected value, as you don't want to use getters and setters. Reflection will make your values accessibly even if they are protected or private.

2) I personally, mainly use protected values, and in your case i would keep them protected as wel. No other object should just be able to change those values, they belong to that object.

3) To continue on 2. For me most values are protected. They belong to the specific object and shouldn't be changed by anyone who wants, nor displayed for that matter. If a different object want's to change or show the values, it should go trough the current object which holds the data and that should tell the calling object how and what to do / display.

I personally like this post: https://stackoverflow.com/a/21902271/660410 it does not directly answer your question but gives a good understanding of the three visibility keywords. (especially the image).

Community
  • 1
  • 1
Michal
  • 1,010
  • 2
  • 8
  • 18
  • Thanks a lots for you nice explanation, I have just one question about your third point. **You said**: "If a different object want's to change or show the values, it should go trough the current object which holds the data and that should tell the calling object how and what to do / display." **Question:** How do you access to that property from the given object? Let's say that i'm injecting the the object that hold the data on the construct in the class that will edit the value. Can you make a short example about you point? Will be appreciated thanks – Fabrizio Fenoglio Jun 19 '14 at 13:17
  • To answer your question, I would refer you to the following patterns: https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/Builder | https://github.com/domnikl/DesignPatternsPHP/tree/master/Creational/AbstractFactory | – Michal Jun 19 '14 at 13:49