On Sat, Sep 6, 2008 at 9:57 PM, David Chelimsky <[EMAIL PROTECTED]> wrote: > On Sat, Sep 6, 2008 at 4:48 PM, Nick Hoffman <[EMAIL PROTECTED]> wrote: >> On 2008-09-06, at 15:58, David Chelimsky wrote: >>> >>> Well, without changing the underlying semantics, you can clean up the >>> syntax a bit like this: >>> >>> mock_property1 = stub('property', :address => '400 Bloor Street', >>> :latitude => 12.34, :longitude => 56.78) >>> >>> Of course, that doesn't address your question :) >> >> That makes the specs much easier to read! >> >>> Here's another thought that doesn't answer your question - this line >>> in the code: >>> >>> add_marker p.address, p.latitude, p.longitude, >>> generate_marker_contents(p) >>> >>> is resulting in a situation where you have to do a lot of setup in >>> order to isolate the object under test. The line exhibits the Feature >>> Envy Code Smell, which is the odor emitted by one object depending on >>> another object's data. >> >> RentalMap#add_properties does have feature envy. However... >> >>> If I were coding by example, I'd probably start w/ a simple example like >>> this: >>> >>> describe '#add_properties' do >>> it 'should add one property to the map' do >>> map = RentalMap.new @map_name, @latitude, @longitude >>> mock_property = mock 'property' >>> Property.stub!(:find).and_return [mock_property] >>> >>> mock_property.should_receive(:add_marker_to).with(map) >>> >>> map.add_properties >>> end >>> end >>> >>> This defines how I'd like to be able to "talk" to the Property, and >>> results in an implementation like this: >>> >>> p.add_marker_to(map) >>> >>> Now all the additional behaviour is pushed to the Property, for which >>> you can write code examples with the details of its own data rather >>> than having to stub so much of its data for use in the current >>> example. >> >> I believe that the process of adding a marker (IE: Property) to a RentalMap >> should be a feature of the RentalMap model, rather than the Property model. >> From a Property's perspective, a property has nothing to do (IE: no >> interactions) with RentalMaps. From a RentalMap's perspective, a RentalMap >> has lots to do with Properties, because it needs to ask a Property for >> information so that it can add a marker to itself. > > Sounds like you're letting adherence to a mental model overrule what > the code is actually telling you. The code is telling you that the > model is flawed. I'd listen to it. > > Personally, I don't see any conceptual, philosophical problem with a > Property knowing it is on a Map - doesn't have to be a RentalMap, just > a Map. If you can accept that, then you can take the next step and do > a little double dispatch: > > class Property > def add_to(map) > map.add_marker address, latitude, longitude, contents > end > end
Or, better yet: class Property def add_marker_to(map) map.add_marker Marker.new(address, latitude, longitude, contents) end end That reduces the surface contact between the Property and the Map even more. > > The map could be RentalMap, a ListingMap, an EventsMap, etc, etc. > >> >> To make an analogy, do I put on a shirt, or does a shirt put itself on me? > > You are human. Programs are not. Seeing as a Person object and a Shirt > object can be programmed to behave as we wish, I'd suggest that there > might be fewer dependencies and a simpler series of instructions if > the shirt object put itself on the person object. > > While Objects can sometimes do a decent job of modeling the real > world, that's not why they exist. They were born to make software more > ... soft. Guidelines like Law of Demeter, Tell Don't Ask and DRY > didn't come out of nowhere. None of them are 100% applicable all the > time, but when they are violated, their resulting cries should at > least be a red flag. > > FWIW, > David > >> >> Thanks again for your opinions, David! >> Nick >> _______________________________________________ >> rspec-users mailing list >> rspec-users@rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users >> > _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users