skip to content

Package and Component Principles

Once classes are grouped into releasable components, a second set of principles decides what belongs together and which way component dependencies may point. This is where interviewers move from class design to module and build-graph design.

part ofSoftware design & architectureoverview, primer and where to startread it →
on this pageshow

questions

page 2 of 2

How do the Stable Dependencies Principle and the Stable Abstractions Principle combine into the "main sequence", and what do the Zone of Pain and Zone of Uselessness mean?

level: seniorimportance: should knowfreq 24%

basics

~20 s

SDP says depend toward stability; SAP says stable components should be abstract. Plot abstractness A against instability I: healthy components sit near the line A + I = 1 (the main sequence). Concrete-and-stable is the Zone of Pain; abstract-and-unstable is the Zone of Uselessness.

open as a page

How does the Common Closure Principle apply when the components are independently deployable services rather than packages, and what does a violation look like at that scale?

level: principalimportance: should knowfreq 28%

basics

~20 s

The rule is the same but the cost is much higher: if one business change forces you to edit and release several services in lockstep, CCP is violated. That is a distributed monolith - the split followed technical or data lines, not business change.

open as a page

How do the Common Closure Principle, the Single Responsibility Principle, and the Open-Closed Principle relate to each other?

level: middleimportance: nice to knowfreq 18%

basics

~20 s

SRP: a class has one reason to change. CCP is the same idea for components: a component has one reason to change. OCP says prefer extending over modifying; where you can't, CCP keeps the unavoidable modification inside one component.

open as a page

Is ADP an absolute rule? Discuss when breaking a component cycle costs more than it saves, and how cycles manifest — and are broken — at service granularity in a distributed system.

level: principalimportance: nice to knowfreq 22%

basics

~20 s

ADP is a strong default, not a law. Breaking a cycle costs indirection, extra components, or a merge — sometimes not worth it for two tiny modules that always ship together. But at service granularity cycles are far more dangerous: they force lockstep deploys and risk cascading failure, so there the rule is close to absolute.

open as a page

Modern tooling can strip unused code from a shipped artifact — tree shaking and dead-code elimination in bundlers, fine-grained build targets in systems like Bazel, and module descriptors in JPMS or OSGi. Does that make the Common Reuse Principle obsolete?

level: principalimportance: nice to knowfreq 14%

basics

~20 s

No. Those tools remove unused bytes, but the Common Reuse Principle is mostly about coupling to another component's release cycle, versioning and dependency closure — none of which tree shaking touches. It reduces one symptom, not the cause.

open as a page

What are the limitations of using distance from the main sequence (D = |A + I − 1|) as an architectural health metric, and how would you govern it responsibly across a large codebase?

level: principalimportance: nice to knowfreq 12%

basics

~20 s

D only measures the balance between abstractness and how depended-upon a component is. It ignores volatility, cohesion, cycles, and whether abstractions are really used. Use it to rank and to watch trends, never as a hard pass/fail target.

open as a page

You are defining the release strategy for an organisation's internal shared components. What policies and mechanisms make the Reuse/Release Equivalence Principle (REP) actually hold at scale, and when would you deliberately not release a reusable piece of code?

level: principalimportance: nice to knowfreq 14%

basics

~20 s

Give each component an owner, a charter, an immutable versioned artifact in a registry, a semver policy over a declared public API, per-release notes, and a deprecation/support window. Skip releasing code that has no cross-boundary consumer or is still churning heavily.

open as a page

You compute abstractness (A), instability (I), and distance from the Main Sequence (D) for every module in a large system and find several modules deep in the Zone of Pain. How would you decide what — if anything — to act on, and would you enforce these metrics in CI?

level: principalimportance: nice to knowfreq 18%

basics

~20 s

Don't act on the metric alone. Cross-reference with how often each module actually changes; a stable concrete module that never changes is harmless. Fix the ones that are widely depended on, concrete, and churning. Enforce dependency direction in CI, not metric thresholds.

open as a page

What are the limits of the Stable Dependencies Principle and its instability metric at scale, and how would you enforce dependency direction across many teams without turning the metric into a target?

level: principalimportance: nice to knowfreq 12%

basics

~20 s

I depends entirely on how you carve components, counts every edge equally, and ignores volatility, cycles and runtime coupling. So enforce direction with explicit allowed-dependency rules in the build, and keep I as a review signal you never grade teams on.

open as a page

showing 31–39 of 39