ConstructiCat Logo
CodeBust.
Browse section ▾

Inner-Platform Effect.

The inner-platform effect is building a system so configurable that it becomes a poor replica of the platform it runs on, such as a database inside a database.

The inner-platform effect is the tendency of software architects to create a system so customizable as to become a replica, and often a poor replica, of the software development platform they are using. This is generally inefficient and such systems are often considered to be examples of an anti-pattern.

Examples

Examples are visible in plugin-based software such as some text editors and web browsers which often have developers create plugins that recreate software that would normally run on top of the operating system itself. The Firefox add-on mechanism has been used to develop a number of FTP clients and file browsers, which effectively replicate some of the features of the operating system, albeit on a more restricted platform.

In the database world, developers are sometimes tempted to bypass the RDBMS, for example by storing everything in one big table with three columns labelled entity ID, key, and value. While this entity-attribute-value model enables the developer to break out from the structure imposed by an SQL database, it loses out on all the benefits, since all of the work that could be done efficiently by the RDBMS is forced onto the application instead. Queries become much more convoluted, the indexes and query optimizer can no longer work effectively, and data validity constraints are not enforced. Performance and maintainability can be extremely poor.

A similar temptation exists for XML, where developers sometimes favor generic element names and use attributes to store meaningful information. For example, every element might be named item and have attributes type and value. This practice requires joins across multiple attributes in order to extract meaning. As a result, XPath expressions are more convoluted, evaluation is less efficient, and structural validation provides little benefit.

Another example is the phenomenon of web desktops, where a whole desktop environment—often including a web browser—runs inside a browser (which itself typically runs within the desktop environment provided by the operating system). A desktop within a desktop can be unusually awkward for the user, and hence this is generally only done to run programs that cannot easily be deployed on end user systems, or by hiding the outer desktop away.

Effect

It is normal for software developers to create a library of custom functions that relate to their specific project. The inner-platform effect occurs when this library expands to include general purpose functions that duplicate functionality already available as part of the programming language or platform. Since each of these new functions will generally call a number of the original functions, they tend to be slower, and if poorly coded, less reliable as well.

On the other hand, such functions are often created to present a simpler (and often more portable) abstraction layer on top of lower level services that either have an awkward interface, are too complex, non-portable or insufficiently portable, or simply a poor match for higher level application code.

Appropriate uses

An inner platform can be useful for portability and privilege separation reasons—in other words, so that the same application can run on a wide variety of outer platforms without affecting anything outside a sandbox managed by the inner platform. For example, Sun Microsystems designed the Java platform to meet both of these goals.

Example

Instead of a table per entity, everything goes into one generic entity–attribute–value table, so the application has to rebuild what the database already provides: types, constraints and joins. Even a simple filter needs a self-join and a cast, and nothing stops a customer from having no email or a negative credit limit.

import sqlite3

db = sqlite3.connect(":memory:")
db.execute("CREATE TABLE entity (id INTEGER, attr TEXT, value TEXT)")


def save_customer(cid, name, email, credit_limit):
    db.executemany(
        "INSERT INTO entity VALUES (?, ?, ?)",
        [(cid, "name", name), (cid, "email", email), (cid, "credit_limit", str(credit_limit))],
    )


def customers_over(limit):
    return db.execute(
        "SELECT n.id, n.value FROM entity n "
        "JOIN entity c ON c.id = n.id AND c.attr = 'credit_limit' "
        "WHERE n.attr = 'name' AND CAST(c.value AS REAL) > ?",
        (limit,),
    ).fetchall()

A real schema lets the RDBMS enforce types and constraints, use an index and optimize the query — the application no longer reimplements the platform it runs on.

import sqlite3

db = sqlite3.connect(":memory:")
db.execute(
    "CREATE TABLE customer ("
    " id INTEGER PRIMARY KEY,"
    " name TEXT NOT NULL,"
    " email TEXT NOT NULL UNIQUE,"
    " credit_limit REAL NOT NULL CHECK (credit_limit >= 0))"
)
db.execute("CREATE INDEX customer_credit_limit ON customer (credit_limit)")


def save_customer(cid, name, email, credit_limit):
    db.execute("INSERT INTO customer VALUES (?, ?, ?, ?)", (cid, name, email, credit_limit))


def customers_over(limit):
    return db.execute("SELECT id, name FROM customer WHERE credit_limit > ?", (limit,)).fetchall()

Adapted from the Wikipedia article “Inner-platform effect” (revision 1319593770), available under the CC BY-SA 4.0 license; the text has been edited and examples added.