Created
July 3, 2015 15:22
-
-
Save OriginUnknown/fc58f70a702d2bb5631e to your computer and use it in GitHub Desktop.
JavaScript OOP Design Patterns - Composite Pattern v2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en"> | |
<head> | |
<title>Composite pattern - 2</title> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
var db = (function () { | |
/* | |
* * Component is the base function containing the operation method {displayInfo} | |
* * common to both leaf and composite component objects | |
*/ | |
var Component = function ( name ) { | |
if ( typeof(name) === 'string' ) { | |
var _name = name, | |
displayInfo = function () { | |
return _name; | |
}; | |
return { | |
"displayInfo": displayInfo | |
} | |
} else { | |
throw new Error( "Unsupported Operation." ); | |
} | |
}, | |
Composite = function ( name ) { | |
var composite = Component( name ), children = [], nm = name, | |
_log = "", | |
traverse = function ( indent, node ) { | |
/* | |
* * Using the Array object's join() method, join() returns to the | |
* * _log variable a modified string of the node name with | |
* * dashes (--) appended to it as the chosen separator | |
* * i.e. "Root--Alternative--African" etc. | |
*/ | |
_log += new Array( indent ++ ).join( "--" ) + node.displayInfo() + "\n"; | |
if ( node.hasOwnProperty( 'getChildren' ) ) {//if the node has the children array... | |
var i = 0, len = node.getChildren().length; | |
for ( ; i < len; i ++ ) { | |
traverse( indent, node.getChildAt( i ) ); | |
/* | |
* * ..it will call the traverse method in each child recursively. | |
* * Incidentally, the traverse method continues looping even if | |
* * the node is a leaf so long as it's parent still has children | |
* * to loop through. Else the traverse method is concluded. | |
*/ | |
} | |
} | |
}; | |
//addSong() returns a leaf object containing only the operation (displayInfo) method needed | |
composite.addSong = function ( component ) { | |
var _leaf = Component( component ); | |
children.push( _leaf ); | |
return _leaf; | |
}; | |
//createDir returns a composite object containing the relevant properties associated with this object | |
composite.createDir = function ( component ) { | |
var _comp = Composite( component ); | |
children.push( _comp ); | |
return _comp; | |
}; | |
composite.remove = function ( child ) { | |
var _parent = composite, _msg = "", | |
_children = _parent.getChildren(), | |
_len = _children.length, | |
i = 0, _node; | |
for ( ; i < _len; i ++ ) { | |
_node = _parent.getChildAt( i ); | |
if ( _node.displayInfo() === child.displayInfo() ) { | |
_children.splice( i, 1 ); | |
_msg = "Done!"; | |
return _msg; | |
} | |
} | |
}; | |
composite.getChildren = function () { | |
return children; | |
}; | |
composite.getChildAt = function ( index ) { | |
return children[ index ]; | |
}; | |
composite.showFiles = function ( n ) { | |
var _parent = composite; | |
if ( ! arguments.length > 0 ) { | |
_log = "";//clear the previous message, if any, from the _log variable | |
traverse( 1, _parent );//log all files within the parent by default | |
return _log; | |
} else { | |
var _children = _parent.getChildren(), | |
_len = _children.length, | |
i = 0, _child; | |
for ( ; i < _len; i ++ ) { | |
_child = _parent.getChildAt( i ); | |
//if n is either a child node of it's parent or the parent itself | |
if ( (_child.displayInfo() === n.displayInfo()) || (n.displayInfo() === _parent.displayInfo()) ) { | |
_log = "";//clear the previous message, if any, from the _log variable | |
traverse( 1, n );//logs a new message to the _log variable for the n arguments passed in | |
return _log; | |
} | |
} | |
} | |
}; | |
return composite; | |
}, _root = Composite( "Root" ); | |
return _root; | |
})(); | |
//Root acts like the root parent for all our songs | |
var Root = db; | |
console.log( Root ); | |
//Add two songs directly to the Root dir | |
var HappyUpHere = Root.addSong( "Happy Up Here" ), | |
MyMyMy = Root.addSong( "My My My" ); | |
//Root's sub-directories -> test#1: Create directories using the createDir method | |
var Alternative = Root.createDir( "Alternative" ), | |
Trance = Root.createDir( "Trance" ); | |
//Alternative dir - {sub dir} | |
var African = Alternative.createDir( "Afro Beats" ); | |
//Alternative dir - {songs} -> test#2: Add songs to directories using the addSong method | |
var Eple = Alternative.addSong( "Eple" ), | |
Galvanize = Alternative.addSong( "Galvanize" ), | |
Trouble = Alternative.addSong( "Trouble" ), | |
Shiver = Alternative.addSong( "Shiver" ); | |
//Alternative > African dir | |
var WakaWaka = African.addSong( "Waka Waka" ), | |
Asonto = African.addSong( "Asonto" ), | |
ChopYourDolla = African.addSong( "Chop Your Dolla" ); | |
//Trance {sub dir} | |
var Electronic = Trance.createDir( "Electronic" ), | |
Dance = Trance.createDir( "Dance" ); | |
//Trance dir - {songs} | |
var WideOpenSpace = Trance.addSong( "Wide Open Space" ), | |
Offshore = Trance.addSong( "Offshore" ), | |
DarkTrain = Trance.addSong( "Dark Train" ); | |
//Trance > Electronic > {songs} | |
var Domination = Electronic.addSong( "Domination" ), | |
UnfinishedSympathy = Electronic.addSong( "Unfinished Sympathy" ); | |
//Trance > Dance > {songs} | |
var MoveYourBody = Dance.addSong( "Move Your Body" ), | |
DrummerGetWicked = Dance.addSong( "Drummer Get Wicked" ), | |
Pride = Dance.addSong( "Pride {A deeper love}" ); | |
//Print out everything (songs and directories) within the Root directory | |
console.log( Root.showFiles() ); | |
//Print out everything (songs and directories) within the Alternative directory WITHOUT an argument | |
console.log( Alternative.showFiles() ); | |
//Print out everything (songs and directories) within the Alternative directory WITH an argument | |
console.log( Alternative.showFiles( Alternative ) ); | |
//Print out everything (songs and directories) within the African directory ONLY | |
console.log( Alternative.showFiles( African ) ); | |
//Remove the African directory from the Alternative directory | |
console.log( Alternative.remove( African ) );//pass: returns "Done!" | |
/* | |
* * Print out everything within the Alternative directory after the African | |
* * directory has been removed | |
*/ | |
console.log( Alternative.showFiles( African ) );//pass: returns undefined | |
/* | |
* * Print out everything within the Root directory after the African directory | |
* * has been removed | |
*/ | |
console.log( Root.showFiles( Root ) ); | |
//Test#10: Remove the song "My My My" from Root directory and print modified root directory | |
console.log( Root.remove( MyMyMy ) ); | |
console.log( Root.showFiles() ); | |
//Test#11: When an object is passed to the createDir method, it returns "Unsupported Operation." | |
//var BlackEyedPeas = Root.createDir({"name":"Black Eyed Peas"});//pass. | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment