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

tiny-js-oop #439

Merged
merged 3 commits into from
Sep 27, 2022
Merged

tiny-js-oop #439

merged 3 commits into from
Sep 27, 2022

Conversation

Yasya23
Copy link
Contributor

@Yasya23 Yasya23 commented Sep 5, 2022

OOP classes

Demo |
Code base

The code is submitted in a dedicated feature branch.

Only code files are submitted.

Please, review.

@github-actions
Copy link

github-actions bot commented Sep 5, 2022

Hey!

Congratulations on your PR! 😎😎😎

Let's do some self-checks to fix most common issues and to make some improvements to the code before reviewers put their hands on the code.

Go through the requirements/most common mistakes listed/linked below and fix the code as appropriate.

If you have any questions to requirements/common mistakes feel free asking them here or in Students' chat.

When you genuinely believe you are done put a comment stating that you have completed self-checks and fixed code accordingly.

Also, be aware, that if you would silently ignore this recommendation, a mentor can think that you are still working on fixes. And your PR will not be reviewed. 😒

A Tiny JS World -- OOP exercise check list

Relates to A Tiny JS World OOP exercise.

Check-list - definition of done

Minimal requirements to meet:

  • Implement a base class to inherit from
  • Employ default parameters
  • Each species is represented with its own class
  • No need to specify species at instantiation
  • Classes for species that do not have hands by natural design, do not consequently have hands or any equivalent property and do not inherit such properties from any base classes
  • All inhabitants are stored in a container (array or object)
  • JS native features are intensively employed (const, let, Array.map|join|forEach|..., etc)
  • Object methods like keys, values, entries as well as for...in shouldn't be used as these do not guarantee any particular order of keys/values
  • Properties used to form an object presentation string must be explicitly listed/specified; Use Array.map and Array.join to build a presentation string from the list.
  • A parent class shouldn't know anything about its children's props. Child classes must have good reasons to assign or refer to any parent's props. There are no such reasons in this task. Method overloading is to the rescue when building an inhabitant's presentation string.
  • OOP, SOLID and DRY principles are intensively employed

Optional level up (not required to implement):

  • Friends list is a list of objects refs rather than names (strings)
  • Cat-woman class is built employing composition rather than inheritance only

Bonus:

  • toString magic method; when implemented print(inhabitant) does the job as .toString is called implicitly
  • this.constructor.name; when used for output then no need to store species property

Helpful resources:

Universal recommendations:

  • Give variables and functions meaningful names. Avoid generic names like item, element, key, object, array or their variations. Exception: helper functions that are specifically and intentionally designed to be multipurpose.
  • Function names should start with a verb as they denote actions; variables are normally nouns; boolean variables/functions start with is, does, has etc; variable containing multiple entities and functions returning lists contain entity name in plural form.
  • Have consistent code style and formatting. Employ Prettier to do all dirty work for you.
  • Use common sense or seek for an advice whenever requirements look ambiguous or unclear.

Also take a note of the requirements above and follow them in all your future projects.

By the way, you may proceed to the next task before this one is reviewed and merged.

Sincerely yours,
Submissions Kottachecker 😺

@Yasya23
Copy link
Contributor Author

Yasya23 commented Sep 5, 2022

Self-check has been done. Everything should be ok.

@stale
Copy link

stale bot commented Sep 19, 2022

This issue has been automatically marked as stale because there were no activity during last 14 days. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.

А. Чому так?
Найбільш розповсюджена причина: Студент не реагує на коментарі змінами коду і не задає запитань через брак часу або зміну життєвих пріоритетів. Покинуті піари відволікають менторів. Коли у студента з'явиться час, він/вона зможе перевідкрити той самий піар і продовжити роботу.

Б. Що робити, якщо в піарі нема оновлень, оскільки не зрозуміло, що треба зробити?
Варіант 1. Задати питання в самому PR.
Варіант 2. Задати питання в студентському чаті.

В. А якщо я все зробив(ла) і це ментор не рев'юває мої зміни?

  1. Переконайся, що ти відреагував(ла) на всі коментарі або кодом, або запитаннями, або відповідями. Напиши в PR і в чаті, що чесно вважаєш, що все зроблено і попроси повторне рев'ю. Якщо щось не зрозуміло, задай запитання.
  2. Реагуй на коментарі як менторів, так і інших учасників, включаючи ботів.
  3. Не ігноруй прохання типу * "Let's do some self-checks ..." * "Go through the checklist below..." * "mark fulfilled requirements..." * "if you would silently ignore this recommendation, a mentor may think that you are still working on fixes"
    навіть якщо вони написані ботом. Боти помічники і ментори покладаються на те, що прохання і пропозиції бота дотримуються.
    Не лінись піти по лінках в коментарях, погуглити термінологію та скористатись Google Translate.
  4. Можливо, у менторів склалися інші пріоритети через роботу, сімейні обставини і т.п. В такому разі, якщо ти зробив(ла) рекомендоване вище, то волай в чаті, що PR позначений stale, наче, все зроблено, а ментори чомусь не реагують - рятуйте!

Г. Хіба недостатньо того, що я додав(ла) коміт із змінами?
Часто буває так, що бачиш новий коміт, ідеш перевіряти, змін багато, доводиться перечитувати весь код. А потім з'ясовується, що одна невеличка зміна "відкладена на потім" чи з'являється ще один коміт і знов треба перечитувати все. Любіть нас, спілкуйтеся з нами - і ми відповімо повною взаємністю.

Традиційна пропозиція: задай питання по вищенаписаному в студентському чаті.

@stale stale bot added the 💤 Stale label Sep 19, 2022
@Yasya23
Copy link
Contributor Author

Yasya23 commented Sep 19, 2022

Self-check has been done.

@stale stale bot removed the 💤 Stale label Sep 19, 2022
@OleksiyRudenko OleksiyRudenko added the self-check-done Student confirmed that self-checks against requirements/common-mistakes are done label Sep 20, 2022
Copy link
Member

@OleksiyRudenko OleksiyRudenko left a comment

Choose a reason for hiding this comment

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

@Yasya23 good job!
A couple of improvements and we are done.

constructor(species, name, gender, saying) {
super(species, name, gender);
this.paws = 4;
this.saying = saying;
Copy link
Member

Choose a reason for hiding this comment

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

What makes saying different from name in terms of generalization into the base class?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hello, thanks for checking! There is no difference in these cases, fixed it.

}

showProperties() {
return `${this.species}; ${this.name}; ${this.gender}`;
Copy link
Member

Choose a reason for hiding this comment

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

This and similar fragments below:
Benefit from Array methods. This will make code DRYer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Corrected for an array.

@OleksiyRudenko OleksiyRudenko self-assigned this Sep 20, 2022
Copy link
Member

@OleksiyRudenko OleksiyRudenko left a comment

Choose a reason for hiding this comment

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

@Yasya23 nearly there

Comment on lines 56 to 58
inhabitants.forEach(function (inhabitant) {
print(inhabitant.showProperties());
print(inhabitant.showProperties().join("; "));
});
Copy link
Member

Choose a reason for hiding this comment

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

Arrow functions will make code less verbose.
Compare:

inhabitants.forEach(function (inhabitant) {
  print(inhabitant.showProperties().join("; "));
});

inhabitants.forEach(inhabitant => print(inhabitant.showProperties().join("; ")));

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for checking. Yes, it looks much better, fixed it.

return `${super.showProperties()}; ${this.hands}; ${this.legs}; ${
this.saying
}`;
return [...super.showProperties(), this.hands, this.legs, this.saying];
Copy link
Member

Choose a reason for hiding this comment

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

Here and line 32 below:

  • repetition
  • also a shared property should be handled by the class that owns it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed it but I`m not sure about my decision. If it's incorrect please give me advice.

Copy link
Member

Choose a reason for hiding this comment

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

That's a good start.
Your previous method version returned a string. Now it returns array not joined into string. Why?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm a little confused. The join method returns a string from the array of elements. If I add it here then it will return a string.

showProperties() { return [ ...super.showProperties().slice(0, 3), this.paws, ...super.showProperties().slice(3, 4), ].join("; "); }

But I don’t understand the difference, because at the end I still iterate over the array and add a join.

inhabitants.forEach(inhabitant => print(inhabitant.showProperties().join("; ")));

Apparently, there is something I don't understand.

Copy link
Member

Choose a reason for hiding this comment

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

My question was about reasons behind changing from string to array. It is a significant change.

Copy link
Member

Choose a reason for hiding this comment

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

Both approaches may be valid. Want to understand reasoning.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because of that post)

This and similar fragments below:
Benefit from Array methods. This will make code DRYer.

For myself, I realized that I need to create an array instead of a string. But now I understand that I could iterate through the array of values ​​​​using the map method and add a join, and not write a semicolon after each value. Something like this.

["species", "name", "gender", "saying"] .map((property) => this.property) .join("; ");

Only working with an array for me here looks easier if I want to insert a value in its middle.

Copy link
Member

@OleksiyRudenko OleksiyRudenko left a comment

Choose a reason for hiding this comment

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

@Yasya23 great job done!

Comment on lines +23 to +26
...super.showProperties().slice(0, 3),
this.hands,
this.legs,
...super.showProperties().slice(3, 4),
Copy link
Member

Choose a reason for hiding this comment

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

I realize why slicing.
Just notice that this is not a really good approach. Why? A: This means that a developer working on Human or any other subclass would need to know what is the right order of props in the base class. Likewise, developer working on Inhabitants class (e.g. add a property between already existing) should be aware their changes may affect subclasses' behavior. On big projects it is not feasible. Ideally, every class handles its own properties and unaware of other classes internals.

P.S. BTW, class names by convention are singular unless they really contain multiple instances of anything.

@OleksiyRudenko OleksiyRudenko merged commit 44ced0c into kottans:main Sep 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
self-check-done Student confirmed that self-checks against requirements/common-mistakes are done task-TJSW-OOP
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants