ArticleS
.
DavidChelimsky
.
DevelopmentTimeDependency
Edit Page:
!title Development Time Dependency When one class cannot be compiled without another, we call that a Compile Time Dependency. When an object uses another in a running system, we call that a Runtime Dependency. I was looking for a way to explain the benefits of respecting the Law of Demeter, and ran into a snag because doing so does not necessarily reduce Compile Time or even Runtime dependencies. Take for example the following: !img http://butunclebob.com/files/david/dev_time_dependency/board_game_1.jpg To get and set pieces on the board, the client code looks like this: {{{board.getSquareAt(0,0).setPiece(piece); board.getSquareAt(0,0).getPiece();}}} Client depends on Square even though Client is only interested in the Board and Pieces. That dependency is a violation of the Law of Demeter, often manifested in the form of message chains like those above. In order to address that violation, you might move to a structure like this... !img http://butunclebob.com/files/david/dev_time_dependency/board_game_2.jpg ...which allows for client code like this: {{{board.setPiece(piece, 0, 0); board.getPieceAt(0,0);}}} This does clean up the code in Client, but it doesn't really reduce any Compile Time or Runtime Dependencies. Compile Time Dependencies are transitive. Because Client depends on Board and Board depends on Square, Client still depends on Square even though there is no direct reference to Square in Client. Similarly, even though Client never uses Square directly, we still need on at run time in order to exercise these operations. It also costs us an additional method on Board. So what benefit are we reaping by doing this? There's an added method and no reduction in compile time or runtime dependencies. Well, the benefit is that we are now free to change the internal structure of Board without having to change any of the code in Client. We can store Squares in Rows and Columns, or even get rid of them entirely, and the changes would not ripple out to our Client. Sure we have to recompile Client, but we live in a day and age in which we encourage recompiling on every commit to our source repository! So unless you're dealing with a tangled mess o' legacy, that's probably not a big problem. I think we need a name for this other kind of dependency. The one that gets reduced when we remove message chains. The one that is not revealed at compile time or run time, but rather when making changes to the software. I'd like to call it "Development Time Dependency". What do YOU think? ----!commentForm !* Tue, 1 Aug 2006 05:52:44, Sagy Rozman, A violation of DIP? Isn't this just a classic case of DIP violation? if Square was an interface, Board would not depend on it's implementation and therefore Client would not depend on it either. *! !* Tue, 1 Aug 2006 09:01:10, ${chelimsky}, re: A violation of DIP? Sure there is a DIP violation, but that might be OK in this case. You wouldn't stick an interface on top of String, right? So somewhere between String and a facade there lies a threshold above which you introduce interfaces and below which you do not. At this point we don't have enough context to make an informed choice vis a vis the Square. And really, this is just an example. So for the purposes of the example, let's assume that the right decision is to keep Square concrete. *! !* Thu, 3 Aug 2006 10:20:39, John Wilkinson, I agree with what you are saying but isn’t this what people generally mean by a dependency, i.e. a change to one module causes a change to one or more other modules. PS. I’ve spotted the deliberate mistake in the second UML diagram. *! !* Thu, 3 Aug 2006 12:59:27, ${chelimsky}, definition of dependency John - I think you are right, that people generally mean Development Time Dependency when talking about dependencies, but the more technical definitions that I am familiar with are more about what the computer sees (Compile Time and Runtime) than what people see. PS. There was no deliberate mistake. I see that the input to setPiece is missing, which I will fix, but that was an honest mistake - what are you seeing that I might be missing? *! !* Fri, 4 Aug 2006 02:09:15, John Wilkinson, Shouldn't Board::!-GetPiece-! return a Piece not a Square. *! !* Fri, 4 Aug 2006 08:01:55, ${chelimsky}, Thanks John - Board::!-GetPiece-! now returns a Piece. Cheers. *! !* Fri, 4 Aug 2006 09:42:58, Trond Arve Wasskog, Domain Dependency I would suggest Domain Dependecy or Object Model Dependency. *! !* Fri, 4 Aug 2006 10:56:44, ${chelimsky}, re: Domain Dependency "Domain Dependency" and "Object Model Dependency" are both good ideas, though I like the double meaning of Development Time (i.e. implying that it happens during development time, and abuse of it sucks up development time). I'm happy to let go of Development Time Dependency, but Domain seems too broad and Object Model seems too granular and too easily confused with Compile Time. There's something in the middle. Bring on the ideas! *! !* Sun, 13 Aug 2006 20:46:19, Mark Brackett, Implementation Dependency Your argument is really one of implementation dependency. By arguing that Client doesn't need to know that Board uses Square to organize Pieces, you're really just saying that Board shouldn't be exposing Square. Your argument about refactoring Board later reinforces that. *!
Hints:
Use alt+s (Windows) or control+s (Mac OS X) to save your changes. Or, tab from the text area to the "Save" button!
Grab the lower-right corner of the text area to increase its size (works with some browsers).