• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 208
  • Last Modified:

PHP class design, how to add the same functionality to different and unrelated classes

Dear all,

I have a design problem to submit to you guys.

Here it goes...

A class represents a series of pictures, one picture per object.

class Picture {
  var $pictureName;
  }

Another class represents a series of books, one book per object.

class Book {
  var $bookName;
  }

Now I would like to have for each of these two classes, a member function to sort these objects. The sorting is done using an arbitrary list order.

So I first modified the picture class, adding a member variable and the corresponding member functions.

class Picture {
  var $pictureName;
  var $listOrder;

  function sortByListOrder() {};
  function setListOrder() {};
  function getListOrder() {};
  }

I does the job. Fine.

To get the same functionality to the book class, I copied and pasted the code into the book class.

It works, but I have duplicated code in now two classes. And more classes are lined up craving for this sorting functionality.

I'm therefore looking for a way to add this
  var $listOrder;

  function sortByListOrder() {};
  function setListOrder() {};
  function getListOrder() {};
to a class without doing any copy/paste.

Any design suggestion..?

Cheers
Stephane



0
stephaneeybert
Asked:
stephaneeybert
  • 3
  • 2
1 Solution
 
aolXFTCommented:
<?php

This is a job for inhereitance

class sortingclass{
  function sortByName(){

  }

  function sortByOtherCriteria(){

  }
}

class
0
 
stephaneeybertAuthor Commented:
But my class is already used in many pages. I can't use a derived class name in all those pages.
And the class already inherits from a base class.

What about multiple inheritance..?
0
 
shmertCommented:
It's not clear to me what the sortByListOrder() method does, since a Picture object only contains a single picture.  Or does it?  You mentioned that
    > A class represents a series of pictures, one picture per object.

At any rate, for sorting functionality I'd recommend getting rid of the sortByListOrder() method and implementing an external comparator function and using usort().

class Picture {
  var $pictureName;
  var $listOrder;

  function setListOrder($newOrder) { $this->listOrder = $newOrder; }
  function getListOrder() { return $this->listOrder(); }
}

function compareObjects($someObject, $otherObject) {
    if ($someObject->listOrder == $otherObject->listOrder) return 0;
    return ($someObject->listOrder < $otherObject->listOrder) ? -1 : 1;
}

$firstPicture = new Picture('theFirstPicture.jpg');
$firstPicture->setSortOrder(1);
$secondPicture = new Picture('theSecondPicture.jpg');
$secondPicture->setSortOrder(2);
$unsorted = array($secondPicture, $firstPicture);
$sorted = usort($unsorted, 'compareObjects')
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
stephaneeybertAuthor Commented:
Hello shmert!

Thanks for your comment.

The sorting aspect here is not so relevant. The functionality could be anything. The problem is how to use, in different classes!, a  set of member variables and corresponding member functions.

In my case the member variable is
  var $listOrder;

and the member functions are
  function setListOrder($newOrder) { $this->listOrder = $newOrder; }
  function getListOrder() { return $this->listOrder(); }
  function sortByListOrder() { return $this->listOrder(); }

This variable and these functions are used in several different classes.

I copied and pasted the source code.

Not the smartest way to go...

So I'm looking for a design that would answer this problem.

Cheers

Stephane

0
 
shmertCommented:
Well, I think aolxft had the right idea, but didn't go into depth explaining it.  Create a common super-class called 'Sortable' and have both the Picture class and the Book class extend from this sortingClass.

class Sortable {
  var $listOrder;
  function setListOrder($newOrder) { $this->listOrder = $newOrder; }
  function getListOrder() { return $this->listOrder(); }
  function sortByListOrder() { return $this->listOrder(); }
}

class Picture extends Sortable {
  // picture stuff here
}

class Book extends Sortable {
  // book stuff here
}
0
 
shmertCommented:
If this isn't an option (for instance, if you already have a super-class that you can't change for some reason), you could use encapsulation over inheritance.  This means you would create a sortable class similar to above, but instead of extending it, the Book and Picture classes would have a variable that holds a Sortable object.  All the logic for sorting is contained in the "Sortable" class, which is reused in as many classes as you like.  Any class that wants to use the sortable functionality just has a variable to store the sortable object.

class Sortable {
  var $listOrder;
  function setListOrder($newOrder) { $this->listOrder = $newOrder; }
  function getListOrder() { return $this->listOrder(); }
  function sortByListOrder() { return $this->listOrder(); }
}

class Picture {
  var $sortable;
  function setSortable($sortable) { $this->sortable = $sortable; }
  // picture stuff here
}

$picture = new picture ('image.jpg');
$sortable = new Sortable();
$sortable->setListOrder(123);
$picture->setSortable($sortable);
$picture->sortable->sortByListOrder();
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now