PHP object composition practice - php

I have a Parent Class Model Like this:
namespace vendor\appname\core;
class Model
{
protected $db;
protected $session;
protected $cookie;
protected $record;
public function __construct()
{
$this->db = new Db;
$this->session = new Session;
$this->cookie = new Cookie;
$this->record = new Record;
}
}
here I have my child models where i can extend the base model and use there objects
namespace vendor\appname\models;
use vendor\appname\core;
class Login extends Model
{
// here i can use simply like so
$this->db->prepare() // and so on
$this->session->set() // and so on so fourth
}
So if i have 100 class should i do the same thing "object composition " is this a good practice ??? what about the registry pattern or factory ? is it possible to implement it here ? or dependency injection

Based on your question, i think you should probably read and research more about the first five OO design principle (SOLID) and General Responsibility Assignment Software Principle (GRASP) to understand more about design pattern and object creation.
Having said that, what you are doing is more of inheritance instead of composition. To make it simple,
Inheritance is more of an "is-a" relationship, for example a UserModel "is-a" Model, thus all properties and methods of a Model will be part of a UserModel.
Aggregation is more like "uses-a" relationship. A Model "uses-a" QueryBuilder and DatabaseClient.
Composition on the other hand, is more like "has-a" or "contain-a" relationship for instance, Book "contain-a" Page.
This is just an example in hope of making things a bit clear for you. Having understanding in these and also Solid and Grasp would make you understand about various design patterns available.

Related

Get the calling object from superclass

I've built a "model" superclass for a MVC framework. In most methods i do need only the class name so i've used get_called_class() but for save and edit methods i need to pass the object with values.
In my design, when you create a model object and you save or edit you have to do:
$object->save($object); or $object->update($object, $id).
I really don't like this, because looks as a bad design. I would like just to say:
$object->save(); and $object->update($id);
Since you are effectively saving the current object.
Models classes extends a Model parent that defines their behaviour and create the DB connection for them.
The methods of superclass that i would like to make does not take as an argument $object but rather i would like to say "get the calling object".
public function save($object) {
return self::$db->save($object);
}
public function update($object,$id) {
return self::$db->update($object, $id);
}
I know that this can be easily doable the in the object model with
public function save () {
parent::save($this);
}
But i would like not to have to reimplement this behaviour for every single model!
Thank you in advance.
The use of any existing ORM library isn't discussed here, since i want to provide a querybuilder and simple ORM that is PDO based as default. Because i do not want to have any 3rd party dependency as default
Define your base model as abstract class and inherit default behavior to child model classes.
abstract class Model
{
public function save() {
return self::$db->save($this);
}
public function update($id) {
return self::$db->update($this, $id);
}
}
class UserModel extends Model;
$myModel = new UserModel();
$myModel->save();

PHP design- abstract classes and factory methods

I am trying to work out the best way to design my classes and I think abstract classes it the right way here, but I'm not sure! I am building a plugin for Wordpress carts that at the moment, will work for both Woocommerce and WP-Ecommerce. As these two systems have different implementations of certain functionality, such as getting an order object, I want to create a separate class for each platform.
I have the following which will contain generic methods that should be available to the classes that inherit from it. This class should never be instantiated:
class Order_Export {
}
I then have 2 more classes that will inherit from the above:
class Order_WooExport extends Order_Export {
}
class Order_WPExport extends Order_Export{
}
Is my design right here? Am I right in saying the class Order_Export should be an abstract class? What about methods that I want the class inheriting to implement? Do I simply mark the signature in the abstract class and not provide a body, or do interfaces come into play somewhere here?
How about instantiating the right class? Do I create a factory that will return one or the other?
Any advice appreciated!
That sound correct to use abstract base class, as long as you are sure to never need to instantiate Order_Export :
abstract class Order_Export
{
abstract protected function someMeth1();
abstract protected function someMeth2();
public function someMeth3() {
// Do common thing to both Order_WooExport and Order_WPExport
// using someMeth1(), someMeth2()...
}
}
Then :
class Order_WooExport extends Order_Export
{
protected function someMeth1() {
// Do something specific
}
protected function someMeth2() {
// Do something specific
}
}
Finally, the factory seems to be the right way to go too.

Class structure possibly needing implementation of composition to mimic multiple inheritance

Here's the basic premise, I'm using an active record pattern for db objects, and I think I need some direction how to organize these classes. And also in general how I could potentially split up my class structure. Hopefully I don't explain this too terribly. If composition pattern is the way to go I may need a little hand holding on a way to implement it.
Let's say there's the ActiveRecord base class, at the bottom of the totem pole that deals with mapping objects to the db and the db to objects.
A child of ActiveRecord is a sort of generic User class, that deals with user sessions, logins, encryption of the password field on save and such.
Another child of ActiveRecord is a ActiveRecordButSlightlyMoreAdvanced class. Usually this class has nothing to do with User, but here's my issue.
I want to have a subclass that wants to be essentially a combination of User and ActiveRecordButSlightlyMoreAdvanced; UserButSlightlyMoreAdvanced, without having to copy paste all of the methods from User. It doesn't make sense for User to extend ActiveRecordButSlightlyMoreAdvanced, as it'd require essentially overriding a bunch of methods that have undesirable behavior for User.
It would make sense for UserButSlightlyMoreAdvanced to extend ActiveRecordButSlightlyMoreAdvanced, but I'd have to copy and paste a bunch of methods from User.
I know some people think better with pictures, so here's the structure illustrated.
Base
class ActiveRecord
{
....
}
Child
class User extends ActiveRecord
{
....
}
Also Child
class ActiveRecordButSlightlyMoreAdvanced extends ActiveRecord
{
....
}
The Problem
class UserButSlightlyMoreAdvanced extends User AND ActiveRecordButSlightlyMoreAdvanced
{
:( :( :(
}
I've been thinking about this problem for about a month now and cannot think of a solution that doesn't place burden of maintaining the objects dually if there's a change to how one of them implements saving. I'm going to experiment with a few solutions over the next couple of days and possibly post what I think was best in this situation.
My guess is that you meant to say this:
class UserButSlightlyMoreAdvanced extends User AND ActiveRecordButSlightlyMoreAdvanced
{
:) :) :)
}
If that is the case, look into traits http://php.net/manual/en/language.oop5.traits.php
You might try using the strategy pattern. In this case you would create your class:
class UserButSlightlyMoreAdvanced extends ActiveRecord implements ActiveRecordButSlightlyMoreAdvancedStrategy
{
private $_strategy;
public function useStrategy(ActiveRecordButSlightlyMoreAdvancedStrategy $s) {
$this->_strategy = $s;
}
}
and make your strategy class:
interface ActiveRecordButSlightlyMoreAdvancedStrategy
{
// Define what this should do here
}
Make a strategy class that implements the above interface.
class ActiveRecordButSlightlyMoreAdvanced implements ActiveRecordButSlightlyMoreAdvancedStrategry {
// Do stuff here
}
Now when you call those advanced methods, both classes implement the same interface, but the UserButSlightlyMoreAdvanced class just passes the requests through to the strategy object:
class UserButSlightlyMoreAdvanced extends ActiveRecord implements ActiveRecordButSlightlyMoreAdvancedStrategy
{
private $_strategy;
public function useStrategy(ActiveRecordButSlightlyMoreAdvancedStrategy $s) {
$this->_strategy = $s;
}
public function someSlightlyMoreAdvancedFunction () {
return $this->_strategy->someSlightlyMoreAdvancedFunction():
}
}
Hope that helps.

Would PHP traits be a good solution

I'm working on a MVC application in which the Model is implemented using an abstract base class that all actual models have to extend. In every model there is some info about that model, currently implemented as an array, let call that protected static $info. So, every model has a different $info array. Now, the base class has lots of functions that use data from that array, and at the moment every one of those functions starts with something like the example save() function below.
abstract class BaseModel {
function save(){
$className = get_called_class();
$modelInfo = $className::$info;
/* lots of other stuff */
}
}
class User extends BaseModel {
protected static $info = array("tableName" => "tblUsers", etc...)
}
In my understanding, this can be resolved by making the BaseModel a trait instead of a constructor, since when traits define static properties, each inheriting class does have their own values. I would copy the $info array from the implementation of the Model to the trait, probably in the constructor, so that I can use self::info['tableName'] in all the functions in the BaseModel...
Would this be a good idea?
The simplest and most appropriate tool for the job would be to use late static binding:
function save(){
$modelInfo = static::$info;
/* lots of other stuff */
}

The M of MVC (ZF)

I don't get it how it really works.
I have a database table user and a model User:
<?php
class User extends Zend_Db_Table_Abstract {
protected $_name = 'users';
}
And in the controller I call it: $user = new User()
But how do I get for example all users or a user with the id: 1?
Zend_Db_Table implements the Table Gateway pattern and the associated Zend_Db_Table_Row implements the Row Data Gateway pattern.
This means that as the table class represents your database table, it makes more sense to use a plural class name. Similarly, a singular class name should be used for the row class.
Hence you end up with something like this:
class Model_Users extends Zend_Db_Table_Abstract
{
protected $_name = 'users'; // database table name
protected $_rowClass = 'Model_User'; // row class name
public function fetchAllInLastNameOrder()
{
return $this->fetchAll(null, array('last_name', 'first_name'));
}
public function fetchUserById($id)
{
return $this->_fetchRow('id = '. (int)$id);
}
}
class Model_User extends Zend_Db_Table_Row_Abstract
{
public function getFullName()
{
return trim($this->title . ' '
. $this->first_name . ' '
. $this->last_name);
}
}
The point of creating your own classes is that you can add your own methods that your controllers and views can then use. You should never use the Zend_Db_Table methods directly other than in your model classes. This is because this model design is tightly coupled to the database implentation. Over time, you may find that this isn't flexible enough and want to use a different system. If you have ensured that the rest of your application only ever accesses methods created in Model_Users and Model_User then you should be able to reimplement your model without breaking the rest of your app...
For larger applications and ones with complex business logic, it is rare for a model to be a simple wrapper over a single database table. For better flexibility and maintainability, you can consider creating models which are simple classes and then using a mapper class that maps from the model to the database. This is explored by Matthew Weier O'Phinney in his talk Architecting Your Models, which I highly recommend looking at.
Also, for ideas on how to use the model from within the controller, the Quick Start or my tutorial are good starting points.
Are you looking for $user->find()?
Also, Zend_Db_Table != Model. You can read more about the M of MVC here:
Model Infrastructure
Zend Framework: Surviving the Deep End
Writing Robust PHP Backends with Zend Framework
Try creating a static method in your User class that returns an array of all users.

Categories