Challenge: Solution Review
This lesson will explain the solution to the problem from the last coding challenge.
We'll cover the following
Solution #
//Componentclass Directory {constructor(name, lastModified, size) {this.name = namethis.lastModified = lastModifiedthis.size = size}getLastmodified() { }getSize() { }getName() { }}//Leaf subclassclass File extends Directory {constructor(name, lastModified, size) {super(name, lastModified, size)}getLastmodified() {return this.lastModified}getSize() {return this.size}getName() {return this.name}}//Compsoite subclassclass Folder extends Directory {constructor(name) {super(name)this.lastModified = 0this.size = 0this.files = []}addFile(file) {this.files.push(file)this.size += file.getSize();}removeFile(file) {for (var i = 0; i < this.files.length; i++) {if (this.files[i] == file) {this.files.splice(i, 1)this.size -= file.getSize();}}}getLastmodified() {var times = []if (this.size == 0) {return this.lastModified}else{for (var i = 0; i < this.files.length; i++) {times[i] = this.files[i].lastModified}this.lastModified = Math.min(...times)return this.lastModified}}getSize() {return this.size}getName() {var names = []for (var i = 0; i < this.files.length; i++) {names[i] = this.files[i].name}return names}}const file1 = new File("dogo.png", 2, 45)const file2 = new File("catty.png", 4, 32)const folder = new Folder("Pictures")folder.addFile(file1)folder.addFile(file2)console.log(folder.getLastmodified())console.log(folder.getSize())console.log(folder.getName())folder.removeFile(file2)console.log(folder.getName())console.log(folder.getSize())const file = new File("penguiny.png", 6, 12)console.log(file.getName())
Explanation
The illustration below provides a visualization of the hierarchy of the classes in the code above:
From the illustration above, you can see that the pattern consists of the following:
-
Component:
Directory
class which contains the abstract methodsgetLastmodified
,getSize
, andgetName
. A directory has the following properties:name
,lastModified
, andsize
. -
Leaf:
File
isDirectory
's subclass. It is the leaf component as it has no children. It defines the functionsgetLastmodified
,getSize
, andgetName
returning thename
,size
, andlastModified
time of a file. -
Composite
Folder
is the composite subclass. It has other files as its children.
Let’s start to discuss each component.
Directory
//Component
class Directory{
constructor(name,lastModified,size){
this.name = name
this.lastModified = lastModified
this.size = size
}
getLastmodified(){}
getSize(){}
getName(){}
}
A Directory
object will contain the properties: name
, lastModified
, size
, and the methods: getLastmodified
, getSize
, and getName
.
File
//Leaf subclass
class File extends Directory{
constructor(name,lastModified,size){
super(name,lastModified,size)
}
getLastmodified(){
return this.lastModified
}
getSize(){
return this.size
}
getName(){
return this.name
}
}
File
is the leaf subclass of Directory
. The super
command initializes the constructor
of Directory
, setting the name
, lastModified
time, and size
of the File
instance.
It also redefines the methods:
getLastmodified
, getSize
, and getName
returning the name
, size
, and the lastModified
time of the file.
Folder
class Folder extends Directory{
constructor(name){
super(name)
this.lastModified = 0
this.size = 0
this.files = []
}
//code...
}
The Folder
is the composite subclass of Directory
. The super
command initializes the constructor
of Directory
, setting the name
of the instance. We set the lastModified
and size
of the folder to 0
since upon creation the folder is empty so the size will be zero. Similarly, it hasn’t been modified yet so lastModified
will be zero as well.
In the constructor
, we also initialize the files
variable, which stores the list of files present in the folder.
We can add/remove files from a folder. So it contains the additional functions for adding/removing files:
class Folder extends Directory{
//code...
addFile(file){
this.files.push(file)
this.size += file.getSize()
}
removeFile(file){
for(var i=0; i<this.files.length; i++){
if(this.files[i] == file){
this.files.splice(i,1)
this.size -= file.getSize();
}
}
}
}
From the code, you can see that the size
of the folder gets modified every time a file
is added or removed.
The getLastmodified
function is defined as follows:
getLastmodified() {
var times = []
if (this.size == 0) {
return this.lastModified
}else{
for (var i = 0; i < this.files.length; i++) {
times[i] = this.files[i].lastModified
}
this.lastModified = Math.min(...times)
return this.lastModified
}
}
First, it checks if the folder is empty by checking its size
. In case it is, it simply returns the default lastModified
date which is. 0
. Else, it stores the lastModified
times of all the files in the folder in a times
array. Next, it finds the minimum of those times and sets the lastModified
of the folder
equal to that. In the end, it returns the lastModified
time of the folder.
The getSize
function returns the size of the folder:
getSize(){
return this.size
}
The getName
function is defined as follows:
getName(){
var names = []
for (var i=0; i<this.files.length; i++){
names[i] = this.files[i].name
}
return names
}
It stores the name
s of all the files in the folder in an array, names
. In the end, it returns the names
array.
So now, we can make a folder and add/remove files from it. We can also access the size, last modified time, and name of the folder. In the same way, we can create a single file that is not a part of any folder and access its properties in the same manner.
const file1 = new Files("dogo.png", 2,45)
const folder = new Folder("Pictures")
folder.addFile(file1)
folder.getName()
const file = new Files("penguiny.png",6,12)
file.getName()
Let’s discuss the flyweight pattern in the next lesson.