Challenge: Solution Review

This lesson will explain the solution to the problem from the last coding challenge.

We'll cover the following

Solution #

//Component
class Directory {
constructor(name, lastModified, size) {
this.name = name
this.lastModified = lastModified
this.size = size
}
getLastmodified() { }
getSize() { }
getName() { }
}
//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
}
}
//Compsoite subclass
class Folder extends Directory {
constructor(name) {
super(name)
this.lastModified = 0
this.size = 0
this.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 methods getLastmodified, getSize, and getName. A directory has the following properties: name, lastModified, and size.

  • Leaf: File is Directory's subclass. It is the leaf component as it has no children. It defines the functions getLastmodified, getSize, and getName returning the name, size, and lastModified 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 names 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.