Memra

Interfaces as factories; nesting interfaces

Return objects through an interface so callers stay decoupled from concrete classes.

Returning a contract, not a class

Because callers can work entirely through an interface, a method can return an interface type while privately choosing which concrete class to build. This is the Factory pattern: a single method maps a request to the right implementation, and the caller never sees a new ConcreteThing().

The Greenhouse recovery code needs the appropriate fix for an error code, but it should not be peppered with if (code == 1) new FixWindow() everywhere. Centralise that decision in a factory that hands back a Fixable:

Worked example — Fixable getFixable(int code)

public Fixable getFixable(int errorcode) {
  switch (errorcode) {
    case 1:  return new FixWindow();
    case 2:  return new FixPower();
    default: return new FixNothing();
  }
}

The return type is the interface Fixable, so the caller writes only:

Fixable f = getFixable(errorcode);
f.fix();
f.log();

Now adding a new fault recovery is a one-line case plus a new class — every call site that uses getFixable(...) keeps working unchanged. The concrete classes (FixWindow, FixPower, …) are an implementation detail hidden behind the factory.

Nesting interfaces

An interface can be declared inside a class or another interface to scope it to its owner. A nested interface is implicitly static and is referred to through its outer type:

class Controls {
  public interface Service {     // nested interface
    void perform();
  }
}
// elsewhere:
class LightService implements Controls.Service {
  public void perform() { }
}

Nesting keeps a small contract bundled with the class that defines it (here, Controls.Service), which is exactly how the project groups its control-related contracts.

NORMAL ~/memra/learn/comp-308/interfaces-as-factories utf-8 LF