Objects Namespaces And Application Architecture
DRY And Managing Knowledge Duplication
DRY means do not duplicate knowledge, not do not repeat any text or code shape. Two blocks can look similar while representing different business rules that will evolve independently. Conversely, one rule can be duplicated across PHP, JavaScript, SQL constraints, documentation, and configuration even when the syntax looks completely different.
DRY is about one authoritative representation of a piece of knowledge. It is not a command to eliminate every similar-looking line.
Why This Matters
Premature deduplication can couple rules that only happen to look alike today. Real duplication is dangerous when the same business rule, formula, mapping, or policy can drift in several places.
Start with the object or service that owns the relevant invariant. Identify who supplies input, who may change state, and what result the caller is entitled to observe. For DRY And Managing Knowledge Duplication, the most persuasive evidence comes from public behavior, contract tests, dependency direction, and valid state transitions; naming those observations before implementation prevents tool names from standing in for a design.
Working Model
The unit of duplication is a decision. Before extracting code, identify the fact being represented, its owner, and whether all copies must change together. Remove duplication when there is one source of truth. Preserve similar code when combining it would couple unrelated concepts or require flags that hide their differences.
The important vocabulary includes:
- knowledge duplication
- coincidental similarity
- single source of truth
- rule ownership
- generated artifacts
- abstraction timing
Separate knowledge duplication from code repetition. Two loops may be harmlessly similar; two definitions of tax rounding are competing sources of truth.
Core Design Decisions
- Extract a shared function when repeated code implements the same rule and must change together.
- Keep separate implementations when business concepts only happen to share today’s shape.
- Prefer named domain operations over generic helpers controlled by boolean flags.
- Generate secondary representations when schemas, clients, or documentation derive reliably from one authoritative contract.
- Use database constraints as authoritative protection even when validation is repeated for user experience.
- Wait for enough examples to reveal stable commonality before designing a broad abstraction.
Use abstraction where it isolates a real variation or responsibility; otherwise prefer direct, cohesive code. Record the reason beside the code or configuration when the choice is not obvious, especially when future maintainers might otherwise “simplify” away a required guarantee.
PHP-Facing Example
The example should be read through ownership: which component knows the rule, and which callers merely use the result?
<?php
declare(strict_types=1);
final class Percentage
{
private function __construct(public readonly int $basisPoints) {}
public static function fromBasisPoints(int $basisPoints): self
{
if ($basisPoints < 0 || $basisPoints > 10_000) {
throw new InvalidArgumentException('Percentage is out of range.');
}
return new self($basisPoints);
}
public function of(int $amount): int
{
return intdiv($amount * $this->basisPoints, 10_000);
}
}
$taxRate = Percentage::fromBasisPoints(2_000);
echo $taxRate->of(10_000);
// Prints:
// 2000
In DRY And Managing Knowledge Duplication, notice which values the example accepts and what form it returns. Production code should preserve that clarity when it crosses the object or service that owns the relevant invariant, translating external or loosely typed data at the edge instead of allowing it to spread through unrelated classes.
Implementation Workflow
Before extracting, name the knowledge being duplicated and the reason it must change together. Put that knowledge behind a boundary with enough context to enforce it. Leave incidental similarity alone when the concepts have different owners.
Failure Modes
- Creating a generic utility whose parameters encode several unrelated workflows.
- Removing useful validation from one layer because another layer also validates.
- Copying constants into clients and documentation without an ownership or generation plan.
- Forcing two domain concepts to evolve together because their first implementation looked alike.
- Building a shared base class that accumulates hooks for every exception.
- Treating a small amount of readable repetition as more dangerous than a premature abstraction.
The main failure modes are generic helpers that need many flags, shared constants used by unrelated domains, copied validation rules that drift, and abstractions whose name hides the business policy they enforce.
Verification Strategy
Use the following checks as a starting point:
- When one rule changes, list every file, service, client, schema, and document that must change.
- Review abstractions for mode flags, nullable parameters, and
instanceofbranches. - Test generated outputs against their source schema.
- Confirm database constraints still protect invariants when application validation is bypassed.
- Use version-control history to see whether similar blocks actually changed together.
- Ask whether deleting the abstraction would make ownership clearer.
Change the rule in one place and run tests that cover every consumer. Also test two similar cases that should diverge, proving the abstraction did not merge separate concepts.
Security And Data Handling
Keep privileged collaborators explicit and prevent callers from bypassing invariant checks through public mutation or hidden service lookup.
Knowledge can be duplicated in code, database constraints, JSON schemas, OpenAPI documents, queues, documentation, and dashboards. Decide which artifact is authoritative and how the others are generated or checked.
Tradeoffs And Evolution
Use abstraction where it isolates a real variation or responsibility; otherwise prefer direct, cohesive code.
A duplication decision can change. Once two policies diverge, split them before adding flags. Once copied rules start changing together repeatedly, extract the shared knowledge deliberately.
Review Questions
Before considering the topic implemented, answer these questions:
- Which DRY And Managing Knowledge Duplication guarantee matters to the caller?
- Where does the object or service that owns the relevant invariant live?
- Which input or state can be stale, malformed, duplicated, or unauthorized?
- What evidence from public behavior, contract tests, dependency direction, and valid state transitions proves the normal path?
- Which failure is retryable, and how are duplicate effects prevented?
- How will public methods, subclass contracts, serialized objects, container wiring, and persistence mapping be handled during change?
- Which operational signal reveals degradation?
- What simpler choice was rejected, and why?
A DRY refactor is successful when the next rule change has one obvious owner. It is not successful merely because the diff has fewer lines.
From Example To Maintained Code
Consider discount eligibility in controllers, jobs, and admin previews. If each path checks customer tier, product category, and dates separately, the business rule can drift. Move the eligibility decision into one policy and make every caller ask it.
Now compare two similar email templates. They may share layout but represent different messages with different compliance requirements. A shared helper that accepts several booleans may make both harder to review. Extract the layout if useful, but keep message-specific rules separate.
For review, ask what fact would change in the future and which file should change first. If that answer is unclear, the abstraction needs a better boundary or should not exist yet.
Duplication In Tests And Documentation
Tests often duplicate rules intentionally so they can catch a broken implementation. A test that repeats the exact production formula in another helper may only prove that both copies share the same mistake. Prefer examples with independently calculated expected values, fixtures from a specification, or properties that must always hold.
Documentation can also duplicate knowledge. An API schema, README, validation code, and database constraint may all describe the same field length. Decide which artifact is authoritative and automate checks where possible. If the OpenAPI document is the contract, test responses against it. If database constraints are authoritative, keep application validation aligned and explain user-friendly failures before the database rejects the write.
Some repetition is useful because it keeps separate concepts separate. Two workflows may both check a date today but diverge next quarter when one accepts backdating and another does not. Extract only after naming the shared rule. If you cannot name it without vague words like "common handling," the abstraction is probably premature.
When removing duplication, watch for a parameter list that grows with every caller. A helper with many booleans is often several policies squeezed into one function. Split by meaning rather than by line count.
Review Checks
When duplicate-looking code appears, ask what knowledge it represents. If it is the same tax rule, permission rule, field mapping, or protocol contract, choose one owner and make other uses depend on it. If it is merely similar control flow for different business concepts, leave it separate until the concepts truly move together. Record the reason so a later cleanup does not merge policies accidentally.
Duplication can also be temporal. A migration script and runtime validator may both contain a rule during a transition. That is acceptable when the script has a short lifetime and the owner is clear. Remove the temporary copy after the migration completes.
Source Of Truth Reviews
For important rules, identify the source of truth during review. A price calculation may live in code, while valid currency codes may come from a maintained data file, and API shape may come from OpenAPI. The review should verify that generated artifacts, caches, and documentation derive from that owner or are checked against it. Otherwise the project silently creates parallel truths.
Official References
What You Should Be Able To Do
After this lesson, you should be able to explain dry and managing knowledge duplication in operational terms, choose it only when its guarantees fit the requirement, implement a narrow PHP-facing boundary, recognize the common failure modes, and verify behavior using evidence from the real system rather than assuming the configuration is correct.
Practice
Model The Boundary
For DRY And Managing Knowledge Duplication, write a short design note for a product-catalog application. Identify the caller, authoritative state, inputs, output, trust boundary, and one invariant. Include one success timeline and one partial-failure timeline.
Show solution
A strong answer names concrete ownership rather than only a tool. The authoritative state should be explicit, and derived copies should be labelled as such. The success timeline should identify when the result becomes observable. The failure timeline should stop after an intermediate step and explain whether retry is safe, whether status must be queried, or whether reconciliation is required.
The invariant should be testable. Examples include “one order causes at most one captured payment,” “only authorized tenant documents appear in results,” or “the latest valid configuration is the one served after rollout.”
Review A Design
Review an implementation of DRY And Managing Knowledge Duplication that works in one local demonstration. Use the lesson’s failure modes to identify at least four production risks. For each risk, propose the narrowest change that restores a clear guarantee.
Show solution
The review should connect each risk to a violated guarantee. Good findings cover validation, authorization, retry or duplicate behavior, environment drift, and observability. Avoid broad recommendations such as “use best practices.” Name the responsible boundary and the evidence that would prove the repair.
A narrow repair may be a constraint, explicit comparison policy, interface contract, timeout, idempotency key, index, security rule, probe, IAM policy, or integration test. The selected mechanism must match the actual risk.
Build A Verification Plan
Create a verification plan for DRY And Managing Knowledge Duplication. Include one unit test, one boundary-level integration test, one negative security or validation test, one failure-injection exercise, and two operational signals. State what each check proves and what it does not prove.
Show solution
The unit test should cover a pure decision. The integration test must cross the real boundary rather than only checking a prepared request. The negative test should use an identity or input that must be rejected. The failure exercise should create a timeout, retry, restart, unavailable dependency, or incompatible version deliberately.
Operational signals should reveal both health and correctness. Useful examples include latency percentiles, error classification, queue age, indexing lag, denied requests, restart count, duplicate side effects, resource saturation, and final business-state reconciliation.