Stewardesses serving passengers I did an exercise (open-ended - without an answer) from a JavaScript book (chapter about functions).


  Given array of passengers of a flight with their names and ticket types and one need to emulate stewardesses asking passengers for service during the flight depending on their ticket type (first class or coach)  (stewardesses provide all the passengers with one same kind of a service at a time). It's required to make code as extensible and flexible (so you can add ticket types (economy, business), drink types etc. and even new kinds of service like dinners or smth.) as possible.


I want to see suggestions on how I can make this code more flexible, extensible and in a more functional style. Or maybe see any critiques as to why this code is bad, with suggestions of a more correct way of doing the exercise.

var passengers = [{
  name: "Jane Doloop",
  ticket: "firstclass"
}, {
  name: "Dr. Evel",
  ticket: "firstclass"
}, {
  name: "Sue Property",
  ticket: "firstclass"
}, {
  name: "John Funcall",
  ticket: "coach"    
}];

function formServices(passengers) {
  for (var i = 0; i &lt; passengers.length; i++) {
    createOrders(passengers[i]);
  }
}

function serveCustomers(passengers) {
  formServices(passengers);
  serveIteration(passengers, "orderDrink");
  console.log("------");
  serveIteration(passengers, "orderDrink");
  console.log("------");
  serveIteration(passengers, "orderMovie");
  console.log("------");
  serveIteration(passengers, "orderDrink");
  console.log("------");
  serveIteration(passengers, "throwGarbage");
}

function createOrders(passenger) {
    if (passenger.ticket === "firstclass") {
      passenger.orderDrink = function() {
        console.log(passenger.name + ", woud you like a cocktail or wine?");
      };
      passenger.orderMovie = function() {
        console.log(passenger.name + ", woud you like a TV-show or movie?");
      };
    } else {
      passenger.orderDrink = function() {
        console.log(passenger.name + ", your choice is cola or water.");
      };
      passenger.orderMovie = function() {
        console.log(passenger.name + ", movies are not available for you.");
      };
    }

    passenger.throwGarbage = function() {
      console.log(passenger.name + ", it's time to throw garbage");
    };
}

function serveIteration(passengers, serviceProperty) {
  switch (serviceProperty) {
    case "orderDrink":
      for (var i = 0; i &lt; passengers.length; i++) {
        passengers[i].orderDrink();
      }
      break;
    case "orderMovie":
      for (i = 0; i &lt; passengers.length; i++) {
        passengers[i].orderMovie();
      }
      break;
    case "throwGarbage":
      for (i = 0; i &lt; passengers.length; i++) {
        passengers[i].throwGarbage();
      }
      break;
    default:
      console.log("No such service");
  }
}

serveCustomers(passengers);


The output is:




Jane Doloop, woud you like a cocktail or wine?
Dr. Evel, woud you like a cocktail or wine?
Sue Property, woud you like a cocktail or wine?
John Funcall, your choice is cola or water.
------
Jane Doloop, woud you like a cocktail or wine?
Dr. Evel, woud you like a cocktail or wine?
Sue Property, woud you like a cocktail or wine?
John Funcall, your choice is cola or water.
------
Jane Doloop, woud you like a TV-show or movie?
Dr. Evel, woud you like a TV-show or movie?
Sue Property, woud you like a TV-show or movie?
John Funcall, movies are not available for you.
------
Jane Doloop, woud you like a cocktail or wine?
Dr. Evel, woud you like a cocktail or wine?
Sue Property, woud you like a cocktail or wine?
John Funcall, your choice is cola or water.
------
Jane Doloop, it's time to throw garbage
Dr. Evel, it's time to throw garbage
Sue Property, it's time to throw garbage
John Funcall, it's time to throw garbage
Correctness

In createOrders(passenger) you use an if-else statement. This has a major issue when you misspell a ticket name.

Extensibility

I would say that your code has 2 major issues that prevent it from being easily extendible:


Ticket names are arbitrary strings. They are easily mistyped, and would lead to all kinds of funky business. While javascript does not have something like enum, you could create your own and use something like this:

var TicketTypeEnum = {
  "COUCH" : "couch",
  "FIRSTCLASS" : "firstclass"
};
if( Object.freeze ) {
  Object.freeze( TicketTypeEnum );
}


This has two benefits. First of all it is immediately clear which ticket types are available. The second benefit is that if you now try to set it to something mistyped, it is undefined. If you would implement something like addPassenger(..) this is easily enough detected.

Similarly, you can have an Object of possible services.
createOrders(..) will become a giant mess when adding more services or more ticket types. There are various ways in which you could improve that:


It is possible to create an Object containing Objects, then retrieve services[ticketType][serviceType] if you want to get the handler for a service given a particular ticket type.
You could have just an Object of services, and assign functions to each of them. Each of these functions switch for ticket type if needed.
You can have a Service class which you can feed a ticket type when called. The difference here being that you can have more advanced logic inside this "Service" abstraction.


I personally would prefer the first option or the third option. In both cases you probably should create a function that adds handlers per ticket type, or adds a Service object to your collection of possible services. You can then easily check if a service or ticket type is forgotten when calling that function, and output an error before you try to serve your customers. In other words: It breaks when setting up the program instead of after an unknown amount of runs.


Note: Your stewards and stewardesses are angry at you for not being called cabin crew. Then again, they are virtual, so you probably don't have to care about this.