Search code examples
javascriptoopdesign-patterns

JS OOP - class method calling another class from function


I was curious about JS Design Patterns and decided to try this website, but on the Command Pattern section I got super confused. You can see the explanation in the link but for this post's sake I have provided a code snippet below.

class OrderManager {
    constructor() {
        this.orders = [];
    }

    execute(command, ...args) {
        return command.execute2(this.orders, ...args);
    }
}
  
class Command {
    constructor(executee) {
        this.execute2 = executee;
    }
}

function PlaceOrderCommand(order, id) {
    return new Command(orders => {
        orders.push(id);
        console.log(`You have successfully ordered ${order} (${id})`);
    });
}

const manager = new OrderManager();

manager.execute(new PlaceOrderCommand("Pad Thai", "1234"));

I am super confused, I thought I was good at JS but apparently I am not..

The questions in line are:

  1. How can you call the manager.execute with only one argument, when in the definition there are two?!

  2. Why call the function with new keyword like new PlaceOrderCommand("Pad Thai", "1234")

  3. How does execute2 call the arrow function when it is just assigned in the constructor?!

all these things are super confusing and seem like magic to me..


Solution

  • tldr - finding reliable information on the internet is hard

    I am super confused

    I would be, if I weren't aware that rampant terrible information is everywhere

    Answers:

    1. manager.execute only requires a single argument - a command instance (or, alternatively an object that has an execute2 method that accepts an array of orders). I imagine the people who created this example were probably thinking: "In the future, I could have a command that accepts more parameters and I could make that happen by just passing ...args"

    2. Because the authors of this website don't know what they're doing

    3. execute2 is the arrow function. So the manager just calls the execute2 method on the object that was passed into it with a single argument that is the orders array held in the OrderManager instance.

    EDIT:

    This keeps getting better, take a look at the CancelOrderCommand when implemented using the "command pattern". It reassigns a local variable and pretends it does the same thing as when the command pattern wasn't being used.

      cancelOrder(id) {
        // modifies instance variable 👍
        this.orders = this.orders.filter(order => order.id !== id)
        return `You have canceled your order ${id}`
      }
    
    
    ...
    
    function CancelOrderCommand(id) {
      return new Command((orders) => {
        // reassign local variable - does nothing 🤷
        orders = orders.filter((order) => order.id !== id);
        return `You have canceled your order ${id}`;
      });
    }
    

    This website should be blacklisted.