Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save OleksiyRudenko/44bc64f66e73bc2f99a151a544374a20 to your computer and use it in GitHub Desktop.
Save OleksiyRudenko/44bc64f66e73bc2f99a151a544374a20 to your computer and use it in GitHub Desktop.
Exercise self-check lists

Minimal requirements to meet

  • Code is DRY, which means that whenever you see a pattern in your code those should be eliminated as much as possible. Examples:
    • print(dog); print(cat); etc ... should be refactored employing Array.forEach as the least
    • `${obj.legs}; ${obj.name}; etc...` (yes, strings are also code) must be refactored employing appropriate Array methods
  • Properties used to form an object presentation string must be explicitly listed/specified
  • Object methods like keys, values, entries shouldn't be used as these do not guarantee any particular order of keys/values

Frogger Arcade Game -- JS OO exercise check list

A self-check list. Relates to Object-Oriented JavaScript task.

Check-list

Minimal requirements to meet:

  • it is OK to employ ES6 features like const, let etc.
  • the code is very DRY
  • OO is implemented using JS prototype chain object model (not ES6 classes syntax)
  • Requirements re Constants:
    • all numbers like block dimensions, initial locations are defined as named constants (e.g. const STEP = 101;) as otherwise numbers scattered across code base look cryptic; named constants add semantic meaning and improve readability
    • every number that have a semantic purpose (like those listed above) should be defined as constants; think of how your code reads - the closer to plain English the better
    • there are core constants and derived constants (e.g. derived constant const FIELD_WIDTH = BLOCK_WIDTH * BLOCKS_NUMBER;)
    • arrays of constants are also constants (e.g. const INITIAL_POSITIONS = [1,2,3,4].map(rowNumber => rowNumber * BLOCK_HEIGHT);)
    • const objects help organizing and structure const data even better (e.g. const PLAYER_CONF = { initialPosition: {x: 1, y: 5}, sprite: '...', ...etc... };
  • Requirements re OOP:
    • classes do not refer to any global variables, like global variable player, which is an instance of Player class (referring to global constants and globals provided by the gaming platform like Resources is OK); Hint: pass Player instance as an argument to every enemy
    • Separation of Concerns principle is followed (e.g. update method does only rendering and doesn't contain any unrelated inline code; for example collision check is defined as a dedicated method and only called from inside update)
    • Nice To Have: properties common for some classes are generalized into a base class (e.g. there is Character base class, which is extended by Enemy and Player classes)
    • class extension is implemented using Subclass.prototype = Object.create(Superclass.prototype), not Subclass.prototype = new Superclass(params);; Useful resource
  • Most common mistakes
    • Make sure target = condition ? valueWhenConditionTrue : valueWhenConditionFalse is used instead of condition ? target = valueWhenConditionTrue : target = valueWhenConditionFalse; Conditional (ternary) operator

Please, confirm all items above are positive. Please, ask a question if anything above requires clarification.

A Tiny JS World -- OOP exercise check list

A self-check list. Relates to A Tiny JS World OOP exercise.

Check-list

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 no need to store species property

ES6 classes cheat-sheet

Please, confirm all items above are positive. Please, ask a question if anything above requires clarification.

// Most common initial code example
const man = {
species: 'human',
name: 'Jack',
gender: 'male',
legs: 2,
hands: 2,
say: 'Argh!',
friends: ['Jane', 'Toby']
};
const woman = {
species: 'human',
name: 'Jane',
gender: 'female',
legs: 2,
hands: 2,
say: 'What a beautiful day!',
friends: ['Jack', 'Kitty']
};
const dog = {
species: 'dog',
name: 'Toby',
gender: 'male',
legs: 4,
hands: 0,
say: 'woof!',
friends: 'Jack'
};
const cat = {
species: 'cat',
name: 'Kitty',
gender: 'female',
legs: 4,
hands: 0,
say: 'meow!',
friends: 'Jane'
};
print(man.species + '; ' + man.name + '; ' + man.gender + '; ' + man.legs + '; ' + man.hands + '; ' + man.say);
print(`species: ${woman.species}; name: ${woman.name}; gender: ${woman.gender}; legs: ${woman.legs}; hands: ${woman.hands}; say: ${woman.say};`
+ woman.fiends);
print(dog.species + '; ' + dog.name + '; ' + dog.gender + '; ' + dog.legs + '; ' + dog.hands + '; ' + dog.say);
print(cat.species + '; ' + cat.name + '; ' + cat.gender + '; ' + cat.legs + '; ' + cat.hands + '; ' + cat.say);
// =======
/*
consts -- ensures constant strings and other literals are consistent; IDE suggests const, not literal
toStr with print inside -- breaks Single Responsibility / Separation of Concerns principle
toStr -- separate string conversion and media output
toStr -- map/join; issues with Object.*
.toStr: say => saying -- naming conventions
friends[''] => friends[{}] -- we want friends, not just arbitrary names
.getFriends -- extract names from listed objects
.addFriend -- bonus: a method with mutual addition
world = {} -- bonus: an object representing world and comprising inhabitants + output method
*/
// ===========
let objToString = function(obj, delim = ';') {
let result = '';
for (key in obj) {
result += obj[key];
result += delim;
}
return result;
}
const toString = function(inhabitant, delimiter = ';') {
return [
'species',
'name',
'gender',
'legs',
'hands',
'saying',
'friends'
]
.map(key => inhabitant[key])
.join(delimiter);
}
[man, woman, dog, cat].forEach(inhabitant => print(toString(inhabitant)));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment