0

Why exactly are all CakePHP Model methods instance methods. For example:

$post = $this->Post->findById($id);

in stead of

$post = Post::find($id);

I would think all methods that work on model instances (or records) would be instance methods, for example:

$post = ...;
$post->publish(); // Would be $this->Post->publish($id) using Cake

and all methods that create or find records (that work on the total collection of records) would be class methods (instance methods), for example:

$post = Post::findById($id); // Would be $this->Post->findById($id) using Cake

$newPost = Post::create(['title' => 'My post', 'body' => '<p>...</p>']);
// Would be $newPost = $this->Post->create([...]); using Cake

I think this Cake convention is contrary to logical OOP conventions. Does anyone know the reason of this design?

user1065745
  • 787
  • 1
  • 5
  • 9
  • 2
    It's almost certainly because each model needs the ability to have individual settings, and so it's better for the model to be able to have state to store these settings. For example, model relationships and validation rules are commonly used settings that are highly variable between individual models. – Kai Sep 15 '14 at 20:36
  • But what about static variables? Eg: class Post extends Model { static $validations = array(...); static $belongsTo = 'User'; } – user1065745 Sep 15 '14 at 20:42
  • Static properties cannot be overwritten by inheritance, and of course all user defined models in CakePHP inherit from Model, so that wouldn't really work. http://stackoverflow.com/questions/532754/inheritance-of-static-members-in-php – Kai Sep 15 '14 at 21:00
  • Static properties can be overwritten by inheritance if they are referenced using static::$variable in stead of self::$variable, right? – user1065745 Sep 16 '14 at 06:54

1 Answers1

2
  • Static calls or singletons make it hard to use dependency injection and make it hard to test your code. You're creating tight coupled code - not good. You want loose coupling.
  • When models are used through associations a new instance is created, that's why there is the alias property of the model. You can bind totally different behaviours to it or change it's state in other ways.
  • You want to be able to modify and overload properties and methods and creating new instances on the fly. Example: Have two model instances of the same table but write into two DBs. This is a very like to happen scenario for apps that use DB connections depending on the logged in user or vhost for example.
  • You clearly don't want to go through this just to extend a model: Extending singletons in PHP

I think this Cake convention is contrary to logical OOP conventions. Does anyone know the reason of this design?

What you describe is not logical nor good practice. Well, you could provide some links that would explain why you consider this as "logical OOP conventions". There are no conventions but design patterns. A good use case are "utility" classes like the classes inside the "Utility" folder of CakePHP. There is no need to have multiple instances of them.

See these questions and links as well:

If you want that "look" or think you "need" it, you can use Laravel instead of CakePHP which makes excessive use of the facade pattern for almost everything. But I guarantee you this won't make your code better.

Community
  • 1
  • 1
floriank
  • 25,546
  • 9
  • 42
  • 66