CodingBlocks
74. Clean Architecture – The Art of Drawing Lines
It’s time for another deep dive into Robert C. Martin’s Clean Architecture as Allen warns us about driving in front of him, Joe tries to describe a diagram again, and Michael can’t understand the survey results.
Using your podcast player to read this? Head to https://www.codingblocks.net/episode74 to find this episode’s show notes.
Sponsors
- FreshBooks.com/Coding – Use code “CODING BLOCKS” in the “How Did You Hear About Us?” section
Survey Says …
The episode we ask: What is the oldest code you actively, regularly work with?
#yop-poll-container-51_yp5a77ad1104fd3 { width: 1000; background:#fff; padding:10px; color:#555; overflow:hidden; font-size:12px; } #yop-poll-container-51_yp5a77ad1104fd3 input[type='text'] { margin:0px 0px 5px 0px; padding:2%; width:96%; text-indent:2%; font-size:12px; } .yop-poll-name-51_yp5a77ad1104fd3 { font-weight:bold; background:#327BD6; color:#fff; padding:5px; text-align:center; font-size:12px; } #yop-poll-questions-container-51_yp5a77ad1104fd3 { font-size:14px; margin:5px 0px; } .yop-poll-question-container-51_yp5a77ad1104fd3 { padding: 2px; } .yop-poll-question-51_yp5a77ad1104fd3 { background:#327BD6; color:#fff; margin-bottom: 21px; margin-top: -10px; font-style: italic; text-align: center; width: 100%; padding:5px; } .yop-poll-answers-51_yp5a77ad1104fd3 { } .yop-poll-answers-51_yp5a77ad1104fd3 ul { list-style: none outside none; margin: 0; padding: 0; } .yop-poll-li-answer-51_yp5a77ad1104fd3 { font-style:normal; margin:0px 0px 10px 0px; padding:0px; font-size:12px; margin-bottom:20px; } .yop-poll-li-answer-51_yp5a77ad1104fd3 input { margin:0px; float:none; } .yop-poll-li-answer-51_yp5a77ad1104fd3 label { margin:0px; font-style:normal; font-weight:normal; font-size:12px; float:none; } .yop-poll-results-51_yp5a77ad1104fd3 { font-size: 12px; font-style: italic; font-weight: normal; margin-left: 15px; } .yop-poll-customs-51_yp5a77ad1104fd3 { } .yop-poll-customs-51_yp5a77ad1104fd3 ul { list-style: none outside none; margin: 0; padding: 0; } .yop-poll-li-custom-51_yp5a77ad1104fd3 { padding:0px; margin:0px; font-size:14px; } /* Start CAPTCHA div style*/ #yop-poll-captcha-input-div-51_yp5a77ad1104fd3 { margin-top:5px; } #yop-poll-captcha-helpers-div-51_yp5a77ad1104fd3 { width:30px; float:left; margin-left:5px; height:0px; } #yop-poll-captcha-helpers-div-51_yp5a77ad1104fd3 img { margin-bottom:2px; } #yop-poll-captcha-image-div-51_yp5a77ad1104fd3 { margin-bottom:5px; } #yop_poll_captcha_image_51_yp5a77ad1104fd3 { float:left; } /* End CAPTCHA div style*/ .yop-poll-clear-51_yp5a77ad1104fd3 { clear:both; } #yop-poll-vote-51_yp5a77ad1104fd3 { } /* Start Result bar*/ .yop-poll-results-bar-51_yp5a77ad1104fd3 { background:#f5f5f5; height:10px; } .yop-poll-results-bar-51_yp5a77ad1104fd3 div { background:#555; height:10px; } /* End Result bar*/ /* Start Vote Button*/ #yop-poll-vote-51_yp5a77ad1104fd3 div#yop-poll-vote-51_yp5a77ad1104fd3 button { float:left; } #yop-poll-vote-51_yp5a77ad1104fd3 div#yop-poll-results-51_yp5a77ad1104fd3 { float: right; margin-bottom: 20px; margin-top: -20px; width: auto; } #yop-poll-vote-51_yp5a77ad1104fd3 div#yop-poll-results-51_yp5a77ad1104fd3 a { color:#fff; text-decoration:underline; font-size:12px; } #yop-poll-vote-51_yp5a77ad1104fd3 div#yop-poll-back-51_yp5a77ad1104fd3 a { color:#555; text-decoration:underline; font-size:12px; } #yop-poll-vote-51_yp5a77ad1104fd3 div#yop-poll-archive-51_yp5a77ad1104fd3 a { color:#555; text-decoration:underline; font-size:12px; } #yop-poll-vote-51_yp5a77ad1104fd3 div { float:left; width:100%; } /* End Vote Button*/ /* Start Messages*/ #yop-poll-container-error-51_yp5a77ad1104fd3 { font-size:12px; font-style:italic; color:red; text-transform:lowercase; margin-bottom:20px; text-align:center; } #yop-poll-container-success-51_yp5a77ad1104fd3 { font-size:12px; font-style:italic; color:green; margin-bottom:20px; text-align:center; } /* End Messages*/#yop-poll-container-51_yp5a77ad1104fd3 img { max-width: 1000; } .yop-poll-forms-display{}What is the oldest code that you actively, regularly work with?
- Less than 1 year. Green as can be!
- 1-3 years. Was there life before Angular?
- 3-10 years. Back when JavaScript only ran in the browser.
- 10-15 years. Pre-jQuery, we had to getElementById back then!
- More than 15 years old. Pre-Stack Overflow?!?!
News
- Huge thanks to those that took time out of their day to leave us a review:
- iTunes: UnhandledExcepSean
- Stitcher: RobertB, RGomez, UnhandledExcepSean
- You know that problem you figured out? Chances are, someone else as the same problem. Share the knowledge. Write a blog/wiki article about it.
- Come see Joe speak at the Orlando Code Camp: http://www.orlandocodecamp.com/
- Want to help us? Visit our sponsors and check out our affiliate resources.
All about Boundaries
Drawing Lines
“Software architecture is the art of drawing lines …” – Robert C. Martin
- Lines are there to keep one side from knowing too much about the other
- Putting it all together, we get: a line drawing programmer, who is concerned with the intent, operation, deployment and maintenance of systems
- Lines are drawn all throughout the life of writing the software
- Conway’s game of life: https://www.codingblocks.net/videos/game-of-life-javascript/
- Reminder – goal of the architect is to minimize the amount of human resources required to build and maintain a system
- Premature decisions are ones based on the technologies rather than the business use cases / needs
- Story of the multi-tiered scalable architecture that was built, but never utilized
- Development efforts many times greater than a simpler architecture
- So, if you’re organization doesn’t think dependency management, or encapsulation are important – does your organization not think architecture is important?
The Success Story of FitNesse
- By creating interfaces for data access, the storage technology was able to be postponed
- Stubbed out the data with mock classes
- When the stubbed out mocks weren’t enough, they went to an in memory extension of the same interface with more data
- mySQL had been the initial intent, but the held back until they needed to persist and decided the file system was the way to go
- The storage decision was deferred until they realized they didn’t even need the DB
- Then a customer needed it in mySQL, and because it was designed in a deferred fashion, the customer was able to get the mySQL implementation fully fleshed out in a SINGLE DAY
- Note that deferring the decision didn’t hamper the technology decision in the long-run, rather it allowed it to be easily adopted
- Interesting side note – by deferring this, they didn’t have to worry about all the things that come with running an RDBMS while developing – no schema issues, query issues, etc.
Which lines do you draw, and when?
“You draw lines between things that matter and things that don’t.” – Robert C. Martin
- GUI doesn’t matter to business rules….so there should be a line
- The notion that the database is tied to the business rules is misguided
- “The database is a tool that the business rules can use indirectly.” – Robert C. Martin
- Business Rules –> Database Interface | <– Database Access –> Database
- Call them “knows about” lines
- The database component is nothing more than a translator that converts the needs or requests of the business class into the language to retrieve / store data specific to the business rules
- The arrow pointing from the Database component to the Business rules component indicates that the business rules component contains nothing more than an interface to the methods exposed by the database component
- Any database / storage method could be swapped out behind the scenes
- Note: just like in the onion architecture, the DB is on the OUTER most layer here!
What about input and output?
- Developers and users get confused about what the system is.
- Most people think about the UI when they think about how a system works
- The UI is basically irrelevant – the business rules / model could function with or without the GUI
- “The interface does not matter to the model …” – Robert C. Martin
- The UI is basically irrelevant – the business rules / model could function with or without the GUI
- The boundary between the UI and the Business rules are in the direction of the UI –> Business Rules
Plugin architecture
- Business rules should be separate from pieces that are considered pluggable (or should be considered pluggable)
- This is not to say that these changes are always trivial – they might be involved, but thinking this way gets you started down the right path
- We want some modules to be immune to changes in other components
- Business rules should not break due to a change in the UI, or schema changes in the database
- Great Pluralsight video on organizing Entity Framework + DDD: https://www.pluralsight.com/courses/domain-driven-design-fundamentals
- Weekly Dev Tips: http://www.weeklydevtips.com/
- By arranging our modules into a plugin architecture, we create firewalls across the components
- Boundaries are drawn where there is an _axis of change_.
- Components on different sides of the boundaries change at different rates and for different reasons
- Remember this from episode 68? OO’s primary benefit is dependency indirection – otherwise we should all just go back to C!
The Conclusion of Drawing Lines
- Draw lines by partitioning the systems into components
- The components dependency directions (the arrows pointing) should be pointing towards the core business rules
- This is an application of the Dependency Inversion Principle and the Stable Abstractions Principle
Boundary Anatomy
Boundary Crossing
- This occurs when a function reaches from one component across the boundary into another component
- The trick is managing the source code dependencies
- Why the source code?
- When one source code module changes, others may have to change as well
- Building and maintaining firewalls to protect against these changes is the purpose of boundaries
The Dreaded Monolith
- Just because the boundaries are not visible during deployment doesn’t mean they don’t exist
- Even for statically linked libraries, the fact that they can be independently developed and marshalled is extremely valuable
- Interfaces are incredibly important
- Communications in a monolith are fast and inexpensive
Deployment Components
- Simplest representation of an architectural boundary in a deployed application is a dll, or a jar or gem, etc.
- Components delivered as binaries are an example of the deployment-level decoupling mode.
- Very similar to a monolith – only real difference is rather than a single exe it’s bundled dynamic libraries
Threads
- Not necessarily boundaries – just a way to organize and schedule execution of code
Local Processes
- This is a much stronger physical architectural boundary
- Typically communicate with sockets
- Run in separate memory spaces and within the same processor
- Sort of an uber component
- Communications across processes can be expensive because of the marshalling in and out of the OS layer
- The architectural goal is for lower-level processes to be plugins to higher-level processes
Services
- Strongest boundary
- Don’t have to run in same process
- Assumes all communications happen over a network
- Due to this, can be very slow and chattiness should be avoided when possible
The Anatomy Conclusion
- Most systems (other than monoliths) use many boundary strategies
Resources We Like
- Clean Architecture by Robert C. Martin (Amazon)
- Domain-Driven Design Fundamentals by Julie Lerman and Steve Smith (available at Pluralsight)
Tip of the Week
- Use CTRL+SHIFT+C (or CMD+SHIFT+C on macOS) to open a command prompt in your project’s root directory.
- Use the Output window in SQL Server Management Studio to see how it does what it’s doing.
- Octotree – A Chrome/GitHub extension that nicely displays the source code in a navigation pane.
- Available in the Chrome Web Store.