# $Id: Hollow.txt,v 1.1 2001/08/29 20:07:41 matju Exp $

SEPARATING PROTOCOL AND IMPLEMENTATION

You have a class Hello that does something in particular; it is an
Implementation. That something can be described and documented. You can
build classes that work *like* Hello; those classes all share a common
Protocol. You can create an empty module called HelloP which you
include in all classes that work like that, to *declare* that they work
like that. This means that you can do type-checking on HelloP to verify
than an object is at least "Hello-like". This also means that since your
documentation for Hello also works for all HelloP's, you should attach
that documentation to HelloP instead. (That's right: documenting
an empty module.)

Up to now we have no way of verifying whether a said Hello-like class
*really* works according to HelloP. All we have is documentation. What
you can do is create a mixin, that I call HelloP::Contract, which
you can overlay on top of Hello to make sure that:

	1. it is used properly;
	2. it works properly.

that overlaying is done by module inclusion. that should be done from
the right spot, to ensure it has priority. If you wonder, consult Ruby's
inheritance model.



HOLLOW BASE CLASSES

Simple/Hollow is a pattern I developed to describe a way of splitting a
class, to make it simple to reimplement, while keeping all of the
gadgets. There are two layers:

	1. Simple: few methods, simple to implement
	2. Hollow: any number of methods, simple or not.

The Hollow part relies solely on the Simple part, and the two together
form a whole.



Now here is your construction kit:

protocol FooP
	as described in the reference manual of the original class.
	(e.g. ArrayP corresponds to documentation of Array class)

contract FooP::Contract
	in a perfect world ;-)
	The closest existing thing is Dave Thomas' "Rubicon" test suite.

protocol SimpleFooP
contract SimpleFooP::Contract

	The protocol for which you write your own. The contract helps you
	verify that you did it right.

implementation HollowFoo

	uses your SimpleFoo to provide the whole Foo.
	can also be seen as: Foo minus SimpleFoo, with all it implies.

class AutoFoo

	the stupidest usage of HollowFoo is to make something work
	*exactly* like Foo, using a real Foo under the hood.

	no, that's not true. it's actually quite smart. You start with
	something that looks pretty much like a very slow Foo, but then you
	can augment its functionality more easily than the original Foo.

	track all the modifications. make that observable. add an undo
	queue, add a redo queue. add logging. define your own default
	values, auto-vivify. check types. cascade your containers. ...





=============

notes on SimpleFoo:

policy on return values: if a return value is called "void", it means
that not only it should be nil, but it also should not be assumed to be
anything by the caller!

notes on HollowFoo:

if #dup cannot be called meaningfully, please overload by a raise
TypeError. You could also overload #dup in other ways, but not for now,
because of a quirk.

some HollowFoo's have a #get_default method that can be overloaded.

Every write operation of HollowFoo wraps all its writes into a #modify
block. You can overload #modify to trap all write operations atomically.

