Apply software design principles across architecture and implementation using deterministic decision workflows, SOLID checks, structural patterns, and anti-pattern detection; use when reviewing designs, refactoring modules, or resolving maintainability and coupling risks.
Does it follow best practices?
Evaluation — 99%
↑ 1.01xAgent success when using this tile
Validation for skill structure
Entities should contain behavior, not just data. Anemic domain models push business logic into services, scattering rules and duplicating validation.
Incorrect (anemic domain model):
// domain/entities/Subscription.java
public class Subscription {
private String id;
private String planId;
private LocalDate startDate;
private LocalDate endDate;
private String status;
// Only getters and setters - no behavior
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public LocalDate getEndDate() { return endDate; }
public void setEndDate(LocalDate endDate) { this.endDate = endDate; }
}
// application/services/SubscriptionService.java
public class SubscriptionService {
public void cancel(Subscription sub) {
if (!sub.getStatus().equals("active")) {
throw new IllegalStateException("Cannot cancel");
}
sub.setStatus("cancelled");
sub.setEndDate(LocalDate.now());
}
public void renew(Subscription sub, int months) {
if (!sub.getStatus().equals("active")) {
throw new IllegalStateException("Cannot renew");
}
sub.setEndDate(sub.getEndDate().plusMonths(months));
}
// Logic scattered across many services
}Correct (rich domain model):
// domain/entities/Subscription.java
public class Subscription {
private final SubscriptionId id;
private final PlanId planId;
private final LocalDate startDate;
private LocalDate endDate;
private SubscriptionStatus status;
public void cancel() {
ensureActive();
this.status = SubscriptionStatus.CANCELLED;
this.endDate = LocalDate.now();
}
public void renew(Period extension) {
ensureActive();
if (extension.getMonths() < 1) {
throw new InvalidExtensionPeriodException(extension);
}
this.endDate = this.endDate.plus(extension);
}
public boolean isExpired() {
return LocalDate.now().isAfter(this.endDate);
}
public boolean canUpgradeTo(Plan newPlan) {
return this.status == SubscriptionStatus.ACTIVE
&& newPlan.isUpgradeFrom(this.planId);
}
private void ensureActive() {
if (this.status != SubscriptionStatus.ACTIVE) {
throw new InactiveSubscriptionException(this.id);
}
}
}
// application/usecases/CancelSubscriptionUseCase.java
public class CancelSubscriptionUseCase {
public void execute(SubscriptionId id) {
Subscription sub = repository.findById(id);
sub.cancel(); // Business logic in entity
repository.save(sub);
}
}Benefits:
Reference: Anemic Domain Model Anti-pattern
Install with Tessl CLI
npx tessl i pantheon-ai/software-design-principlesevals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
references