Created
March 26, 2012 01:28
-
-
Save arwagner/2202072 to your computer and use it in GitHub Desktop.
Recumbent bicycles
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Recumbent < Bicycle | |
attr_reader :flag | |
def post_initialize(args) | |
@flat = args[:flag] | |
end | |
def local_spares | |
{flag: flag} | |
end | |
def default_chain | |
'9-speed' | |
end | |
def default_tire_size | |
'28' | |
end | |
end |
Ok, I think I get this now. I like the idea of thinking about what you can see from inside a class. And also the way you describe the "space between objects". You have an excellent way with words!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Imagine that when you stand inside of any class you can't see out, ie, you can only know things about the class you're in. What follows thinks of MountainBikes from this point of view.
Ask yourself, 'What does MountainBike know". In the case above, MountainBIke doesn't explicitly know anything about any object outside of itself. It sends no messages so it doesn't even know that any other objects exist. It's passive; it offers up its own specializations when asked but requires no external context.
The only thing MountainBike needs from it's environment is a Bicycle class to inherit from, but even that dependency is fairly loose. If MountainBike were changed to be a subclass of Object this class would still be useable, exactly as it is, by some other object that wanted to know about MountainBike specializations.
BIcycle contains two things. An algorithm (feeble though it may be) and the template methods (hook methods are just a kind of template method). Bicycle should own (be in sole control of and be the only object that has knowledge of) the algorithm. We want to be able to change this algorithm and have subclasses magically inherit the new behavior. Bicycle sends template methods to invite subclasses to fill in specializations.
In the code above Bicycle and MountainBike are coupled, you are right, but the coupling is very loose. Bicyclish things (ie, subclasses) have an api, an agreed upon way to share their specializations. The BIcycle class uses this api to ask for specializations. This api is that only thing that can change in such a way as to force a change on MountainBike, and it is very stable, so it might never actually change.
The coupling between Bicycle and MountainBike is this close.
Bicycle................................................MountainBike
Contrast this with the previous example that overrode spares and within it, sent super. In that version of the code
MountainBike knew:
In this case
The coupling between Bicycle and MountainBike is this close.
Bicycle......MountainBike
If Bicycle changes the name of the spares method or it's return type, MountainBike (and every other subclass) will be forced to change.
It all boils down to how much an object knows about other objects. In the code above, MountainBike knows very little about Bicycle. If Bicycle is written such that MountainBike has to override spares and send super, it's forced to know a lot more. It is this knowledge that couples the objects and raises risks.