<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Software-Architecture on Osmar Petry</title><link>https://osmarpetry.dev/tags/software-architecture/</link><description>Recent content in Software-Architecture on Osmar Petry</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Sun, 01 Jun 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://osmarpetry.dev/tags/software-architecture/rss.xml" rel="self" type="application/rss+xml"/><item><title>Domain-Driven, Data-Oriented Design (DDDOD)</title><link>https://osmarpetry.dev/blog/dddod/</link><pubDate>Sun, 01 Jun 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/dddod/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;&#10;&lt;p&gt;Bill Kennedy adapts Domain-Driven Design principles to Go by emphasising data flow and simplicity. DDDOD keeps the focus on reliable data transformations while preserving idiomatic Go patterns.&lt;/p&gt;&#10;&lt;h2 id="why-not-pure-ddd"&gt;Why not pure DDD?&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Traditional DDD can introduce excessive abstraction and ceremony in Go projects.&lt;/li&gt;&#10;&lt;li&gt;Too many layers and interfaces obscure intent, reducing maintainability.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="core-pillars"&gt;Core pillars&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Data-oriented design&lt;/strong&gt;: prioritise data models and their transformations; ensure data can cross layers safely.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Validation &amp;amp; trust&lt;/strong&gt;: embed validation logic early; fail fast to maintain integrity.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Structured layers&lt;/strong&gt;: app → business → storage; each layer defines clear contracts and side-effects.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Domain isolation&lt;/strong&gt;: separate bounded contexts to prevent accidental coupling and cascading failures.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="implementation-tips"&gt;Implementation tips&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Use packages to reflect domains (&lt;code&gt;internal/user&lt;/code&gt;, &lt;code&gt;internal/auth&lt;/code&gt;); avoid grab-bag packages like &lt;code&gt;common&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Expose only necessary APIs; keep implementation details private.&lt;/li&gt;&#10;&lt;li&gt;Guard entry points with validation and logging to catch anomalies early.&lt;/li&gt;&#10;&lt;li&gt;Leverage functional options or constructors to initialize services with dependencies explicitly.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Bill Kennedy, “Domain-Driven, Data-Oriented Design” talk and articles (Ardan Labs).&lt;/li&gt;&#10;&lt;li&gt;Ardan Labs Service repository as a starter kit: &lt;a href="https://github.com/ardanlabs/service" target="_blank" rel="noreferrer"&gt;https://github.com/ardanlabs/service&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[ddd|Domain-Driven Design: Tackling Complexity in the Heart of Software]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Package Oriented Design</title><link>https://osmarpetry.dev/blog/pod-go/</link><pubDate>Mon, 12 May 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/pod-go/</guid><description>&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;&#10;&lt;p&gt;Bill Kennedy’s Package Oriented Design (POD) emphasises starting and ending architectural decisions at the package level. Each package should provide a focused solution for a domain problem to keep code composable, testable, and maintainable.&lt;/p&gt;&#10;&lt;h2 id="definition"&gt;Definition&lt;/h2&gt;&#10;&lt;p&gt;POD identifies where each package belongs and the design rules it follows. Packages act as the building blocks of Go applications, supporting composition and isolation.&lt;/p&gt;&#10;&lt;h2 id="guiding-philosophy"&gt;Guiding philosophy&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Purpose over storage:&lt;/strong&gt; packages should provide behaviour, not just hold utilities.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Encapsulation:&lt;/strong&gt; expose only necessary APIs and hide implementation details.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Portability:&lt;/strong&gt; a consistent package structure makes discussion and reuse easier across projects.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Layering:&lt;/strong&gt; organise code into purposeful layers, such as &lt;code&gt;kit&lt;/code&gt;, &lt;code&gt;application&lt;/code&gt;, and &lt;code&gt;service&lt;/code&gt;, with explicit interaction rules.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="benefits"&gt;Benefits&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Modularity:&lt;/strong&gt; domain-specific packages reduce unwanted coupling.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Maintainability:&lt;/strong&gt; clear responsibilities make testing and refactoring easier.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Scalability:&lt;/strong&gt; well-defined package boundaries support growth in complexity and team size.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="package-responsibilities"&gt;Package responsibilities&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Live in one place per domain, such as &lt;code&gt;internal/user&lt;/code&gt; or &lt;code&gt;internal/platform&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Provide a specific solution and avoid generic buckets like &lt;code&gt;common&lt;/code&gt; or &lt;code&gt;util&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Export only the API needed by consumers and keep implementation details private.&lt;/li&gt;&#10;&lt;li&gt;Name files to reflect behaviour so callers understand what the package delivers.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="layering-cheat-sheet"&gt;Layering cheat-sheet&lt;/h2&gt;&#10;&lt;h3 id="kit"&gt;&lt;code&gt;kit&lt;/code&gt;&lt;/h3&gt;&#10;&lt;p&gt;Shared libraries with zero dependency on application packages.&lt;/p&gt;</description></item><item><title>Conway’s Law — origins, literature, and team design</title><link>https://osmarpetry.dev/blog/conways-law-birth-1968/</link><pubDate>Tue, 15 Apr 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/conways-law-birth-1968/</guid><description>&lt;h2 id="reference-stack"&gt;Reference stack&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Melvin Conway, “How Do Committees Invent?” (1968).&lt;/li&gt;&#10;&lt;li&gt;Thoughtworks, “Applying Conway’s Law to Improve Your Software Development.”&lt;/li&gt;&#10;&lt;li&gt;M. Soldani et al., “A Decade of Conway’s Law: A Literature Review 2003–2012” (IEEE).&lt;/li&gt;&#10;&lt;li&gt;Video summary: &lt;a href="https://youtu.be/SWrlFod8t5g" target="_blank" rel="noreferrer"&gt;https://youtu.be/SWrlFod8t5g&lt;/a&gt;.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="essence-of-the-law"&gt;Essence of the law&lt;/h2&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;“Any organization that designs a system will produce a design whose structure is a copy of the organization’s communication structure.”&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Architecture mirrors team communication pathways; siloed teams create siloed modules, joined at fragile seams.&lt;/li&gt;&#10;&lt;li&gt;“Monolithic teams do not build microservices”—system modularity depends on cross-team autonomy and shared vocabulary.&lt;/li&gt;&#10;&lt;li&gt;Neglecting communication design results in accidental system design, rather than deliberate architecture.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="historical-context--popularization"&gt;Historical context &amp;amp; popularization&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Conway observed the phenomenon across software, military, and governmental projects in the 1960s.&lt;/li&gt;&#10;&lt;li&gt;Frederick Brooks amplified the idea in &lt;em&gt;The Mythical Man-Month&lt;/em&gt;, cementing “Conway’s Law” in software folklore.&lt;/li&gt;&#10;&lt;li&gt;Later research confirms that org charts and interface diagrams often align, sometimes unintentionally.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="key-takeaways-from-the-literature-review"&gt;Key takeaways from the literature review&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Larger organizations introduce communication friction, leading to complex, tightly coupled systems.&lt;/li&gt;&#10;&lt;li&gt;Parkinson’s Law: management layers tend to expand, exacerbating coordination overhead.&lt;/li&gt;&#10;&lt;li&gt;Small, autonomous teams (“two-pizza teams”) correlate with cleaner, more modular architecture.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="review-questions"&gt;Review questions&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;How does organizational structure influence the resulting system design?&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Systems reflect the communication patterns of their creators; poor cross-team collaboration manifests as brittle interfaces.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;ol start="2"&gt;&#10;&lt;li&gt;How does company size impact system complexity?&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;As organizations grow, coordination paths lengthen, producing sprawling systems with integration pain; keeping teams small mitigates the effect.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="practical-implications"&gt;Practical implications&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Design teams around the architecture you want (the “inverse Conway maneuver”): align squads to bounded contexts before writing code.&lt;/li&gt;&#10;&lt;li&gt;Optimize for communication density: co-locate domains, create shared rituals, and collapse unnecessary hierarchy.&lt;/li&gt;&#10;&lt;li&gt;When introducing API gateways or platform teams, ensure their communication network matches the required integrations.&lt;/li&gt;&#10;&lt;li&gt;Regularly map org structures to architecture diagrams; adjust teams when misalignment appears.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="next-actions"&gt;Next actions&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Compare current team topology with service/module boundaries; plan reorg if misalignment exists.&lt;/li&gt;&#10;&lt;li&gt;Share the original essay and Thoughtworks article with engineering leadership to ground discussions in historical context.&lt;/li&gt;&#10;&lt;li&gt;Incorporate Conway’s Law checkpoints into architecture reviews (e.g., “Does a team own each interface?”).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[DbC|Design by Contract]]&lt;/li&gt;&#10;&lt;li&gt;[[no-silver-bullet-1986|No Silver Bullet — Essence &amp;amp; Accidents]]&lt;/li&gt;&#10;&lt;li&gt;[[parnas-modularization-1972|Modularization Criteria — Parnas 1972]]&lt;/li&gt;&#10;&lt;li&gt;[[software-aging-1994|Software Aging]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Design by Contract (DbC)</title><link>https://osmarpetry.dev/blog/dbc/</link><pubDate>Tue, 15 Apr 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/dbc/</guid><description>&lt;h2 id="abstract"&gt;Abstract&lt;/h2&gt;&#10;&lt;p&gt;Bertrand Meyer introduced Design by Contract (DbC) to formalise expectations between software components. Contracts specify obligations and benefits for clients and suppliers via preconditions, postconditions, and invariants, enabling safer, more maintainable systems.&lt;/p&gt;&#10;&lt;h2 id="key-points"&gt;Key points&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Contracts&lt;/strong&gt;: Define preconditions (caller responsibilities), postconditions (supplier guarantees), invariants (state consistency).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Runtime checks&lt;/strong&gt;: Contracts can be enforced during development/testing to catch violations early.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Documentation&lt;/strong&gt;: Contracts serve as precise specs and executable documentation.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Encapsulation&lt;/strong&gt;: Components hide implementation details while exposing contractual behaviour.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Reuse &amp;amp; reliability&lt;/strong&gt;: DbC encourages reusable components with clear expectations.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="connections"&gt;Connections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Basis for Eiffel language features; influences modern assertion frameworks.&lt;/li&gt;&#10;&lt;li&gt;Complements unit testing and TDD by clarifying expected behaviour.&lt;/li&gt;&#10;&lt;li&gt;Aligns with API design best practices and microservice contracts.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="questions"&gt;Questions&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;How to balance DbC runtime checks with performance constraints?&lt;/li&gt;&#10;&lt;li&gt;How to integrate DbC in languages without native support?&lt;/li&gt;&#10;&lt;li&gt;When should contracts be relaxed or extended as systems evolve?&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="personal-reflections"&gt;Personal reflections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Contracts clarify team communication and reduce misunderstandings.&lt;/li&gt;&#10;&lt;li&gt;Useful for critical systems where correctness outweighs overhead.&lt;/li&gt;&#10;&lt;li&gt;Combining DbC with automated tests and CI improves confidence in deployments.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Meyer, B. (1992). &lt;em&gt;Applying &amp;ldquo;Design by Contract&amp;rdquo;&lt;/em&gt;. Computer, 25(10), 40-51.&lt;/li&gt;&#10;&lt;li&gt;Official Eiffel documentation on DbC.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[conways-law-birth-1968|Conway’s Law — origins, literature, and team design]]&lt;/li&gt;&#10;&lt;li&gt;[[design-patterns|Design Pattern]]&lt;/li&gt;&#10;&lt;li&gt;[[ddd|Domain-Driven Design: Tackling Complexity in the Heart of Software]]&lt;/li&gt;&#10;&lt;li&gt;[[no-silver-bullet-1986|No Silver Bullet — Essence &amp;amp; Accidents]]&lt;/li&gt;&#10;&lt;li&gt;[[parnas-modularization-1972|Modularization Criteria — Parnas 1972]]&lt;/li&gt;&#10;&lt;li&gt;[[shape-up-2020|Shape Up: Stop Running in Circles and Ship Work that Matters]]&lt;/li&gt;&#10;&lt;li&gt;[[software-aging-1994|Software Aging]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Modularization Criteria — Parnas 1972</title><link>https://osmarpetry.dev/blog/parnas-modularization-1972/</link><pubDate>Tue, 15 Apr 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/parnas-modularization-1972/</guid><description>&lt;h2 id="abstract"&gt;Abstract&lt;/h2&gt;&#10;&lt;p&gt;David L. Parnas (1972) proposed information hiding as the primary criterion for modular design, using the KWIC (Key Word In Context) system to compare traditional flow-based modularization vs encapsulating design decisions. His approach yields systems that are easier to modify, maintain, and evolve.&lt;/p&gt;&#10;&lt;h2 id="key-points"&gt;Key points&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Traditional modularization (aligned with processing steps) leads to high coupling and brittle systems.&lt;/li&gt;&#10;&lt;li&gt;Information hiding: modules encapsulate design decisions (data structures, algorithms, storage formats).&lt;/li&gt;&#10;&lt;li&gt;KWIC case study: conventional design (5 modules aligned with processing sequence) vs information-hiding design (4 modules for storage, circular shift generation, sorting, output).&lt;/li&gt;&#10;&lt;li&gt;Benefits: localized changes, clear responsibilities, replaceable internals without breaking clients.&lt;/li&gt;&#10;&lt;li&gt;Trade-off: potential performance overhead due to inter-module communication; can be mitigated via inlining and efficient call mechanisms.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="connections"&gt;Connections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Precursor to object-oriented encapsulation and modern modular design.&lt;/li&gt;&#10;&lt;li&gt;Supports microservices and DDD bounded context thinking.&lt;/li&gt;&#10;&lt;li&gt;Relates to clean architecture and low coupling principles.&lt;/li&gt;&#10;&lt;li&gt;Anticipates interface contracts in modern API design.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="questions"&gt;Questions&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;How to apply information hiding in fast-paced agile projects?&lt;/li&gt;&#10;&lt;li&gt;Which metrics can quantify effective information hiding?&lt;/li&gt;&#10;&lt;li&gt;How to balance encapsulation with performance in real-time systems?&lt;/li&gt;&#10;&lt;li&gt;Applicability to distributed architectures?&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="personal-reflections"&gt;Personal reflections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Encapsulating design decisions prevents leakage of implementation details across layers.&lt;/li&gt;&#10;&lt;li&gt;KWIC example illustrates how storage strategies can remain swappable with proper abstraction.&lt;/li&gt;&#10;&lt;li&gt;Critique of flow-based modularization still relevant for ETL/data pipeline architectures.&lt;/li&gt;&#10;&lt;li&gt;Stable interfaces support DevOps pipelines and isolate testing concerns.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Parnas, D. L. (1972). &lt;em&gt;On the Criteria To Be Used in Decomposing Systems into Modules&lt;/em&gt;. Communications of the ACM, 15(12), 1053-1058.&lt;/li&gt;&#10;&lt;li&gt;Modern commentary: &lt;a href="https://www.refact0r.dev/blog/module-criteria" target="_blank" rel="noreferrer"&gt;https://www.refact0r.dev/blog/module-criteria&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[conways-law-birth-1968|Conway’s Law — origins, literature, and team design]]&lt;/li&gt;&#10;&lt;li&gt;[[DbC|Design by Contract]]&lt;/li&gt;&#10;&lt;li&gt;[[no-silver-bullet-1986|No Silver Bullet — Essence &amp;amp; Accidents]]&lt;/li&gt;&#10;&lt;li&gt;[[software-aging-1994|Software Aging]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>No Silver Bullet — Essence &amp; Accidents</title><link>https://osmarpetry.dev/blog/no-silver-bullet-1986/</link><pubDate>Tue, 15 Apr 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/no-silver-bullet-1986/</guid><description>&lt;h2 id="abstract"&gt;Abstract&lt;/h2&gt;&#10;&lt;p&gt;Frederick P. Brooks Jr. (1986) argues there’s no single “silver bullet” that will provide an order-of-magnitude productivity boost in software engineering. Distinguishes &lt;strong&gt;essential&lt;/strong&gt; difficulties (intrinsic to software) from &lt;strong&gt;accidental&lt;/strong&gt; difficulties (tooling, implementation). Technological advances continue to chip away at accidental issues, but inherent complexity remains.&lt;/p&gt;&#10;&lt;h2 id="key-points"&gt;Key points&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Essence vs accidents&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;Essential: inherent complexity, changing requirements, invisibility, costly change.&lt;/li&gt;&#10;&lt;li&gt;Accidental: tooling limitations (manual compilation, lack of IDEs) that technology can mitigate.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Central thesis&lt;/strong&gt;: innovations (OO, AI, higher-level languages) alone won’t deliver 10x productivity across the board.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Potential breakthroughs&lt;/strong&gt;: rapid prototyping, incremental development, empowering great designers.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Critique of techno-optimism&lt;/strong&gt;: automating accidental tasks doesn’t fix mis-specified requirements or poor communication.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="connections"&gt;Connections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Relates to discussions on technical debt (unmanaged accidental complexity).&lt;/li&gt;&#10;&lt;li&gt;Anticipates agile principles (short iterations, prototyping).&lt;/li&gt;&#10;&lt;li&gt;Aligns with critiques of low-code/no-code as silver bullets.&lt;/li&gt;&#10;&lt;li&gt;Connects to cognitive complexity in distributed systems.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="questions"&gt;Questions&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Where do modern frameworks (React, Kubernetes) fall in essence vs accidents?&lt;/li&gt;&#10;&lt;li&gt;Does generative AI (Copilot) confirm or challenge Brooks’ predictions?&lt;/li&gt;&#10;&lt;li&gt;Has cloud computing reduced essential complexity or just moved it around?&lt;/li&gt;&#10;&lt;li&gt;Do DORA metrics (deployment frequency, etc.) mostly track accidental difficulties?&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="personal-reflections"&gt;Personal reflections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Essential/accidental distinction explains why microservices fix operational issues but add systemic complexity.&lt;/li&gt;&#10;&lt;li&gt;Emphasising “great designers” foreshadows Site Reliability Engineering and other multiplier roles.&lt;/li&gt;&#10;&lt;li&gt;Invisibility still critical in distributed architectures; justifies heavy investment in observability.&lt;/li&gt;&#10;&lt;li&gt;Incremental evolution (“UNIX philosophy”) continues to beat grand revolutions.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="detailed-notes"&gt;Detailed notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Essential difficulties: complexity, conformity, invisibility, cost of change.&lt;/li&gt;&#10;&lt;li&gt;Accidental wins: high-level languages, IDEs, CI/CD automation.&lt;/li&gt;&#10;&lt;li&gt;Suggested strategies: buy vs build, rapid prototyping, nurture expert designers.&lt;/li&gt;&#10;&lt;li&gt;Predictions validated: OOP aided encapsulation but didn’t eliminate logic bugs; open source helped with accidental costs, not conflicting requirements.&lt;/li&gt;&#10;&lt;li&gt;Quote: “Complexity is the soul of software; there is no silver bullet.”&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Brooks, F. P. Jr. (1986). &lt;em&gt;No Silver Bullet: Essence and Accidents of Software Engineering&lt;/em&gt;. (Link: &lt;a href="http://www.cs.unc.edu/techreports/86-020.pdf" target="_blank" rel="noreferrer"&gt;http://www.cs.unc.edu/techreports/86-020.pdf&lt;/a&gt;)&lt;/li&gt;&#10;&lt;li&gt;Additional commentary and analyses (ACM DL, Wikipedia, etc.).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[conways-law-birth-1968|Conway’s Law — origins, literature, and team design]]&lt;/li&gt;&#10;&lt;li&gt;[[DbC|Design by Contract]]&lt;/li&gt;&#10;&lt;li&gt;[[parnas-modularization-1972|Modularization Criteria — Parnas 1972]]&lt;/li&gt;&#10;&lt;li&gt;[[shape-up-2020|Shape Up: Stop Running in Circles and Ship Work that Matters]]&lt;/li&gt;&#10;&lt;li&gt;[[software-aging-1994|Software Aging]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Software Aging</title><link>https://osmarpetry.dev/blog/software-aging-1994/</link><pubDate>Tue, 15 Apr 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/software-aging-1994/</guid><description>&lt;h2 id="abstract"&gt;Abstract&lt;/h2&gt;&#10;&lt;p&gt;David L. Parnas likens software aging to biological aging: over time, software becomes harder to maintain, less efficient, and more failure-prone. Maturity in software engineering requires prioritizing long-term health over first releases. Preventive practices can slow aging but cannot eliminate it.&lt;/p&gt;&#10;&lt;h2 id="key-points"&gt;Key points&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Software aging is inevitable but manageable through disciplined engineering.&lt;/li&gt;&#10;&lt;li&gt;Two main accelerants:&lt;/li&gt;&#10;&lt;li&gt;Inability to update software as business needs change.&lt;/li&gt;&#10;&lt;li&gt;Accumulation of ignorance due to team turnover and poor documentation.&lt;/li&gt;&#10;&lt;li&gt;Aging costs: lost competitiveness, increased defects, degraded performance, higher maintenance effort.&lt;/li&gt;&#10;&lt;li&gt;Preventive “medicine”: design for change, thorough documentation, frequent code reviews.&lt;/li&gt;&#10;&lt;li&gt;Critiques the focus on initial releases and lack of systematic engineering practices.&lt;/li&gt;&#10;&lt;li&gt;Documentation is essential despite agile tendencies to downplay it.&lt;/li&gt;&#10;&lt;li&gt;Suggests planning for software “retirement” as part of lifecycle management.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="connections"&gt;Connections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Links to discussions of technical debt and legacy systems.&lt;/li&gt;&#10;&lt;li&gt;Resonates with sustainability narratives and maintaining long-lived open source projects.&lt;/li&gt;&#10;&lt;li&gt;Contrasts with agile manifesto statements about documentation.&lt;/li&gt;&#10;&lt;li&gt;Aligns with DevOps practices emphasizing observability and continuous improvement.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="questions"&gt;Questions&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;How to objectively measure software aging across domains?&lt;/li&gt;&#10;&lt;li&gt;Which documentation practices balance agility with sustainable knowledge?&lt;/li&gt;&#10;&lt;li&gt;How to adapt recommendations for small teams or short-lived projects?&lt;/li&gt;&#10;&lt;li&gt;Differences in aging patterns between proprietary and open source software?&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="personal-reflections"&gt;Personal reflections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Aging metaphor helps analyze system trajectories, especially with high team turnover.&lt;/li&gt;&#10;&lt;li&gt;Highlights challenges seen in both public and private IT projects lacking systematic processes.&lt;/li&gt;&#10;&lt;li&gt;“Retirement plan” concept is valuable for interviewing IT managers.&lt;/li&gt;&#10;&lt;li&gt;Reinforces importance of documentation and review in case studies.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="detailed-notes"&gt;Detailed notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Aging compared to humans: inevitable but mitigable via prevention and care.&lt;/li&gt;&#10;&lt;li&gt;Focus should shift to system health over first release success.&lt;/li&gt;&#10;&lt;li&gt;Aging factors recorded from various talks (timestamps included in original note).&lt;/li&gt;&#10;&lt;li&gt;Emphasis on design for change, documentation, code reviews.&lt;/li&gt;&#10;&lt;li&gt;Recognize when software becomes unreliable; apply re-modularization and documentation retrofits.&lt;/li&gt;&#10;&lt;li&gt;Plan for end-of-support lifecycle as part of responsible engineering.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Parnas, D. L. (1994). &lt;em&gt;Software Aging&lt;/em&gt;. Proceedings of ICSE 16.&lt;/li&gt;&#10;&lt;li&gt;Article PDF: &lt;a href="http://www.inf.ed.ac.uk/teaching/courses/seoc/2004_2005/resources/bullet11.pdf" target="_blank" rel="noreferrer"&gt;http://www.inf.ed.ac.uk/teaching/courses/seoc/2004_2005/resources/bullet11.pdf&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;Talk: &lt;a href="https://youtu.be/fe8Mp1YOjQI" target="_blank" rel="noreferrer"&gt;https://youtu.be/fe8Mp1YOjQI&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[conways-law-birth-1968|Conway’s Law — origins, literature, and team design]]&lt;/li&gt;&#10;&lt;li&gt;[[DbC|Design by Contract]]&lt;/li&gt;&#10;&lt;li&gt;[[no-silver-bullet-1986|No Silver Bullet — Essence &amp;amp; Accidents]]&lt;/li&gt;&#10;&lt;li&gt;[[parnas-modularization-1972|Modularization Criteria — Parnas 1972]]&lt;/li&gt;&#10;&lt;li&gt;[[shape-up-2020|Shape Up: Stop Running in Circles and Ship Work that Matters]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>TDD Effects on Quality and Productivity</title><link>https://osmarpetry.dev/blog/tdd-systematic-review-2016/</link><pubDate>Tue, 15 Apr 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/tdd-systematic-review-2016/</guid><description>&lt;h2 id="abstract"&gt;Abstract&lt;/h2&gt;&#10;&lt;p&gt;Systematic review of 27 empirical studies (1999–2014) on Test-Driven Development (TDD). Evaluates internal code quality, external product quality, and productivity. Findings: TDD generally improves cohesion and reduces coupling; external quality gains are observed in 88% of cases; productivity results vary, showing improvements in academic settings but a decrease in industrial environments.&lt;/p&gt;&#10;&lt;h2 id="key-points"&gt;Key points&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Internal quality:&lt;/strong&gt; Improves in 76% of evaluated cases, showing lower coupling, reduced cyclomatic complexity, and higher cohesion (often measured via CK Metrics).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;External quality:&lt;/strong&gt; Positive impact in 88% of the scenarios, with significant defect reduction in critical systems.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Productivity:&lt;/strong&gt; Mixed outcomes. Academic environments reported speed gains, while industrial settings reported a productivity dip.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Moderators:&lt;/strong&gt; Prior unit testing experience and continuous integration adoption amplify benefits.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Limitations:&lt;/strong&gt; Selection bias, uncontrolled environmental variables, self-reported productivity metrics.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="connections"&gt;Connections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Aligns with Clean Code principles and CK metrics usage.&lt;/li&gt;&#10;&lt;li&gt;Supports discussions on technical debt in agile processes.&lt;/li&gt;&#10;&lt;li&gt;Contrasts with test-last approaches in rapid prototyping.&lt;/li&gt;&#10;&lt;li&gt;Relates to research on developer psychology and TDD adoption.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="questions"&gt;Questions&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;How to tailor TDD for volatile requirements?&lt;/li&gt;&#10;&lt;li&gt;What is the maintenance cost of large test suites over time?&lt;/li&gt;&#10;&lt;li&gt;Are metrics like branch coverage sufficient to gauge TDD effectiveness?&lt;/li&gt;&#10;&lt;li&gt;How does TDD coexist with generative AI in testing workflows?&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="personal-reflections"&gt;Personal reflections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;TDD excels for complex business logic; less so for simple CRUD modules.&lt;/li&gt;&#10;&lt;li&gt;CK metrics help quantify internal quality gains.&lt;/li&gt;&#10;&lt;li&gt;Variability explains why some companies abandon TDD after superficial adoption.&lt;/li&gt;&#10;&lt;li&gt;Integrating TDD with BDD could boost external quality.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="detailed-notes"&gt;Detailed notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Methodology:&lt;/strong&gt; PRISMA-based review of 27 empirical studies.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Variables:&lt;/strong&gt; Internal quality (CBO, LCOM, WMC, RFC), external quality (defects, MTBF, user satisfaction), productivity (delivery speed, cognitive effort).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Results:&lt;/strong&gt; 76% of cases showed increased internal quality (coupling reduction, ~20% cohesion increase, lower cyclomatic complexity); 88% showed increased external quality (defect reduction); proficiency reached after initial productivity dip, mostly observed in academic scenarios.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Limitations:&lt;/strong&gt; Many studies lacked controls for prior testing expertise; productivity data often self-reported; publication bias toward positive outcomes.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="example-in-go"&gt;Example in Go&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;testing&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;TestCPFRejectsAllZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;testing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;IsValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;00000000000&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;All-zero CPF should be invalid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;TestCPFValidKnownValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;testing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;IsValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;52998224725&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Valid CPF was rejected&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;IsValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Simplified logic for example&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Bissi, W., Seca Neto, A. G. S., &amp;amp; Emer, M. C. F. P. (2016). The effects of test driven development on internal quality, external quality and productivity: A systematic review. &lt;em&gt;Information and Software Technology&lt;/em&gt;. &lt;a href="https://www.sciencedirect.com/science/article/abs/pii/S0950584916300222" target="_blank" rel="noreferrer"&gt;https://www.sciencedirect.com/science/article/abs/pii/S0950584916300222&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;Additional supporting documents (ResearchGate, CK Metrics literature).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;span&#10; class="post-inline-link--missing"&#10; aria-label="Gophers Workshop — Deploy-First Go Architecture. Page does not exist."&#10; title="Page does not exist."&#10; data-tooltip-message="Page does not exist."&#10; &gt;Gophers Workshop — Deploy-First Go Architecture&lt;/span&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;span&#10; class="post-inline-link--missing"&#10; aria-label="Design &amp;amp;amp; Analysis of Algorithms — Course Overview. Page does not exist."&#10; title="Page does not exist."&#10; data-tooltip-message="Page does not exist."&#10; &gt;Design &amp;amp; Analysis of Algorithms — Course Overview&lt;/span&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;span&#10; class="post-inline-link--missing"&#10; aria-label="Assembly Study Plan. Page does not exist."&#10; title="Page does not exist."&#10; data-tooltip-message="Page does not exist."&#10; &gt;Assembly Study Plan&lt;/span&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a class="post-inline-link" href="https://osmarpetry.dev/blog/bdd/"&gt;BDD&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;span&#10; class="post-inline-link--missing"&#10; aria-label="Code Smells and Maintainability. Page does not exist."&#10; title="Page does not exist."&#10; data-tooltip-message="Page does not exist."&#10; &gt;Code Smells and Maintainability&lt;/span&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;span&#10; class="post-inline-link--missing"&#10; aria-label="Enterprise UI Development — Testing, Standards, and Ego Control. Page does not exist."&#10; title="Page does not exist."&#10; data-tooltip-message="Page does not exist."&#10; &gt;Enterprise UI Development — Testing, Standards, and Ego Control&lt;/span&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a class="post-inline-link" href="https://osmarpetry.dev/blog/testing-concepts-notes/"&gt;Testing Concepts Notes&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>ADR — Architecture Decision Records</title><link>https://osmarpetry.dev/blog/adr/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/adr/</guid><description>&lt;p&gt;ADRs (Architecture Decision Records) are essential documents in software engineering that capture important architectural choices and the context behind them. In an Obsidian vault, ADRs integrate naturally into project documentation.&lt;/p&gt;&#10;&lt;h2 id="why-use-adrs"&gt;Why use ADRs?&lt;/h2&gt;&#10;&lt;p&gt;In long-running projects — such as framework migrations or service changes in Go or Java — decisions change constantly. Without recording &lt;em&gt;why&lt;/em&gt; a tool was chosen over another, the team (or even yourself) may forget the reasoning months later, losing the context that justified the choice.&lt;/p&gt;</description></item><item><title>Design Patterns</title><link>https://osmarpetry.dev/blog/design-patterns/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/design-patterns/</guid><description>&lt;h2 id="presentation-intent"&gt;Presentation Intent&lt;/h2&gt;&#10;&lt;p&gt;Prepare the presentation with a clear script of intentions.&lt;/p&gt;&#10;&lt;p&gt;Explain how to read the book and how, by recognizing similar patterns, you create connections between them and discover different perspectives on the same problem. In some cases, this leads to other ways—or better ways—to apply a different pattern.&lt;/p&gt;&#10;&lt;p&gt;Another pattern can sometimes feel very similar to the one you are reading. The point is to think beyond the current chapter and compare intent, structure, and trade-offs.&lt;/p&gt;</description></item><item><title>Domain-Driven Design: Tackling Complexity in the Heart of Software</title><link>https://osmarpetry.dev/blog/ddd/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/ddd/</guid><description>&lt;p&gt;Domain-Driven Design (DDD) is a software design approach that focuses on modeling complex systems based on the real-world domains or concepts they represent. The aim is to tackle complexity in the heart of software by aligning the development process with the business domain, using a common language, and creating models that capture the behavior and relationships of the system. DDD emphasizes the importance of designing software around the concepts and processes of the business domain, rather than just technical implementation. It encourages communication and collaboration between the development team and business stakeholders, and promotes the use of models as the primary driver for design decisions. The end result is a software solution that better reflects the needs and requirements of the business domain, and is more maintainable, scalable and adaptable over time.&lt;/p&gt;</description></item><item><title>Shape Up: Stop Running in Circles and Ship Work that Matters</title><link>https://osmarpetry.dev/blog/shape-up-2020/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/shape-up-2020/</guid><description>&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;&#10;&lt;p&gt;In December 2020 I read several books and papers: &lt;strong&gt;The Mythical Man-Month&lt;/strong&gt;, &lt;strong&gt;Design by Contract&lt;/strong&gt;, &lt;strong&gt;Programming with Abstract Data Types&lt;/strong&gt;, &lt;strong&gt;Shape Up&lt;/strong&gt;, and &lt;strong&gt;Domain-Driven Design&lt;/strong&gt;. Their ideas map directly to problems and solutions I encountered building apps in recent years.&#10;The largest recurring gap in real projects is the &lt;strong&gt;beginning&lt;/strong&gt;—how we &lt;strong&gt;shape&lt;/strong&gt; and refine the work—more than the middle or the end. &lt;strong&gt;Shape Up&lt;/strong&gt; gives a concrete way to close that gap in modern teams.&lt;/p&gt;</description></item></channel></rss>