[rspec-users] Depot app, Demeter's law and troubles cleanly specing

David Chelimsky dchelimsky at gmail.com
Sun Apr 19 14:54:39 EDT 2009

On Sun, Apr 19, 2009 at 11:24 AM, Mark Wilden <mark at mwilden.com> wrote:
> On Sun, Apr 19, 2009 at 3:51 AM, Matt Wynne <matt at mattwynne.net> wrote:
>> @order_presenter.product_titles do |product_title, url|
>>  <%= link_to product_title, url %>
>> end
> The presentation of an order in most apps will be constructed from
> additional columns (e.g., color, size, price, extended price). These
> columns may well be formatted differently depending on the
> circumstance (e.g, printed or on-screen).
> Now, it might be a good idea to put this construction and formatting
> in a helper or presenter outside the view (though it won't be
> TSTTCPW). But anywhere you put it, there will be non-Demeterian code
> that needs to drill down into each order's items', products'
> information (as well as non-product information, such as line-item
> discount). If the underlying model changes, this code will have to
> change - you can't avoid it.

The motivation behind demeter is to localize change. The cost is
method bloat and potential lack of cohesion on a model. Having a
single presenter object act as the one and only place that will change
besides the model itself is a good compromise between complete
localization of change in the model and method bloat on the model.

A very interesting approach to all this was presented by Allen Holub
in his talk boldly entitled "Everything You Know is Wrong," in which
he tears apart common misunderstandings about OO.


The idea, as I understand it (but, according to his basic premise, I'm
probably wrong) is to have data importers and exporters on domain
objects in order to minimize getters and setters. These collaborators
are going to take the hit of changes to the model objects, but *only*
they will if you follow this approach. In the example we're talking
about here, we'd end up with code like this in the controller:

def some_view
  @order = find_order.export_to(OrderPresenter.new)

OrderPresenter would have a bunch of setters on it, which *the order,
which knows its own data structure* would call. Now you don't need a
bunch of getter methods on order.

Similarly, data importers would have a bunch of getters on them, and
you would use them to import data into an order like this:

order_form = OrderForm.new(params[:order])
order = Order.create_from(order_form)

Obviously, ActiveRecord provides the getters and setters anyway, but
the real violator of encapsulation is the consumer, not the vendor.
Just because a flasher opens his coat doesn't mean that reaching
inside is a good idea ;)


> ///ark
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

More information about the rspec-users mailing list