Package by component groups related business and data-access logic behind a component’s public interface, while architecturally aligned testing chooses test boundaries that reflect how the software is built and used. The two ideas reinforce each other: consumers depend on component contracts, and tests exercise those contracts at the boundary where they matter. They are design options, not universal rules; their fit depends on the codebase’s responsibilities and dependencies.
What package by component means
Package by component is a hybrid between organizing code by technical layer and organizing it by feature. Each component represents a cohesive domain concept or bounded context. Business behavior and its related data-access code live behind a public interface, while presentation remains a separate concern. Other parts of the application use the interface rather than reaching into the component’s implementation.
Simon Brown’s April 4, 2015 article describes this arrangement as a way to make architectural components visible in the code. In Java, access controls can help enforce the separation. That is design rationale, not a measured guarantee that a particular package layout improves a system.
How it differs from package by layer or feature
| Organization | Primary grouping | Typical boundary |
|---|---|---|
| Package by layer | Technical role across the application | Related controllers, services, or data-access classes are grouped by role. |
| Package by feature | Feature-specific code | Classes from multiple technical layers for a feature are kept together. |
| Package by component | Cohesive domain component | Business and data-access behavior sit behind a component interface, with presentation kept separate. |
Package by feature can make feature-specific code easier to find and maintain together. Package by component can make a component easier to reuse across controllers. Either can feel artificial if the application has no natural boundaries. A contemporaneous critique by Claysnow argues for judging organization by cohesion and loose coupling rather than treating a packaging style as dogma.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Choose test boundaries that match the behavior
Brown cautions against relying on labels such as “unit test” and “integration test” alone: teams use those terms for different-sized tests. Instead, decide what behavior needs protection and choose a boundary that exercises it clearly.
Test suitable classes in isolation
Domain classes, utilities, and other classes can be tested alone when isolation provides a useful, focused check. Isolation is not an end in itself; a test should still cover the behavior the team intends to protect.
Test component behavior through its interface
When the component’s public behavior is the contract, exercise it through that interface. Brown gives the example of a component backed by MySQL tested from its interface through to the database. This verifies the production interaction across that boundary rather than testing only internal implementation details.
Control external dependencies where needed
A component that sends asynchronous messages or calls a third-party service may need a controlled seam to test its behavior adequately. Brown points to dependency-injection points such as ports and adapters as options. Introduce them where they help isolate an external interaction; unnecessary indirection can make the design harder to understand.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCover service behavior and whole-system scenarios
For service-oriented systems, Brown describes a range of checks: low-level class tests, service tests through public interfaces, and end-to-end scenarios across the system. Use the level that captures the interaction at risk; a component-interface test does not, by itself, establish that every cross-component workflow behaves correctly.
A practical way to evaluate the approach
Before reorganizing packages or adding new test seams, make the intended boundaries explicit. Structurizr’s component-modelling guide recommends identifying the architectural style already present and using a sketch or class diagram as a starting point for a component diagram.
Rank #4
- Identify cohesive responsibilities. Sketch the domain concepts or bounded contexts and check whether each proposed component has a clear, related purpose.
- Define the public boundary. List what consumers need to do and expose that behavior through the component interface. Avoid direct dependencies on internal classes or data-access details.
- Map tests to production interactions. For each behavior to protect, decide whether an isolated class test, a component-interface test, or an end-to-end scenario gives the clearest useful coverage.
- Inspect external dependencies. Decide how database, messaging, or third-party interactions will be exercised or controlled. Add injection points only where they serve a concrete testing or design need.
- Pilot and review. Compare how easily developers find code, whether responsibilities remain cohesive, how much consumers depend on internals, and the runtime and maintenance cost of tests. These are evaluation criteria, not published scores or benchmark results.
What the approach does—and does not—establish
The architectural aim is to make component boundaries visible, keep implementation details behind interfaces, and align tests with the system’s actual boundaries. Brown and the contemporaneous critique offer qualitative design arguments; they do not provide comparative benchmark data showing that package by component or architecturally aligned testing is faster, cheaper, or better for every codebase. The right arrangement depends on whether the boundaries are cohesive, usable by consumers, and practical to test.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Further reading
InformIT’s publisher listing for Robert C. Martin’s Clean Architecture: A Craftsman’s Guide to Software Structure and Design includes a chapter titled “Package by Component,” along with chapters on the test boundary and design for testability. It offers a related treatment of the concepts.
Quick Recap
Best Value
- Simon Brown, “Package by Component and Architecturally-aligned Testing,” DZone, April 4, 2015
- Claysnow’s contemporaneous critique, March 19, 2015
- Structurizr’s component-modelling guide
- InformIT publisher listing for Clean Architecture
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

