Podcast: Play in new window | Download
Subscribe: Apple Podcasts | Spotify | TuneIn | RSS
We’re back with our last deep dive into Robert C. Martin’s latest book, Clean Architecture, while Allen suffers from sleep deprivation, Joe shows us his dance moves, and Michael’s mind is blown on how to unit test.
Sponsors
- FreshBooks.com/Coding – Use code “CODING BLOCKS” in the “How Did You Hear About Us?” section
Survey Says
It’s time for another survey and this episode we ask: Do you pay attention to 3rd party licenses?
News
- Thank you to everyone that left us a review:
- iTunes: Frodo McNuggets, 007 Benny, Likely Suspect, Markus Rasbech, alex13cp, Klenke Family, ChrisSeanHayes, Deleeted, Grim 4 2, Zac Reeves
- Stitcher: Roca88, DeezStructs, TheCodedSelf, JoeIsDev4Life
- Stack Overflow 2018 survey results are out and always interesting. (Stack Overflow)
- Developers love trendy new languages but earn more with functional programming (Ars Technica)
- Irrelevant languages? Can anyone _really_ know?
- Joe moderated a Productivity in Tech round table regarding programmers and management. (YouTube)
- Allen find the ultimate silent mouse. (Amazon)
Your Service is not an Architecture
Services Great and Small
- Service Oriented Architectures and Micro Service Architectures:
- What I Wish I Had Known Before Scaling Uber to 1000 Services (YouTube)
- Services _seem_ to be strongly decoupled.
- And they _seem_ to support independent development and deployment.
- But are they truly decoupled?
- Real world stories of serverless, microservices, and DevOps (Orlando Code Camp)
- Services are not an architecture.
- Services that only separate application behaviors are not much more than expensive function calls.
- This doesn’t mean that _all_ services need to be significant.
- Even when they break the Dependency Rule, there are, at times, benefits to separating the functionality.
- But this does not define an architecture.
Service Benefits?
- Are services truly decoupled? – Not really…
- They are tightly bound by the data they share.
- If a new field is added to a data structure that services pass to each other, then all those services must be modified.
- They must all agree on how to use the various fields on the data, so again they’re tightly coupled.
- Service interfaces are not any more formal, rigorous, or defined than functions.
- They are tightly bound by the data they share.
- But are they independently developed and deployed?
- It’s been proven that large enterprise systems can exist in the form of monoliths, services, or component based systems.
- David Heinemeier Hansson on the State of Rails, Monoliths, and More (Software Engineering Radio epsiode 261)
- Because services are often tightly bound to the data they ingest or output, they are still tightly coupled to their dependencies and their deployments must still be coordinated with those external changes.
- It’s been proven that large enterprise systems can exist in the form of monoliths, services, or component based systems.
- The Kitty Problem…
- A taxi service turns into a kitty delivery service – how many services would have to change?
- Cross cutting concerns impact all things – functional, service oriented, whatever.
- Take care so that new features don’t cut across all of your services.
- How to fix this? SOLID design principles.
- Services can also be abstracted away with those same principles / abstractions.
Cross-Cutting Concerns
- Architectural boundaries don’t run between services but rather through them.
- Internal pieces of services must follow the Dependency Rule in order to keep them decoupled.
- The architecture is defined by the boundaries within the system and the dependencies that cross those boundaries.
- Architecture is not defined by the physical mechanisms of how the code communicates and runs.
Test Boundary
- Yes, the tests are a part of an architecture.
- Very detailed and concrete – following the dependency rule – always pointing inward.
- Think of them as the outermost circle.
- They are independently deployable and the most isolated system component.
- NOTHING should depend on them.
- They support development, not operation.
- All code should be modeled like tests.
- Fragile Tests Problem
- Solution is to design for testability.
- Don’t depend on the volatile things.
- Creating a test API:
- A superset of the interfaces used by the UI.
- Decouples tests from the application.
- Rather than writing unit tests against all the production classes, you write tests against the API allowing the primary application to change without worrying about breaking many unit tests.
- Testing API hides the structure of the application.
- This goes against a lot of how-to unit philosophies.
- Testing API should have super-powers – outside the normal powers of a regular system user – therefore it’s probably best if deployed separately so it never ships with your product.
- A superset of the interfaces used by the UI.
Clean Embedded Systems
- Software doesn’t wear out, but it can be destroyed by unmanaged dependencies on firmware and hardware.
- Firmware isn’t firm because of _where_ it is stored; rather what it depends on and how hard it is to change as the hardware changes.
- “Although software does not wear out, it can be destroyed from within by unmanaged dependencies on firmware and hardware.”
- Non-embedded developers also create firmware when they embed SQL statements in your code.
- Make it work. Then make it better.
- Only making it work is doing everyone a disservice.
- There more to software development than just making it work.
- Intermingling software and firmware is an anti-pattern.
- Intermingled code “resist” changes.
- Worst these changes are dangerous and require full regression tests of the entire system.
- Target hardware bottleneck – if code is written that will only work on the target hardware, that will simply slow you down and it is usually due to a poor architecture.
- HAL is the boundary between the software and the firmware.
- It provides a service without revealing how.
- You’re doing it right if you can test the software off of the hardware.
- PAL is the boundary that sits between the firmware and the hardware.
- Anything that knows about the hardware registers _becomes_ firmware.
- By implementing a PAL, you can make the firmware less firm and testable off of the hardware.
- OSAL is the boundary between the software and the OS.
- Treat the OS as a detail to protect yourself against dependencies.
- A layered architecture is premised on the idea of programming to interfaces.
- This allows for substitutability.
- A clean embedded architecture’s software is testable:
- Off of the target hardware.
- Off of the target operating system.
- Within layers because the modules interface through interfaces.
- #ifdef statements violate the DRY principle when you have them sprinkled all over your code.
- Keep those isolated to a single file.
- Letting all code become firmware is bad.
- Only being able to test on the target hardware is bad.
- Following the principles outlined in Clean Architecture is good for your code.
Resources We Like
- Clean Architecture by Robert C. Martin (Amazon)
- Clean Architecture sample solution setup from @ardalis (Github)
- Brain Games (Netflix)
- MRC Cognition and Brain Sciences Unit – …it deosn’t mttaer in waht oredr the ltteers in a wrod are… – https://www.mrc-cbu.cam.ac.uk/people/matt.davis/cmabridge/
Tip of the Week
- Get involved in a hackathon!
- Episode 67 – Your First Hackathon (Cynical Developer)
- Hack24 Pre Hackathon Setup Check (YouTube)
- Remote pair programming with Visual Studio Live Share is now a possibility.
- Introducing Visual Studio Live Share (Visual Studio Code blog)
- Sign up for early access (Sign up)
- Microsoft announces Blazor, an experimental web UI framework using C#/Razor and HTML running in the browser via WebAssembly. (GitHub)