Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Presenter Pattern #216

Closed
michaelachrisco opened this issue May 27, 2016 · 7 comments
Closed

Presenter Pattern #216

michaelachrisco opened this issue May 27, 2016 · 7 comments

Comments

@michaelachrisco
Copy link
Contributor

michaelachrisco commented May 27, 2016

How do you feel about adding the Presenter Pattern to this repo? Its similar to the Decorator pattern, but has some key differences. Decorators add new functionality to class instances, whereas Presenters are closer to the view and work directly with the view layer and may contain the language of the view (html/css/etc..). It also contains the ui business logic for the View.

Example code:

class PresentableClass{
  use PresentableTrait;
  protected $presenter = 'ClassPresenter';
}

//Sample class presenter used for this test only
class ClassPresenter extends Presenter{
  public function userName(){
    if($this->email) return $this->email;   
    return "{$this->firstName} $this->lastName";
  }
}

//An example of a presenter trait
<?php namespace App\Presenters;
trait PresentableTrait {
    protected $presenterInstance;

    public function present()
    {
        // Check if the property has been declared on the model and
        // the class exists
        if (!$this->presenter or !class_exists($this->presenter)) {
            throw new Exception('Please set the Presenter path to your Presenter FQN');
        }

        // The good old Singleton pattern
        if (!$this->presenterInstance) {
            $this->presenterInstance = new $this->presenter($this);
        }
        return $this->presenterInstance;
    }
}

<?php
namespace App\Presenters;
abstract class Presenter
{
    protected $entity; // Store the original model instance
    function __construct($entity){
        $this->beforeConstruct();
        $this->entity = $entity;
        $this->afterConstruct();
    }

  // Call the function if exists, or return the property on the original model
    public function __get($property)
    {
        if (method_exists($this, $property)) {
            return $this->{$property}();
        }
        return $this->entity->{$property};
    }
    //optional
    public function beforeConstruct(){}
    public function afterConstruct(){}
}

Some references:
https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter
http://stackoverflow.com/questions/2056/what-are-mvp-and-mvc-and-what-is-the-difference
https://github.com/laracasts/Presenter

Thoughts as this might be closer to the singleton pattern (might be an anti-pattern)?

@ihor
Copy link
Contributor

ihor commented May 27, 2016

For something to be a pattern according to Wikipedia it has to be "strictly described and commonly available". But even these few links you shared don't have the strict and common description of the Presenter.

This is because the Presenter is a just one of the components of the MVP architecture which only defines the communication flow between its three key components and their responsibilities. There is no concrete implementation of the Presenter or its interface because it can be done in many different ways.

In case, maintainers want to add architectural patterns to this repository it has to be an example of the whole MVP approach. But it's a very tricky task which requires writing much more code than for design patterns and writing a pretty good explanation of key differences and benefits comparing with other MVC family patterns.

Btw there is an interesting reading on this topic from Martin Fowler http://martinfowler.com/eaaDev/ModelViewPresenter.html

@ihor
Copy link
Contributor

ihor commented May 27, 2016

I think I wrote too much above, which created more than enough space for arguing. To make it shorter and simpler, the idea of adding Presenter pattern is the same as the idea of adding separate Model or View patterns.

@michaelachrisco
Copy link
Contributor Author

You are correct, there seems to be multiple implementations to this pattern that differ depending on the use-case(framework/language/etc..). Also the MVC/MVP patterns are probably too big to be discussed within a repo such as this. At that point, looking at frameworks would be a good start. Ill keep the issue open, as the MVP pattern is something worth thinking about.

Ill have to give this more thought. Thanks @ihor!

@ihor
Copy link
Contributor

ihor commented May 27, 2016

Rule of thumb: when in doubt, check with Martin Fowler :)

@michaelachrisco
Copy link
Contributor Author

michaelachrisco commented May 27, 2016

Following that link you gave me, it seems there is an example of a presenter model http://martinfowler.com/eaaDev/PresentationModel.html

"The essence of a Presentation Model is of a fully self-contained class that represents all the data and behavior of the UI window, but without any of the controls used to render that UI on the screen. A view then simply projects the state of the presentation model onto the glass."

Although the point still stands that a presenter has no context without its corresponding dependent models and view. Hopefully, I am not confusing the Presenter Model with just a plain old Model.

@ihor
Copy link
Contributor

ihor commented May 27, 2016

It's a different thing but it helps to achieve one of the benefits which MVP provides, which is decoupling the view and the model.

@michaelachrisco
Copy link
Contributor Author

Closing this issue until a more definite presenter pattern can be ascertained.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants