Strategic architecture, tactical design, and testable code principles (SOLID, Clean Architecture, Design Patterns, Testable Design)
97
97%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Passed
No known issues
Use automated tests to enforce that dependency rules are followed. Architecture tests catch violations before they become entrenched patterns.
Incorrect (no boundary verification):
// Over time, developers add shortcuts
// domain/Order.java
import org.springframework.stereotype.Component; // Framework in domain!
import javax.persistence.Entity; // JPA in domain!
// application/CreateOrderUseCase.java
import com.stripe.Stripe; // Direct payment vendor dependency!
import infrastructure.email.SendGridClient; // Infrastructure in application!
// No tests catch these violations
// They accumulate until refactoring becomes impossibleCorrect (architecture tests enforce boundaries):
// Using ArchUnit (Java) or similar tools
@AnalyzeClasses(packages = "com.myapp")
class ArchitectureTest {
@ArchTest
static final ArchRule domain_should_not_depend_on_infrastructure =
noClasses()
.that().resideInAPackage("..domain..")
.should().dependOnClassesThat()
.resideInAPackage("..infrastructure..");
@ArchTest
static final ArchRule domain_should_not_use_frameworks =
noClasses()
.that().resideInAPackage("..domain..")
.should().dependOnClassesThat()
.resideInAnyPackage(
"org.springframework..",
"javax.persistence..",
"jakarta.persistence.."
);
@ArchTest
static final ArchRule usecases_should_not_access_controllers =
noClasses()
.that().resideInAPackage("..application..")
.should().dependOnClassesThat()
.resideInAPackage("..interface..");
@ArchTest
static final ArchRule dependencies_point_inward =
layeredArchitecture()
.consideringAllDependencies()
.layer("Domain").definedBy("..domain..")
.layer("Application").definedBy("..application..")
.layer("Infrastructure").definedBy("..infrastructure..")
.layer("Interface").definedBy("..interface..")
.whereLayer("Domain").mayNotAccessAnyLayer()
.whereLayer("Application").mayOnlyAccessLayers("Domain")
.whereLayer("Infrastructure").mayOnlyAccessLayers("Domain", "Application")
.whereLayer("Interface").mayOnlyAccessLayers("Domain", "Application");
}
// TypeScript equivalent using dependency-cruiser
// .dependency-cruiser.js
module.exports = {
forbidden: [
{
name: 'domain-no-infra',
from: { path: '^src/domain' },
to: { path: '^src/infrastructure' }
},
{
name: 'domain-no-frameworks',
from: { path: '^src/domain' },
to: { path: 'node_modules/(express|prisma|typeorm)' }
}
]
};Run in CI:
# .github/workflows/ci.yml
- name: Check architecture
run: |
./gradlew archTest # Java with ArchUnit
npx depcruise src # TypeScript with dependency-cruiserBenefits:
Reference: ArchUnit
clean-architecture
evals
references
design-patterns
solid-principles
testable-design