Software Architecture, Architect, and API Qualities
Software Architecture
Key Software Design Principles
Paul Rayner — How Agile Can Cripple Effective Design Work (and what to do about it)
"A good design is not one that correctly predicts the future, it's that makes adapting to the future affordable." -Venkat Subramaniam
Good Architecture Qualities:
Key Software Design Principles
Paul Rayner — How Agile Can Cripple Effective Design Work (and what to do about it)
"A good design is not one that correctly predicts the future, it's that makes adapting to the future affordable." -Venkat Subramaniam
Good Architecture Qualities:
- Useful, satisfies the requirements
- Bug free given adequate effort (remember Microsoft worse is better to be first to market)
- Responsive enough
- Secure
- Reliable enough 99.9, 99.999... see this and this
- Ubiquitous/Portable access/environment
- Robust - tolerant of faults with minimal outage and no corruption
- Maintainable/Extensible: adequate test coverage, easy to refactor
- Scalable: ideally horizontal scale vs. vertical
- Implementation consistency
- Cohesive modularity with low coupling
- Defined layering and visibility
- Acyclic / unidirectional dependencies
- Convention over configuration
- Overarching concerns are abstracted and consistent: security (authentication, authorization, auditing), monitoring, metrics, logging, persistence, transactions, exceptions, error messages, search, pagination, caching, configuration, internationalization, messaging
- Package by feature not by layer
- Not complex: KISS - Keep it simple, Stupid
- No waste, nothing extra: YAGNI - You aren't going to need it
- DRY - no/low duplication, follow Rule of Three
- Service Statelessness
- Microservices
- Continuously Delivery/Deployment: enable by microservices
- Zero-Downtime Deployment/Updates: if warranted, increases developer and testing effort
Good Architect Qualities - in no particular order
- Passion for the craft
- Good listener and communicator
- Collaborates and negotiates with all stakeholders to: extract and define true requirements, create comprehensive architecture, and achieve buy-in
- Technical knowledge
- Leadership skills, decision maker
- Aware of and navigates organizational politics
- Practical: can shoot the engineer and create a shippable product timely
- Careful: demands adequate testing and progressive deployments and/or migration to reduce risk
- Design and programming skills
- Business domain knowledge
- Software Development Process/Life Cycle experience and knowledge
- Curious: continuously explores new technologies, patterns, frameworks, tools, and best practices
- Continues to learn and grow, attending technical conferences
- Thorough: open-minded exploring beyond the first solutions, continually asking questions and seeking out alternatives
- Cautious: utilizes NEW alternatives when/where appropriate: beneficial, productive, stable, mature
- Scrutinizes costs, flexibility and maintenance of buy/COTS vs build/reinventing the wheel
- Pragmatic: can prioritize features and create MVP when necessary
- Grok, utilize, and communicate common well tested and understood design patterns
- Strives to recognize all assumptions and to validate them
- Documents assumptions and all considered alternatives with pros and cons, why certain choices were and weren't made - document for those that follow why the design is the way it is
- Mentor: shares knowledge and experience through demos, hosting technical talks, lunch & learn, and/or teaching others one-on-one or in group settings
- Not Pedantic, egotistical, sanctimonious, or self-righteous which inhibit collaboration & buy-in
- Overseer: reviews and monitors that implementation adheres to the overarching design goals and not violated without good reason
- Available to discuss the architecture and implementation concerns
- Timely: periodically reviews, updates, and adapts the architecture as necessary to align with new or changing business objectives and advances in industry, technology, and best practices
Good API Qualities - generally speaking, only violate with good reason
- Easy to learn, use, and extend API without documentation
- Hard to misuse the API, no ambiguity
- Easy to read and maintain code that uses the API
- API design is not a solitary activity, collaborate and carefully consider all opinions
- Favor unchecked exceptions over checked exceptions
- Never fail silently; don't swallow exceptions
- Don't use exceptions for flow control
- Include failure capture information in exceptions
- Methods should have three or fewer parameter
- Method parameters have consistent ordering
- Fluent style for ease of reading and use
- Return zero length arrays or empty collections instead of null
- Parameters types should be as specific as possible, ideally not Strings
- Service Provider Interface (SPI) - write two - three implementation minimum
- Functionality should be small and easy to explain and name or it's a sign of over-complexity
- Implementation should not impact API
- Minimize accessibility of everything
- Names matter, be consistent
- Document everything
- Consider performance implications of API
- Favor immutability
- Inheritance violates encapsulation: design and document or prohibit inheritance with final
- Favor Composition over Inheritance
- Subclass only where is-a relationship, otherwise utilize composition
- Reduce the need for boilerplate
- Don't violate principle of least astonishment - users of the API shouldn't be surprised
- Fail-fast: as soon as possible, ideally compile time
- Provide access to all data available in Strings, don't make clients parse Strings
- Overload with care to avoid ambiguous behavior, ideally use different names
- 12 factor app
Design Principles
Highly modular
- loose coupling - knowledge of other components, general interface dependency is best
- high cohesion - belong together, easy to understand and maintain
Principle of Least Knowledge (Law of Demeter)
- Single Responsibility
- Open for extension, Closed for modification
- Liskov Substitution Principle - Design by Contract
- Interface Segregation
- Dependency Inversion
Tools
- Structure101: modularity, dependency, visibility visualization and enforcement, $400-$1K
- Enterprise Architect: forward/reverse engineering, comprehensive, *nix w/wine, <$1K
- IBM Rational Rose: forward/reverse engineering, comprehensive, *nix compatible, >$3K
- Visual Paradigm: Eclipse/intellij integration, full featured, *nix, $700-$1400
- ObjectAid: Eclipse, class, sequence, forward/reverse engineering, *nix, $19
- Gliffy: web based, no forward/reverse engineering, $8/mo
- Cacoo: web based, no forward/reverse engineering, $5/mo
- Lucidchart: web based, no forward/reverse engineering, $9/mo
- Diagramly: web based, free
- You Want to Become a Software Architect? Here is Your Reading List!
- UML2
- 97 Things Every Software Architect Should Know
- No Silver Bullet by Frederick P Brooks
- The Free Lunch is Over
- Head First Design Patterns by Eric Freeman
- Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin
- The Pragmatic Programmer: From Journeyman to Master by Andrew Hunt
- Effective Java by Joshua Bloch
- Refactoring: Improving the Design of Existing Code by Martin Fowler
- Test Driven Development: By Example by Kent Beck
- Mythical Man Month by Frederick P Brooks
- The Elements of Programming Style by Brian W. Kernighan and P. J. Plauger
- Essential software architecture by Gorton, Ian
- Real World Java EE Patterns Rethinking Best Practices by Adam Bien
- Model Driven Design/Architecture
- Conways Law - organizational structure affects software modularity
- Your Job Is Not To Write Code
- Microservices - Martin Fowler
Use a Checklist
#78 It Takes Diligence
Effective architects often follow mundane daily and weekly checklists to remind
them of that which they already know academically, but fail to practice by habit. Without such
mundane checklists and reminders architects can quickly fall into software time, in which no
measurable progress is achieved because a lack of diligence allowed the architecture to meander
and violate known academic principles.
Comments