I was intrigued by Robert Martin's talk about "Architecture: The Lost Years". In it he discusses the Entity, Boundary, Control design pattern on which MVC is based. I love the idea of deferring architectural decisions. He described deferring the decision about how to implement the DB layer in his own wiki app FitNesse. I have organically deferred decisions like this in my own coding, though there wasn't a preconceived modular design that brought this about.
I want to better understand this EBC architecture (which seems closely related to DCI) from a practical standpoint so that I can begin using in a small project. I want to capitalize on "deferring decisions" and the ability to swap out aspects of the design like the UI.
Rails, for example, uses a form of EBC (MVC) but it's so heavily baked in that one could not easily substitute an alternate UI thus converting a Rails app to a console app or a desktop app. The intriguing thing about design for me is this ability to transform applications by swapping one thing out and plugging another in. That is, I wonder at the idea of designing an architecture so that one can, in a manner of speaking, swap out the UI or the persistence layer. I feel that if the architecture is well designed, the coupling will be low, and such a feat will be within grasp.
I've ordered the book by Ivar Jacobson that Bob mentioned in his talk. I've search online quite a bit but all of the examples I've found show simple diagrams. I speak code. I would benefit more from looking over a few simple classes that demonstrate the concept and show how one might swap out one layer (UI, DB) for some other implementation through the use of boundary classes.
If someone can't point me to a good resource illustrating this, would this be hard to whip up? Maybe we could use the standby example used in lots of software books: a video rental store (almost a relic these days). Please demonstrate how the UI or DB layer could be swapped. One thing that's confusing me is views. I can't tell from the diagrams I've seen if the views are the boundary classes themselves or if they just communicate with them. Also, Bob mentioned that the original intent of EBC was that we'd have lots of micro-views not a single macro-view (as we do in typical MVC); I'm curious what this might look like. (I prefer Ruby or JavaScript but, as beggars can't be choosers, any example would be fine.)
Thank you.
As far as I understand the video by Uncle Bob using "EBI" (Entity, Boundary, and Interactor) you should completely decouple your business behavior/state from frameworks/OS and services.
So in case of an Rails app your business behavior/state is completly free of dependencies to the Rails framework and hence can be tested like with rspec without firing Rails!
So on the business side you have Boundary classes wich interact with the Rails side using request and response models (very simple dataholders, not to be exchanged with the usual models from Rails). Only the Boundary classes interact with the Interactor classes which implement the (business) use cases / scenarios. And only the Interactor classes interact with the Entity classes which encapsulate the business state.
On the Rails side you find Controller classes interacting with Boundary classes (using Request models) and backwards a Boundary class interacts with a Presenter (using a Response model). Only Presenters/Controllers interact with Views (with the help of models (again simple data-holders). Note that in the realm of Rails Presenters are most likely Controllers.
Where does this leave AR? Well AR just provides the persistant service. On the same level as the Presenter/Controller level you will find Service classes which provide their services to the Boundary classes. So they provide all the necessary services which are frameworks/OS/technology dependent like persistance, security, timing, notifaction, etc..
With this architecture you are really able to reuse your business logic and completely replace the UI or database technology. For example, porting to mobile (iOS, Android, Windows) should be pretty straight forward.
With Rails, your app folder could look like:
app/
controllers/ Only these interact with Boundary classes
models/ simple data-holders, no AR here! (see services)
views/
services/ AR-stuff
boundaries/ To be tested without Rails
models/ Request & Response
interactors/ use cases / scenarios, to be tested without Rails
entities/ "the real business model without technical dependencies"
With this architecture, you need to code a bit more but don't forget the benefits of a good architecture:
Last note: compared to the MVC pattern, its more like the M is replaced by EBI, the C can be splitted in CP/resenter), and an S(ervice) is added. So this could be called: VCPS/EBI but that sounds ugly to me ;-) BEPVICS maybe?
@Seralize, thanks for your feedback.
Let me try to answer your questions, so far I understand them: the stuff in services are coupled to Rails. They provide the implementation for the logic in EBI side. In the usecase of security, you have to be clear what (quantified) requirements you have, so you know what logic you can implement on EBI side, for instance (business) rules about when a user(role) has access to what content(and needs to be authenticated).
This means to implement authentication will be implemented using Rails, this service will be used by EBI. This security related logic in EBI is then pretty easy to reuse in your Java GUI example. There you have only to reimplement the authentication service.
To be clear in the security example:
The EBI side has the logic: what stuff needs what kind of security and when and how. The Rails knows nothing about this, it request what to do from the EBI side and or the EBI side request the Rails side to act.
The Rails side only implements the way how to do security like asking the user to authenticate (when needed) and passing the result of this to EBI so the logic can decide what should be done next.
EBI demands both sides to be decoupled & independent. It were as you are developing the EBI as a library with a defined API.
Ask and you shall receive. I kept my eyes open and discovered this resource by Avdi Grimm:
http://avdi.org/devblog/2011/11/15/early-access-beta-of-objects-on-rails-now-available-2/
In it, he covers some of the reason that Rails projects get so tightly coupled to both the framework and ActiveRecord. He uses TDD to assure loose coupling with techniques like
It provides a good start to answering this question in a practical way. (It costs $5 for the early beta but will eventually be free.) In fact, it's the first resource I've found that does. Please add any others you find.
Here's the real gem that elucidates the heart of the problem:
One day, after years of witnessing and addressing the technical debt incurred in various maturing Rails codebases as a result of ActiveRecord-inspired tight coupling, I had an epiphany. What if we stopped treating ActiveRecord as the backbone of our model classes, and instead, programmed as if ActiveRecord were merely a private implementation detail?
Corey Haines puts it another way:
I pull the behavior out of my models into other objects that wrap the models. I prefer to make the AR objects simple wrappers around the db-access stuff in AR.
I have a fairly strict rule that controller actions cannot use AR finders or, in fact, interact with AR at all. AR should be accessed within api methods inside your model, not from the outside.
This should be of interest too. It's the other book, not referred to by name in "Architecture: The Lost Years"
"Agile Software Development: Principles, Patterns, and Practices", by "Uncle Bob" Martin.
Taken from this SE question & answer. Read the other answers too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With