Click here to Skip to main content
13,147,376 members (25,942 online)
Rate this:
Please Sign up or sign in to vote.
See more:

I need your help. If I add the drums to the cymbals that already belong to drums then I create a circular reference. When calling getDescription() a line like this can crash a Web Server. I want to safeguard against such mistakes. My strategy would be to check during the add() method to see whether the instrument being added already contains a reference to the one calling the method.My pseudo-code is:

  1. Check if drums has children;

  2. If has children then compare drums with cymbals:

  3. If are equals then return true else return false;

My questions are:
  1. Is it correct my logic/pseudo-code?

  2. To transale this pseudo-code to PHP, is it good idea to create a recursive method or interactive method?

  3. There is another way to check a circular reference? If so, please tell me!

body{ font:12px Verdana, Geneva, sans-serif; font-weight:bold}
td{ font:11px Verdana, Geneva, sans-serif;}
abstract class AbstractInstrument{
	private $name;
	private $category;
	private $instruments = array();
	public function add(AbstractInstrument $instrument){
		array_push($this->instruments, $instrument);	
	public function remove(AbstractInstrument $instrument){
		array_pop($this->instruments, $instrument);
	public function hasChildren(){
		return (bool) (count($this->instruments) > 0);
	public function getChild($i){
		return $instruments[$i];
	public function getDescription(){
		echo "- one ".$this->getName();
			echo " which includes:<br>";
			foreach($this->instruments as $instrument){
				echo "<table cellspacing=\"5\" border=\"0\"><tr><td>   </td><td>-";
				echo "</td></tr></table>";
	public function setName($name){
	public function getName(){
		return $this->name;
	public function setCategory($category){
	public function getCategory(){
		return $this->category;
class Guitar extends AbstractInstrument{
	function __construct($name){
class DrumSet extends AbstractInstrument{
	function __construct($name){
class SnareDrum extends AbstractInstrument{
	function __construct($name){
		parent::setCategory("snare drums");
class BaseDrum extends AbstractInstrument{
	function __construct($name){
		parent::setCategory("base drums");
class Cymbal extends AbstractInstrument{
	function __construct($name){
$drums = new DrumSet("tama maple set");
$drums->add(new SnareDrum("snare drum"));
$drums->add(new BaseDrum("large bass drum"));
$cymbals = new Cymbal("zildjian cymbal set");
$cymbals->add(new Cymbal("small crash"));
$cymbals->add(new Cymbal("large high hat"));
//$cymbals->add($drums); //Uncomment this and then it will show an error!!
$guitar = new Guitar("gibson les paul");
echo "List of instruments: <p>";
Posted 13-Feb-13 4:59am
Sergey Alexandrovich Kryukov 13-Feb-13 13:41pm
Before we continue, can you explain what's wrong in circular references? They are pretty much a commonplace, can be found anywhere. What's wrong?
Peter Trumbull 13-Feb-13 16:46pm
I think a circular reference is a mistake very serious. Please copy code, uncomment "//$cymbals->add($drums)" and test! This will origin a error. I want prevent this mistake.
Rate this: bad
Please Sign up or sign in to vote.

Solution 1

Your $drums is actually a drum set, not a collection of drums, isn't it?

So should you not be adding each cymbal to that collection rather than adding cymbal to a collection of cymbals then adding that collection to the drum set?

So I would have a Drum Set to which I add each drum and each cymbal(or add a collection of drums and a collection of cymbal)

If Cymbals needs a reference to the Drum Kit then all good - the collection of Cymbals' parent would be the drum kit.
Peter Trumbull 14-Feb-13 5:38am
My $drums is actually a drum set, not a collection of drums.

No. I should not be adding drums to the cymbals that already belongs to drums! This origin a circular reference.

A drum set is a composite of (1 or more)drum(s) and (1 or more)cymbal(s).

My questions are:
1)Is it correct my logic/pseudo-code?
2)To transale this pseudo-code to PHP, is it good idea to create a recursive method or interactive method?
3)There is another way to check a circular reference? If so, please tell me!
_Maxxx_ 14-Feb-13 6:02am
You say you shouldn't be adding drums to the cymbals - then surely the answer is "then don't"
The way you are setting up our drum$ is that it is a collection that contain individual drums plus a collection of cymbals. M<y suggestion is that it simply contains individual drums and individual cymbals , or it contains a collection of drums and a collection of cymbals.

I guess i simply can't see why you would want to uncomment the line in question - I believe your design is flawed and, rather than work around the issue, you would be better off fixing the design.
Peter Trumbull 14-Feb-13 6:09am

But can you answer my questions?
Rate this: bad
Please Sign up or sign in to vote.

Solution 2

It is not possible to answer your question sensibly;

Your pseudo code will always return true given the info you have given.

if you can add a drum kit to a cymbal, could you also add a cymbal to a cymbal, or a drum to a cymbal? Your Cymbal object seems to act both as an individual and a collection of cymbals (there is no Cymbalset class) so I cannot deduce what your intentions may be.

If you talk abstractly of collections that can hold collections and you do not want to add collection a to collection b if some object already in collection b contains collection a, then you would need to traverse the entire tree every time you want to add to any collection; If I had to do it I would do it recursively - but as I said earlier, i wouldn't do it like this in the first place.
Peter Trumbull 14-Feb-13 6:27am
Thanks for your help anyway.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy |
Web04 | 2.8.170915.1 | Last Updated 14 Feb 2013
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100