Hi all
I'm reading through Eric Evans' awesome work, Domain-Driven Design. However, I can't help feeling that the 'layers' model is contrived. To expand on that statement, it seems as if it tries to shoe-horn various concepts into a specific, neat model, that of layers talking to each other. It seems to me that the layers model is too simplified to actually capture the way that (good) software works.
To expand further: Evans says:
"Partition a complex program into layers. Develop a design within each layer that is cohesive and that depends only on the layers below. Follow standard architectural patterns to provide loose coupling to the layers above."
Maybe I'm misunderstanding what 'depends' means, but as far as I can see, it can either mean a) Class X (in the UI for example) has a reference to a concrete class Y (in the main application) or b) Class X has a reference to a class Y-ish object providing class Y-ish services (ie a reference held as an interface).
If it means (a), then this is clearly a bad thing, since it defeats re-using the UI as a front-end to some other application that provides Y-ish functionality. But if it means (b), then how is the UI any more dependent on the application, than the application is dependent on the UI? Both are decoupled from each other as much as they can be while still talking to each other.
Evans' layer model of dependencies going one way seems too neat.
First, isn't it more accurate to say that each area of the design provides a module that is pretty much an island to itself, and that ideally all communication is through interfaces, in a contract-driven/responsibility-driven paradigm? (ie, the 'dependency only on lower layers' is contrived). Likewise with the domain layer talking to the database - the domain layer is as decoupled (through DAO etc) from the database as the database is from the domain layer. Neither is dependent on the other, both can be swapped out.
Second, the idea of a conceptual straight line (as in from one layer to the next) is artificial - isn't there more a network of intercommunicating but separate modules, including external services, utility services and so on, branching off at different angles?
Thanks all - hoping that your responses can clarify my understanding on this..
Edit: In fact Evans clarifies later that it is case (b) he is talking about: "Layers are meant to be loosely coupled, with design dependencies in only one direction. Upper layers can use or manipulate elements of lower ones straightforwardly by calling their public interfaces, holding references to them. ... When an object needs to communicate upward we need another mechanism .. such as OBSERVERS"
This seems wholly contrived to me. It seems to confuse design dependencies with just the flow of the interaction. UI needs a reference to the app because actions are generally user initiated! For actions that are app initiated, eg some internal timer event alerting the user to something, the app now needs a reference to the UI, just as much as the UI needed a reference to the app earlier. In what sense is one more 'design dependent' than the other? To back up my point, to implement OBSERVER, it's the APP that's going to need a list of references to the UI components.
It seems to me that the only reason the references and design SEEM to go from top layer to bottom is because that's where the actions typically get initiated. When the action is initiated in the app, the references have to go the other way..