mediawiki-extensions-Popups/docs/adr/0006-factories.md
Thiemo Kreuz 7ef925fb97 Prefer YYYY-MM-DD ISO dates in all documentation
It is probably not that critical to understand if "09/11/2016" refers
to September 11th or November 9th. I still think it's worth looking for
a documentation format that is easy to understand by an international
developers community. My personal best practice is to use the ISO format.

Change-Id: Ib209a8a1651970d74f82c188ae4b84d1a4eb534e
2019-01-17 17:11:29 +01:00

3.2 KiB
Raw Permalink Blame History

6. Factories

Date: 2016-11-08

Status

Accepted.

This ADR was accepted implicitly by the (current) primary maintainer of this repository, Sam Smith. The date of this ADR was changed to reflect this.

Context

Given that the majority of the codebase is going to be rewritten, there's a need for a consistent style for building the system anew.

The Reading Web team, historically, has tended towards taking an object oriented approach to building software. However, a typical result of this approach are classes that have many varied concerns, share not specialise  behaviour via inheritance rather than via composition. These issues are evidenced by a lack of unit tests, i.e. the classes become increasingly hard to test and even harder to test in isolation to the point where high-level integration tests are relied on for validation of the design.

Unless attention is paid, these classes have all of their members exposed by default due to a lack of support for visibility modifiers from either the JavaScript language or our (current) tooling. Like other teams, the Reading Web team tends to follow the convention of prefixing private member names with an underscore.

Moreover, while planning the rewrite of the codebase, the decision to use Redux to maintain state was made very early on. A significant part of the codebase will be written in the style that Redux requires: functions that return objects, or factories.

What's needed, then, is a general rule that, when applied, leads the Reading Web team to produce a codebase that's easier to maintain (verify and modify) and is familiar. This rule must also acknowledge that it must be broken now and again.

Decision

  1. Favour factories over classes  however we wish to define them, e.g. with OOjs by default.
  2. Favour classes when the performance benefits of prototypal inheritance far outweigh the benefits of consistency and simplicity.

Consequences

The most obvious consequence of this decision is the easy portability of the codebase: there's no requirement for a framework to help define classes and manage inheritance, e.g. OOjs. Moreover, the new operator in new Foo(), is simply replaced with the createFoo factory function, and the instanceof operator is rendered useless.

The more subtle consequence is that behaviour must be shared via composition since the use of inheritance is strongly discouraged. The most important positive consequence of this is is that the system will be more flexible as it'll be composed of implementations of small interfaces. The most important negative consequence is that more effort will be required when sharing behaviour between parts of the system, which is trivial using inheritance, as attention must be paid when designing these interfaces.

Despite being the negative consequence, requiring more attention to be paid when defining behaviour should make it harder to write and easier to spot components "that have many varied concerns" and, hopefully, result in components that are easier to test.