Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OOP exercise #222

Merged
merged 5 commits into from
Aug 25, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions submissions/kotlyar-andrey/oop_exercise/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/* Refer to https://github.com/OleksiyRudenko/a-tiny-JS-world for the task details
Complete the below for code reviewers' convenience:

Code repository: https://github.com/kotlyar-andrey/a-tiny-JS-world
Web app: https://kotlyar-andrey.github.io/a-tiny-JS-world/
*/

class Creature {
constructor(species, name, gender, phrase) {
this._species = species;
this._name = name;
this._gender = gender;
this._phrase = phrase;
this._friends = [];
this._properties = ["_species", "_name", "_gender", "saying"];
}

getFriends() {
return this._friends && this._friends.length > 0
? this._friends.map((friend) => friend._name).join(", ")
: "no friends";
}

setFriends(newFriends) {
this._friends = [...newFriends];
}

getSaying() {
return self._phrase;
}

setSaying(newPhrase) {
this._phrase = newPhrase;
}

addProperties(...newProperties) {
this._properties = [...this._properties, ...newProperties];
}

display() {
const friends = this.getFriends();
print(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A class shouldn't know anything about external environment.
Using a side effect (print is a side effect) also makes the class less flexible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I can rename display to getInfo and return value

getInfo() {
  const friends = this.getFriends();
  const saying = this.getSaying();
  return this._properties
    .map(prop => this[prop])
    .join("; ")
    .concat(`; ${saying}; ${friends}`);
}

End then print inhabitants

inhabitants.forEach(creature => {
   print(creature.getInfo());
});

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making class method just return some data is definitely a good design decision.

this._properties
.map((prop) => this[prop])
.join("; ")
.concat(`; ${friends}`)
);
}
}

class HomoSapiens extends Creature {
constructor(species, name, gender, phrase, legs, hands) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want users to specify species for class Homo Sapiens?

super(species, name, gender, phrase);
this._legs = legs;
this._hands = hands;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do all animals have hands?
Imagine we popultae the world with birds, fish, rhinos and deer.
OOP helps to model the real world quite accurately avoiding defining properties and behavior that the counterparts in the real world do not have.

this.addProperties("_legs", "_hands");
}

get saying() {
return this._phrase;
}
}

class Animal extends Creature {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strictly speaking humans are animals as well. We need to resolve the matter in a consistent way.

constructor(species, name, gender, phrase, paws, wings) {
super(species, name, gender, phrase);
this._paws = paws;
this._wings = wings;
this.addProperties("_paws", "_wings");
}

get saying() {
return this._phrase;
}
}

class Anomaly extends HomoSapiens {
constructor(species, name, gender, phrase, legs, hands, linkTo) {
super(species, name, gender, phrase, legs, hands);
this._linkTo = linkTo;
}
get saying() {
return this._linkTo._phrase;
}
}

const man = new HomoSapiens("human", "Ivan", "male", "Hello", 2, 2);
const woman = new HomoSapiens("human", "Maria", "female", "Hi", 2, 2);
const dog = new Animal("dog", "Bars", "male", "Woof", 4, 0);
const cat = new Animal("cat", "Jerry", "male", "Myau", 4, 0);
const parrot = new Animal("parrot", "Kuzya", "male", "How are you?", 2, 2);
const woman_cat = new Anomaly("woman-cat", "Marta", "female", "", 2, 2, cat);
const man_parrot = new Anomaly("man-parrot", "Petr", "male", "", 2, 2, parrot);

man.setFriends([woman, cat, dog]);
woman.setFriends([man, cat]);
dog.setFriends([cat]);
woman_cat.setFriends([man, cat]);

cat.setSaying("Hello, it's me, your cat");

const inhabitants = [man, woman, dog, cat, parrot, woman_cat, man_parrot];

inhabitants.forEach((creature) => {
creature.display();
});