Analogy time.

Software and system design are difficult to comprehend without a framework. Analogies can help clarify things. So, in order to help, lets analogize your application as a warehouse and features are boxes that business wants to put in your warehouse. As a software developer, your job is to help manage the warehouse.

Now, as a new warehouse manager, you start with an empty warehouse/application. You want to get to market as soon as possible. Unfortunately, you have never seen or heard of a warehouse before, so you pick up a box, walk two feet in the door to the warehouse, and place it down. You get another box, walk two feet in the door, and place it down. Another box, you put it on top of the first two.

Soon you are creating pyramids of boxes. Mazes of boxes. You feel like a genius when you put a new box in. Your boss is amazed and makes you chief warehouse executive.

But, soon you cannot keep up with the demand. Some boxes are buried in the wrong places. Some boxes are starting to mold. The owners have hire a small army of assistant box management people but the maze of boxes is incomprehensible to anyone but you. The warehouse is losing money hand over fist and eventually is sold for pennies on the dollar to StoringSpoons who fires everyone and collects the money as the warehouse crumbles into dust.

How can you, the fresh and intrepid warehouse manager, stop this grim future? Warehouses have learned how to scale to massive sizes and with a few practiced tools in your belt you can too.

Extension

This is kind of like having a roller line.

┌─────────┐                  ┌───────────┐   
  │         │                  │           │   
  │         │    ┌────────┐    │           │    
  │         │    │        │    │           │   
  └─────────┘    └────────┘    └───────────┘   
ooooooooooooooooooooooooooooooooooooooooooooooo

New boxes are added to the front of the line and all the existing boxes roll down the line. The line is "open to extension". If you want to remove a box, you pull it off the line and that does not affect adding more boxes to the line.

Example of extension: Lists are lines of items. If you can reduce your concept to a list of things, it is probably extension.

Encapsulation

┌─────────┐  ┌─────────┐
  │ ┌┐┌────┐│  │         │
  │ └┘│    ││=>│         │
  │   └────┘│  │         │
  └─────────┘  └─────────┘

Boxing. You need to send out manuals, dials, motors, cases, and basins to the customers. You could have them all individually and have 5 work items, or you encapsulate them in a box labeled "washing machine kit" and have one item.

Example: Files. Files are really just thousands, millions, or billions of bits in memory, but if you encapsulate those bits into a "file" with a set of functions to perform tasks on those bits, then it becomes easier to think about than needing to handle those bits yourself.

Composition

A type of encapsulation and alternative to inheritance. The washing machine kit box "has a" dial. The dial is put into the box.

Example: Directories "have many" files as a way to organize and think about the files. One can move all the files in a directory with one command instead of many commands. Just like one can move the contents of a box by moving the box.

Inheritance

A way to group objects by shared attributes and functionality. You as the warehouse manager might need to store large things and small things so you make two bins for empty boxes. "Big", and "Small". As time goes on you may subdivide this further, but do note that you probably need to throw away the old groupings to prevent confusion as the groupings are conceptually linked.

Example: Executable files are a subtype of files. They also are a collection of bits and can be manipulated the same as all files.

Dependency Injection

You hire your first employee, Devin. You start writing down what needs to happen at the warehouse. "Devin preps 30 boxes." "Devin fills 30 boxes." etc. One day, Devin quits and you hire Billy. Oops, now you need to change everything. Instead, you could have written "Box prepper preps 30 boxes" and "box filler fills 30 boxes" then given Devin the titles of Box prepper and Box filler.

Example of dependency injection: arguments to your executable are you injecting dependencies. You don't write a custom file mover for every file in the system. You pass the file to the mv function.

Conclusion

These are all tools that need practice and exercise. No one builds a perfect warehouse the first time around, much as no one builds a perfect application. The goal is that when you discover why the application is wrong, that you can quickly fix the problem. This might be more of a series as I think of more patterns that can be like a warehouse.