title: 'Register' extra methods with a base class with automatic discovery
body: <p>I'm working on a base class which will check for a set of common methods and do something with each one if it exists:</p>
  
  <pre><code>class BaseClass {
  
    get router() {
      if (!this._router) {
        this._register();
      }
      return this._router;
    }
  
    _register() {
      this._router = new Router()
      if (this.list) {
        this._router.use('/', this.list);
      }      
  
      if (this.detail) {
        this._router.use('/:id', this.detail);
      }
      // etc...
  
     }
  
  }
  </code></pre>
  
  <p>I want to allow users of the class to 'register' their own custom methods aswell. 
  As a first pass, I thought to have them override <code>_register</code>:</p>
  
  <pre><code>class MyClass extends BaseClass {      
    list() {...}
  
    _register() {
      super._register();
      this._router.use('/custom/route', this.customMethod);
    } 
  }
  </code></pre>
  
  <p>Hmmm... thats not great as they have to add the <code>super</code> boilerplate and know about <code>_router</code>.</p>
  
  <p>My next best was to add a method to register extras in the base class:</p>
  
  <pre><code>addExtraRoute(route, method) {
    this._extras[route] = method
  }
  </code></pre>
  
  <p>Then to loop over it in the _register method, adding them all.
  this is slightly better as the user can then just 'register' their methods in the constructor:</p>
  
  <pre><code>class MyClass extends BaseClass {
      constructor() {
        super();
        this.addExtraRoute('/custom/route', this.customMethod);
      }
  }
  </code></pre>
  
  <p>still not great:</p>
  
  <ul>
  <li>No locality between defining the method and registering, which is a bit harder to read</li>
  <li>Still the super boilerplate &amp; need to make sure we know about any arguments to be passed to the base class. </li>
  </ul>
  
  <p>What is a better design?</p>