6.0.0-git
2018-12-10
Last Modified 2006-08-16 by Chuck Hagenbuch

Instantiate Application Object Refactoring

This is a refactoring. It is informed by some experience, but is by no means complete.

Intent

Remove coupling with global state to make application reusable in different contexts.

Motivation

  • Allows for subclassing applications, which benefits testing
  • Provides for multiple, differently-configured applications, desirable for virtual hosting environments
  • Aesthetics, ease of understanding

Mechanics

Presuming you are working on an app named "flarg":

  1. If there is a global $flarg variable which is an instance of some kind of driver, rename it to $flarg_driver
  2. In lib/base.php, create a global $flarg which is an instance of Flarg::
  3. For each static method in Flarg::
    1. Find all calls of the method and replace Flarg::method() with $flarg->method(). (Possible exception: if the method is truly static, meaning it will always produce the same output given the same parameters, you might want to keep it static.)
  4. For each global variable ($flarg_driver is used as an example):
    1. Add a getDriver() method to Flarg::
    2. Make getDriver() return the global variable's value
    3. Find references to the global variable, and replace each with a call to $flarg->getDriver()
    4. When all references are replaced, do one of the following:
      1. Move initialization code for the value into the method
      2. Introduce a field, move initialization code into constructor
      3. Introduce a field which defaults to null, move initialization code into getter, but only execute when the field is null (Note, beware of introducing cycles.)

When application class gets too heavy to work with, you can use ExtractClass and/or MoveMethod to split up responsibilities.

Ideally, we will eventually end up with an application object which takes all configuration as constructor parameters, does all of the application's work (probably most via delegation - FacadePattern), but does not contain any UI code. Ideal for use from command-line scripts and unit tests.

TODO

  1. Open discussion from Horde developers
  2. Check for core developer support for this pattern.
  3. When/how to write tests and run tests for this refactoring?
  4. "Motivation" section needs some work.
  5. ...