[Nitro] Encapsulation (was Re: xhtml builder in model?)

TRANS transfire at gmail.com
Wed Sep 7 10:42:49 EDT 2005


On 9/7/05, Ysabel <deb at ysabel.org> wrote:
> The former violates encapsulation (Writer knows that model has properties X
> and Y, and if you change the general shape of Model, you'll have to change
> Writer as well).  The latter does not, presuming that do_this() and
> do_that() are, in fact, intended as part of Writer's public interface and
> thus less likely to change.
> 
> To make it more concrete, since do_this and do_that don't tell you much,
> compare:
> 
>   class Model
>     attr_accessor :name
>     attr_accessor :color
> 
>     def self.color_choices
>       [ "Red", "Green", "Blue" ]
>     end
>   end
> 
>   class Writer
>     def render_text_input(value)
>       ...
>     end
>     def render_choice(value)
>       ...
>     end
>     def render(model)
>       render_text_input(model.name)
>       render_choice(model.color, Model.color_choices)
>     end
>   end
> 
> to this:
> 
>   class Writer
>     def render_text_input(value)
>       ...
>     end
>     def render_choice(value)
>       ...
>     end
>   end
> 
>   class Model
>     def render(writer)
>       writer.render_text_input(@name)
>       writer.render_choice(@color, ["Red", "Green", "Blue"])
>     end
>   end
> 
> When looking at those two cases, ask the question about which objects know
> what things.  Encapsulation is all about keeping knowledge on a
> need-to-know basis.  Yes, the code for these two isn't all that different,
> but in the first case Writer knows about Model's implementation -- it knows
> that Models have names and colors and that names should be rendered as text
> and colors should be rendered as choices, and it has to know how to figure
> out what the valid choices for a color are; in the second only Model knows
> how it's implemented (and the details aren't even exposed).  In the first,
> Model doesn't know anything at all about Writer; in the second, Model knows
> that Writer allows one to render a text input and a choice, but nothing
> more.
> 
> This is, of course, based on the assumption that Writer has a well-defined
> interface and it's most likely Model that you're planning on tweaking as
> you work through the problem.  If Writer is not well-defined, then both of
> the original examples violate encapsulation by messing with each other's
> implementation details...and you really need to figure out some sort of
> stable interface!  Or at least a metastable one...note also that I am using
> interface in a generic sense here rather than in some sort of strict-typing
> capital-I-Interface sense.
> 
> This is not unique to Ruby somehow; it's a standard problem in every
> language I've ever worked in, though the idiomatic solution may change from
> language to language.  Reducing coupling and increasing coherency (and
> defining which is which) is an issue even in non-OO languages like, oh, C
> or assembly.  :)

Nicely stated. Thanks. I think you've mad it clear that the issue is
really one of coupling, and how to minimize the headaches invloved
with that. Often you are write it is the model that is more likely to
change. But it depends --what if you've had the model for ages and now
need a new format?

What about...

  module IFace_Writer_Model

    def render_text_input( writer, model )
       ...
    end

    def render_choice( writer, model )
      ...
    end

  end

Then you can teach both the writer and the model to call on the above
--and it works either way.

Of course, in the end probably the keenest thing to do is learn about
dependency injection. I've gone over it myself and basically "get it"
(or I should say "have gotten it") but have never put it to use, so
don't have enough experience to say.

T.




More information about the Nitro-general mailing list