On 13 June 2013 18:38, David Harkness <david.h@xxxxxxxxxxxxxxxxx> wrote: > Hi Richard, > > On Thu, Jun 13, 2013 at 10:16 AM, Richard Quadling <rquadling@xxxxxxxxx>wrote: > >> I'm building a class which needs to have certain methods called by the >> subclass, but the subclass can extend but not obscure/override the >> behaviour. >> > > This is the Template Method pattern, though in this case you could use a > Strategy where the specific authentication implementation is in a separate > class that gets injected into the Auth class. As for your example there a a > few things I would change. > > * The template method that the subclass must implement should not be > declared by an interface. Interfaces are for declaring public contracts. > You can simply declare an abstract, protected method in Auth. This is the > contract that every subclass must fulfill. > > * I would avoid reference variables as you've indicated. If you don't want > to build a data-holder class yet, simply return an array for now. While you > cannot enforce the return type at parse time, they should be verified with > unit tests. Unit tests are critical with dynamic languages like PHP and > Python since runtime is the only way to verify behavior. > > Otherwise, your example is spot on, though the name AuthRequestMade > implies the request has already been made yet I think from your description > that this method should *make* the actual request. Here's how I would > write it with the above in place. > > class Auth { > public function MakeAuthRequest() { > // before > $this->MakeAuthRequestImpl(); // Adding "Impl" suffix is a > common convention > // after > } > > /** > * Make the actual authentication request. > * > * @return array Must contain keys "state" and "message" to hold > the result > */ > protected abstract function MakeAuthRequestImpl(); > } > > Peace, > David > > Excellent advice. I will be making an extendable data holder class. I'm going to do the sort of thing Zend_Db does for the adapter/rowset/row classes, allowing an extended class to supply the corresponding extended adapter/rowset/row classes. Each of the base classes has a job to do, but they can only operate in conjunction with an external provider. Thanks for the pointers. Richard. -- Richard Quadling Twitter : @RQuadling EE : http://e-e.com/M_248814.html Zend : http://bit.ly/9O8vFY