Useful Abstractions
The following are simply links to useful abstractions (UAs) that may or may not be references by the guidelines for Hub. These are intended as reference material to facilitate understanding and are not a canonical list of UAs we implement in full or part within Hub or elsewhere.
Coupling and Cohesion
This may be the most important concept to understand. The holy grail in software design and architecture is high cohesion and low coupling. This is easier said than done.
- Coupling and Cohesion Short 1 min watch
- Highly COHESIVE Software Design to tame Complexity 9 min watch
In large systems, the idea of having a single entity live in a single table just isn't reality. This quote and the example he gives can be applied to many entities within Prenda software: [Micro]school, term, guide, etc.
- Low Coupling, High Cohesion 3 min read
- AVOID Entity Services by Focusing on Capabilities (snippet) 2 min watch - watch from linked timestamp
- SOLID Principles? Nope, just Coupling and Cohesion 14 min watch
In my experience, informational cohesion can really drive a large degree of coupling. Informational Cohesion has its place. But the switch from thinking with a focus on Informational Cohesion to a focus on Functional Cohesion aligns you closer with business concerns and frees you from the mental gymnastics required for managing coupling and cohesion while aligning new features and support of old features against an information focused system - data supports capabilities, not the other way around.
Vertical Slices
- Tired of Layers? Vertical Slice Architecture to the rescue 13 min watch
- Lessons Learnt from Vertical Slice Architecture 12 min watch
- DRY vs WET
- Rearranging Testing Pyramid (Subcutaneous Tests most Confidence)
- Vertical Slice and DDD are not Mutually Exclusive
- Vertical Slice Architecture - Jimmy Bogard102 min watch
- Vertical Slice Architecture, not Layers 47 min watch
Bounded Contexts
- Anatomy of Domain Driven Design (short ver.) 10 min read
- Domain Driven Design Distilled Book ~$30-40
- Domain Modeling Made Functional Book ~$30-40
Domain Modeling
- Domain Modeling - Software Architecture Explained (Ft. Domain Driven Design) 6 min watch
- Domain Modeling Made Functional - Scott Wlaschin 51 min watch
- Designing with types: Making illegal states unrepresentable
- Errors as Documentation 6 min read
Clean/Hexagonal/Onion Architecture/Ports and Adapters
- Onion Architecture - Software Design Patterns Explained 12 min watch
- Onion Architecture with DDD and CQRS 51 min watch
Task/Behaviors instead of CRUD
- CRUD isn't for complexity 1 min watch
- CRUD API + Complexity = Death by a 1000 Papercuts
- Why Are You Still Creating CRUD APIs?
Persistence Agnosticism
Derived Types
- Synchronized Derived Types 5 min read
Command Query Responsibility Separation (CQRS) + Command Query Separation (CQS)
- Is REST with CQRS Possible? 17 min watch
- CQRS From Scratch With TypeScript 12 min read
- https://www.youtube.com/watch?v=sD6W4n-Ksfs&ab_channel=Petabridge 7 min watch (just CQRS section)
Errors as Values
- STOP throwing Exceptions! Start being Explicit 10 min watch
Distributed Systems
- CAP Theorem Simplified 6 min watch
- Data Consistency | Strong Consistency vs. Eventual Consistency | System Design for Beginners 7 min watch
- Eventual Consistency is a UX Nightmare 12 min watch
- "I NEED data from another service!"... Do you really? 11 min watch
- When To Use Microservices (And When Not To!) • Sam Newman & Martin Fowler • GOTO 2020 39 min watch
We tend to violate monolith architecture by not respecting modules. Breaking them into services makes it harder to do so. 3 min watch - just the Organization and teams section
Domain Driven Design
- Domain Driven Design Hexagon 30 min read (reference material)
- Using Event Storming to Introduce Domain Driven Design
- Is Domain Driven Design Overrated? 51 min watch
Repository Pattern
- The Repository Pattern explained for EVERYONE (with Code Examples) 14 min watch
- Repository Pattern using NestJS 6 min read
- The example uses NestJS but the repository pattern can easily be implemented without a framework. Pre-application of a dependency matching an interface/type requirement against a curried function is one way that also works.
Dependency Management (Tactical in code)
- Functional Dependency Injection in Typescript%20those%20dependencies%20as%20arguments.) 7 min read
- Six Approaches to Dependency Injection 20 min read (for all sub-articles)
Additional Learning
High Optionality Programming
Article ~10 minute read
Video 22 min watch.
The earlier you are in a project's lifecycle, the more options you have and the less expensive they are then.. We should pay a premium here when the options are abundant and the cost is relatively low.
(Top Youtube Comment) The essence of architecture is at least as much about what changes are anticipated as it is about what is built. Every architectural choice you make is a bet on the relative likelihood of different changes in the future. How good a bet you can make a function of an understanding of core software design principles and experience in making (not avoiding) learning from the outcomes of bets.
Examples of technical debt:
- Tight coupling based on information cohesion causing issues when bumping into functional cohesion. The bloating of collections in mongo or tables in Hub, entity classes/types in Hub, or different modules in Zoho are good examples.
- Tight coupling of unrelated concerns. There are cases where changing the alias of a column in a sql query or a field on a table would require changes all the way up to a React component.
- Any of the data integrity issues we've had or STILL have and haven't resolved (school/term statuses, guide data, parent data, microschool data, etc.).
- The lack of a single and independent Authorization capability to serve all consumers.
- Not identifying the distinct stages of business processes and the owners for those stages.
- Not identifying the life cycle of data within our system.
- Building solutions to solve "this year's problems".
Green Field Projects
Greenfield Project? Start HERE! 13 min watch