DEV Community

Discussion on: What's the deal with downing PHP development?

alchermd profile image
John Alcher

Interesting. What scenario would you say a developer might want a prototype model over plain-old OOP?

Thread Thread
dmfay profile image
Dian Fay

Many! Composability is a really powerful technique with a host of applications, and it's much, much easier to accomplish with a prototypal model than it is with classic object orientation.

For a concrete example, I maintain a data access library which introspects a database to build an API over it. A database contains tables, views, functions, and schemas. Tables can be read and written; views can be read; functions can be executed; schemas act as namespaces and contain objects of the other three types. The first three object types have certain attributes in common: a name, a schema they belong to, et cetera.

A classic OO approach would be to create an Entity class which centralizes the common attributes, and have each of Table, View, and Function inherit Entity. A method may act on any "real" database object (omitting schemas, which just contain things) as long as it takes an Entity and either only references Entity properties and methods or performs the appropriate checks and casts.

Then you get into the "building an API" stage. The goal is to return a Database tree that lets you issue a statement like db.things.stuff.find(), where things is a schema and stuff a table, determining the query target by navigating the tree. This isn't so hard: simply ensure that you create namespaces and attach Entities at the appropriate path.

However: the default schema is unnamespaced, so what happens when it also contains a table named things? What do you do now? Classic OOP has no easy answer. Do you create classes for TableWhichIsAlsoASchema and TableWhichIsAlsoAFunction and all the other possible collisions? Do you cross-contaminate your three base classes and gate alternative logic behind introspection checks? Good luck!

With prototypal inheritance, resolving these collisions isn't just possible, it's easy: just keep applying prototypes as they come in! If you already have a Table at a path which turns out to resolve to a schema as well, you can just hang the new stuff on the existing object. The only collisions that can't be resolved are due to (small-f) functions being overridden or becoming ambiguous, not due to simple pathing.