Skip to content

Instantly share code, notes, and snippets.

@mul14

mul14/00.md Secret

Last active August 7, 2020 22:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mul14/e723a9bb61719c7dd4d63c5e3972059c to your computer and use it in GitHub Desktop.
Save mul14/e723a9bb61719c7dd4d63c5e3972059c to your computer and use it in GitHub Desktop.
Object Oriented Programming Challenge

OOP Challenge

Short URL: https://bit.ly/oop-challenge

Basic Instructions

Add your answers should follows this conventions:

  • File name must use number of question, but with .js extension in src folder. For example, if the question file name is 01.md, then your answer must be 01.js.
  • The answer should have tests.

Overview

In this challenge you have freedom to design the class. I provide the example of code, but you could create your own implementation. For example I want to create User class. That class should be able create User object with username, name, email, and password.

Approach

Here is my first approach.

class User {
  constructor(username, name, email, password) {
    this.username = username
    this.name = name
    this.email = email
    this.password = password
  }
}

// Usage
const user = new User('mul14', 'Mulia', 'email@example.com', 'S3cR3T')

My second approach.

class User {
  setUsername(username) {
    this.username = username
  }

  setName(name) {
    this.name = name
  }

  setEmail(email) {
    this.email = email
  }

  setPassword(password) {
    this.password = password
  }
}

// Usage
const user = new User()
user.setUsername('mul14')
user.setName('Mulia')
user.setEmail('email@example.com')
user.setPassword('S3cR3T')

The both approaches are acceptable. When design a class you should think it first, "Is this a good way to design a class? Is it easy enough for use?".

#1 Hash

Create a Hash class with ability to create hash string, with popular hash algorithm.

Usage example

Hash.md5('secret') // 5ebe2294ecd0e0f08eab7690d2a6ee69

Hash.sha1('secret') // e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4

Hash.sha256('secret') // 2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b

Hash.sha512('secret') // bd2b1aaf7ef4f09be9f52ce2d8d599674d81aa9d6a4421696dc4d93dd0619d682ce56b4d64a9ef097761ced99e0f67265b5f76085e5b0ee7ca4696b2ad6fe2b2

#2 Cipher

Create Cipher class with ability to encrypt/decrypt a string.

Usage example

const message = Cipher.encrypt('Ini tulisan rahasia', 'p4$$w0rd')

console.log(message) // Anyone without password can't read this message

const decryptedMessage = Cipher.decrypt(message, 'p4$$w0rd')

console.log(decryptedMessage) // Ini tulisan rahasia

#3 Log

Create Log class with ability to log text with several levels. The levels based on severity levels in Syslog.

The Log class should be able to produce output to a app.log file, like so

[2018-04-03T12:10:36.100Z] INFO: This is an information about something.
[2018-04-03T13:21:36.201Z] ERROR: We can't divide any numbers by zero.
[2018-04-03T16:45:36.210Z] NOTICE: Someone loves your status.
[2018-04-03T23:40:36.215Z] WARNING: Insufficient funds.
[2018-04-03T23:56:36.215Z] DEBUG: This is debug message.
[2018-04-04T04:54:36.102Z] ALERT: Achtung! Achtung!
[2018-04-04T05:01:36.103Z] CRITICAL: Medic!! We've got critical damages.
[2018-04-04T05:05:36.104Z] EMERGENCY: System hung. Contact system administrator immediately!

It would be great if you could create filter based on level, date, and messages. For example filter by CRITICAL at 2018-04-04.

Don't use any 3rd-party library.

#4 Config class (Adapter Pattern)

Create Config class with CRUD ability to create a configuration. User should be able to change the implementation of config storage by using Adapter Pattern.

Usage example

const config = new Config(new ConfigFileStorage('config.json'))    // Use local file system to store config file.

const configDb = new Config(new ConfigNedb('config.db'))           // Use NeDB.

const connection = {username: 'root', password: '', db: 'config'}

const configMysql = new Config(new ConfigMysql(connection))        // Use MySQL database as config storage.

config.put('site_name', 'Blog')         // Be able to save string.
config.put('maintenance', false)        // Be able to save boolean.
config.put('age', 30)                   // Be able to save number.
config.put('meta', {"description": "lorem ipsum"}) // Be able to save object or array.

config.get('site_name')            // Will return "Blog".

config.put('site_name', 'Perfect Blog')    // Will update the "site_name" with new value.

config.remove('site_name')         // Remove "site_name" key.

config.get('site_name')            // Return null, because "site_name" was deleted.

#5 Http Client

Create HTTP client class with ability to send a request to HTTP server. That class should be able to do some of HTTP verb methods such as GET, POST, PUT, PATCH, DELETE, OPTIONS, and HEAD. The POST, PUT, and PATCH should be able to send data.

The implementation should wraps the native API instead of 3rd-party modules, and must be able to used in NodeJS or web browser (optional).

  • NodeJS should use http.
  • For web browser should use Fetch API or XHR (optional).

Usage example

Http.get('https://httpbin.org/get').then(response => {
  //
})

const data = {
  author_id: 43,
  title: 'Lorem ipsum',
  body: '<p><strong>Lorem ipsum</strong> dolor sit amet</p>',
  created_at: (new Date()).toISOString(),
  tags: ['hello', 'world'],
}

Http.post('https://httpbin.org/post', data).then(response => {
  //
})

#6 Auth

Create Auth class with some abilities ...

Example

Auth.login({username: 'root', password: 'secret'})      // If valid, user will log in.

Auth.validate({username: 'root', password: 'secret'})   // Just verify username and password without log in.

Auth.logout()          // Log out the current logged in user.

Auth.user()            // Get information about current logged in user.

Auth.id()              // Get the User ID.

Auth.check()           // Will returns true if user already logged in.

Auth.guest()           // Will returns true if user not logged in.

Auth.lastLogin()       // Get information when the user last logged in.

#7 Validator

Create Validator class with ability to validate data based on rules.

Usage example

const data = {
  username: 'mul14',
  email: 'email@example.com',
  name: 'Mulia',
  zip: 75324,
  is_admin: true,
  age: 28,
}

const rules = {
  username: 'required|alphanum',
  email: 'required|email',
  name: 'required',
  zip: 'required|numeric',
  is_admin: 'boolean',
  age: 'numeric|min:21',
}

// The message is optional. But user should be able to customize the messages.
const message = {
  required: 'The %s field is required.',              // Message will be "The username field is required."
  age: 'The %s field must a number.',                 // The age field must a number.
}

const validator = new Validator(data, rules, message)

validator.fails()          // If data contain not valid field, will return true.

validator.passes()         // If all data valid, will return true.

validator.errors()         // Show all error fields with error message.

#8 Cart - Method Chaining

Create Cart class with method chaining ability.

Usage example

const cart = new Cart()

// Do some chainings
cart.addItem({ item_id: 1, price: 30000, quantity: 3 })
    .addItem({ item_id: 2, price: 10000 })               // By default quantity is 1
    .addItem({ item_id: 3, price: 5000, quantity: 2 })
    .removeItem({item_id: 2})
    .addItem({ item_id: 4, price: 400, quantity: 6 })
    .addDiscount('50%')

cart.totalItems() // 3

cart.totalQuantity() // 11

cart.totalPrice() // 51200

cart.showAll() // Show all items in cart

cart.checkout() // Store data in a file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment