Software Architecture
Growing software
Linux kernel - number of lines of code (forrás: Wikipedia)
- Why Linux’s biggest ever kernel release is really no big deal
- Linux 5.8 features over 14,000 non-merge commits, some 800,000 new lines of code, and added around a hundred new contributors.
The more, the better?
if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent"
E.W. Dijkstra EWD 1036
Every line of code written comes at a price: maintenance. To avoid paying for a lot of code, we build reusable software. The problem with code re-use is that it gets in the way of changing your mind later on.
Complex Software
How to measure? - Cyclomatic complexity
Cyclomatic complexity measures the number of linearly independent paths through the method, which is determined by the number and complexity of conditional branches. A low cyclomatic complexity generally indicates a method that is easy to understand, test, and maintain. The cyclomatic complexity is calculated from a control flow graph of the method and is given as follows:
cyclomatic complexity = the number of edges - the number of nodes + 1
where a node represents a logic branch point and an edge represents a line between nodes.
The rule reports a violation when the cyclomatic complexity is more than 25.
Issues with cyclomatic complexity
- Not every statement is equal
if
,while
,for
andcase
statements considered as identical
- Nesting
- it doesn’t account for nesting
NPATH complexity
The NPath complexity of a method is the number of acyclic execution paths through that method. A threshold of 200 is generally considered the point where measures should be taken to reduce complexity.
Consider writing a unit test and you have a function with an NPath complexity of 16. This means that if you need want 100% code coverage you need to test for 16 possible outcomes and that would end up in pretty messy tests.
Niklas Modess - NPath complexity and cyclomatic complexity explained
Complex vs. complicated
Michael Bykovski: Simple vs. Complicated vs. Complex vs. Chaotic
Complexity: Accidental vs. Essential
Accidental Complexity is something that can be simplified by a new idea, design, technique, procedure or approach. Essential Complexity is something that can't be simpler or something that loses value when it becomes simpler. Identifying the difference between accidental and essential complexity is a fundamental design technique.
John Spacey - Complexity: Accidental vs. Essential
What is Software Architecture
"Architecture" is a term that lots of people try to define, with little agreement. There are two common elements: One is the highest-level breakdown of a system into its parts; the other, decisions that are hard to change.
Martin Fowler - Patterns of Enterprise Application Architecture
All architecture is design but not all design is architecture. Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change.
Grady Booch
In most successful software projects, the expert developers working on that project have a shared understanding of the system design. This shared understanding is called ‘architecture.’ This understanding includes how the system is divided into components and how the components interact through interfaces. These components are usually composed of smaller componnets, but the architecture only includes the components and interfaces that are understood by all the developers.
Ralph Johnson, XP mailing list
Miért kell ez?
Architecture is the decisions that you wish you could get right early in a project
-- Ralph Johnson
- https://gbksoft.com/blog/why-you-need-a-software-architect-for-your-project/
- https://www.martinfowler.com/articles/designDead.html#SoIsDesignDead
- https://www.codeproject.com/Articles/1064240/Introduction-to-Software-Architecture
Hogyan lesz egy ilyenünk?
- Practical Tips on Software Architecture Design, Part One
- Practical Tips on Software Architecture Design, Part Two
Architecture decision records
Alább látható a Michael Nygard féle sablon: Documenting Architecture Decisions
# ADR template by Michael Nygard
This is the template in [Documenting architecture decisions - Michael Nygard](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions).
You can use [adr-tools](https://github.com/npryce/adr-tools) for managing the ADR files.
In each ADR file, write these sections:
# Title
## Status
What is the status, such as proposed, accepted, rejected, deprecated, superseded, etc.?
## Context
What is the issue that we're seeing that is motivating this decision or change?
## Decision
What is the change that we're proposing and/or doing?
## Consequences
What becomes easier or more difficult to do because of this change?
Design Principles
- How to Learn Software Design and Architecture
- fenti kép forrása
- SOLID
- YAGNI
- "You aren't gonna need it"
-
Always implement things when you actually need them, never when you just foresee that you need them.
Ron Jeffries
- TDD
4C: Complete, Compliant, Clear, Concise
- Four Cs for Flawless Agile Business Requirements
- https://www.mojotech.com/blog/the-4cs-a-code-review-mnemonic/
Rob Pike's 5 Rules of Programming
- You can't tell where a program is going to spend its time. Bottlenecks occur in surprising places, so don't try to second guess and put in a speed hack until you've proven that's where the bottleneck is.
- Measure. Don't tune for speed until you've measured, and even then don't unless one part of the code overwhelms the rest.
- Fancy algorithms are slow when n is small, and n is usually small. Fancy algorithms have big constants. Until you know that n is frequently going to be big, don't get fancy. (Even if n does get big, use Rule 2 first.)
- Fancy algorithms are buggier than simple ones, and they're much harder to implement. Use simple algorithms as well as simple data structures.
- Data dominates. If you've chosen the right data structures and organized things well, the algorithms will almost always be self-evident. Data structures, not algorithms, are central to programming.
Pike's rules 1 and 2 restate Tony Hoare's famous maxim "Premature optimization is the root of all evil." Ken Thompson rephrased Pike's rules 3 and 4 as "When in doubt, use brute force.". Rules 3 and 4 are instances of the design philosophy KISS. Rule 5 was previously stated by Fred Brooks in The Mythical Man-Month. Rule 5 is often shortened to "write stupid code that uses smart objects".
Zen of Python1
The Zen of Python is a collection of 19 "guiding principles" for writing computer programs that influence the design of the Python programming language. 2
- Beautiful is better than ugly.
- Explicit is better than implicit.
- Simple is better than complex.
- Complex is better than complicated.
- Flat is better than nested.
- Sparse is better than dense.
- Readability counts.
- Special cases aren't special enough to break the rules.
- Although practicality beats purity.
- Errors should never pass silently.
- Unless explicitly silenced.
- In the face of ambiguity, refuse the temptation to guess.
- There should be one-- and preferably only one --obvious way to do it.
- Although that way may not be obvious at first unless you're Dutch.
- Now is better than never.
- Although never is often better than right now.
- If the implementation is hard to explain, it's a bad idea.
- If the implementation is easy to explain, it may be a good idea.
- Namespaces are one honking great idea -- let's do more of those!
Zen of Zyg3
- Communicate intent precisely.
- Edge cases matter.
- Favor reading code over writing code.
- Only one obvious way to do things.
- Runtime crashes are better than bugs.
- Compile errors are better than runtime crashes.
- Incremental improvements.
- Avoid local maximums.
- Reduce the amount one must remember.
- Focus on code rather than style.
- Resource allocation may fail; resource deallocation must succeed.
- Memory is a resource.
- Together we serve the users.
3 https://ziglang.org/documentation/0.8.0/#Zen
The 23 Gang of Four Design Patterns
Teljes összefoglaló, ahol mindegyikhez van magyarázat, UML diagram és C# kód.
Topologies
Introduction to Software Architecture
Layered Architechture
Message Bus Architecture
Server-Client Architecture
C4 model
- The C4 model for visualising software architecture
- Context, Containers, Components and Code
- The C4 Model for Software Architecture
Level 1: System Context diagram
Shows the software system you are building and how it fits into the world in terms of the people who use it and the other software systems it interacts with.
Simon Brown - The C4 Model for Software Architecture
Level 2: Container diagram
Zooms into the software system, and shows the containers (applications, data stores, microservices, etc.) that make up that software system. Technology decisions are also a key part of this diagram.
Simon Brown - The C4 Model for Software Architecture
Level 3: Component diagram
Zooms into an individual container to show the components inside it. These components should map to real abstractions (e.g., a grouping of code) in your codebase.
Simon Brown - The C4 Model for Software Architecture
Level 4: Code
Finally, if you really want or need to, you can zoom into an individual component to show how that component is implemented.
Simon Brown - The C4 Model for Software Architecture
Versioning
Semantic Versioning
- website
- Why I don't like SemVer anymore
- blogposzt az árnyoldalairól
Calendar Versioning
- "CalVer is a versioning convention based on your project's release calendar, instead of arbitrary numbers."
- YYYY.MINOR.MICRO
- website
ZeroVer: 0-based Versioning
- "Your software's major version should never exceed the first and most important number in computing: zero."
- e.g.: 0.4.1
- website