Aqui vai a versão em inglês com hashtags fortes e estratégicas 👇 ⸻ Architecture is not a detail. It’s maturity. Understanding the difference between DTO and ViewModel separates developers who just “make it work” from those who build scalable systems. 🔹 A DTO is not a disguised domain model. 🔹 A ViewModel is not a reused DTO. 🔹 Every layer must have a clear responsibility. When you mix them, coupling begins. And technical debt follows. Professional software demands separation of concerns, well-defined contracts, and respect for architecture boundaries. Real engineers think in layers. Ramon Fullstack 🚀 #SoftwareArchitecture #CleanCode #DotNet #BackendDevelopment #SystemDesign
DTO vs ViewModel: Separating Concerns for Scalable Systems
More Relevant Posts
-
Simplicity is the ultimate sophistication (Leonardo da Vinci) It is not only about code reuse - sometimes code reuse introduces incidental complexity. It is about using reusable patterns that are simple to implement, understand and (re)use. https://lnkd.in/dqMYcHW6 #SoftwareArchitecture
To view or add a comment, sign in
-
What if architecture diagrams built themselves from a single sentence? In this tutorial, we walk through building an LLM-powered architecture diagram generator that turns natural language into a visual system design. Describe your stack in plain English, and the application generates a structured diagram automatically. The project combines React, FastAPI, Docker, and Kubernetes with Civo’s relaxAI sovereign AI platform. The backend interprets architecture descriptions with an LLM and returns structured JSON, while the frontend renders it instantly as a diagram. From local development to deploying the full stack on Civo Kubernetes, the tutorial covers the entire journey from empty folder to live application. Read the tutorial from Mostafa Ibrahim: https://civo.io/47fRKEt
To view or add a comment, sign in
-
The difference between reusable components and reusable systems Many frontend codebases focus on building reusable components. Button, Card, Modal and Input And that is good practice. But reusable components alone do not scale a system. There is an important distinction that often appears as projects grow. Reusable components solve visual repetition. Reusable systems solve behavioral repetition. A button can be reused across the entire application, but the real complexity of most products is not in the button itself. It is in things like tables, forms, filters, validation, sorting, pagination, and data interactions. If every feature implements these behaviors slightly differently, the codebase slowly becomes harder to maintain. This is where reusable systems start to matter. Examples of reusable systems in frontend architecture: • a table system that handles sorting, filtering, pagination, and column configuration • a form system that maps fields to a data model and validation rules • a data fetching layer that standardizes loading, caching, and error handling • a layout system that defines consistent structure across pages These systems are not just visual components. They define patterns that the rest of the application follows. The benefit is not only code reuse. It is consistency. When behavior is centralized into systems instead of being reimplemented feature by feature, the entire codebase becomes easier to reason about. New features integrate into existing patterns instead of introducing new ones. In the long term, scalable frontends are rarely built from reusable components alone. They are built from reusable systems.
To view or add a comment, sign in
-
-
Legacy is not about old code. It’s about lost architecture. React projects don’t decay because they are 5 years old. They decay because, at some point, we stop designing the system — and start shipping features. The pattern usually looks like this: • A feature request comes in. • We start from components. • We build bottom-up. • We “fit” it into the existing app. It works. It ships. Everyone is happy. Until six months later. The real problem isn’t about code duplication. It’s duplicated domain logic. When business rules live inside components: - The same logic is reimplemented in different features - There is no single source of truth - Behavior becomes inconsistent - Refactoring becomes risky UI duplication is annoying but manageable. But when domain logic is scattered across the main application layer — without deliberate system design — that’s when systems start to break. This happens when we think in features instead of systems. We patch what exists instead of asking: - What are the functional requirements? - What are the non-functional constraints? - Where should this logic belong in the architecture? - What boundaries does this feature touch? Frontend scalability is not about rendering performance. It’s about system design: - Clear module boundaries - Predictable data flow - Separation of concerns - Refactoring safety If we don’t design the system deliberately, the system will design itself — through accidental complexity. Do you agree that frontend scalability is mostly about system design? In the next post, I’ll share what actually prevents frontend systems from decaying — and why abstractions, system design, and architectural ownership matter more than the choice of library.
To view or add a comment, sign in
-
-
⚙️ Architecture Insight — 2026-03-23 The tightest feedback loops in modern engineering aren't in CI pipelines — they're in the editor, before code ever runs. TypeScript's combination of static analysis, gradual typing, and editor tooling does something structurally important: it makes developer intent explicit at the boundaries between modules, services, and teams. That's where contract drift quietly accumulates, and where catching it before runtime is the difference between a refactor and an incident. Engineering implications: • Static analysis enforced at the module boundary reduces the ambiguity that grows fastest in large, multi-team codebases • Gradual typing gives teams a practical migration path — correctness improves incrementally without requiring a full rewrite • Engineering teams should evaluate where undeclared contracts between services are creating hidden coupling and runtime risk If your architecture depends on implicit agreements between components, you're accumulating technical debt that only surfaces under pressure. Type systems make those agreements visible and enforceable. What's the actual cost of contract drift in your codebase — and how much of it is invisible until production? Source: https://lnkd.in/dp-NqASe #SoftwareArchitecture #EngineeringLeadership #TechStrategy #SystemDesign #PlatformEngineering 🤖 Auto-posted via trs-agent — built by Usama Nadeem
To view or add a comment, sign in
-
Hooks are more than just a way to reuse code. They make your architecture stronger. When we first started extracting logic into hooks, the goal was simple: reuse. But the real impact was much bigger. By moving business logic out of components, we changed how the system is structured. Components stopped worrying about permissions, async flows, and state transitions. They became responsible for one thing: rendering. And that separation made everything easier to work with. Reusing logic through hooks improves understanding and maintainability. Components no longer need to know how the system works internally. They just consume a clear contract and focus on displaying the result. This naturally aligns with good design in practice: • Components handle presentation • Hooks handle behavior and orchestration • Logic evolves without breaking UI As the system grows, this becomes even more valuable. Instead of duplicating rules or passing complex props around, you centralize behavior in one place and reuse it safely across the application. In practice, the difference is clear. A component-heavy approach mixes UI, state, and business rules. A hook-based approach isolates complexity and keeps components predictable. Over time, this leads to: Cleaner code. Easier reasoning. Faster changes with less risk. This is less about React patterns and more about building systems that scale with both code and team. In the comments, I added a small example comparing both approaches side by side.
To view or add a comment, sign in
-
-
Most tests break when you refactor. They break because they're scripts, not contracts. They test how something works, not what it produces. In hexagonal architecture, you trust a new adapter without reading it. You know the port contract. If the adapter passes the tests, it's done. Tests should work the same way. Three things changed how I write tests: → 𝗧𝗲𝘀𝘁𝘀 𝗮𝗿𝗲 𝗰𝗼𝗻𝘁𝗿𝗮𝗰𝘁𝘀. "Given this input, I expect this output." Not "call this method with these arguments." Rewrite the internals tomorrow - the test should still be valid. → 𝗙𝗮𝗸𝗲𝘀, 𝗻𝗼𝘁 𝗺𝗼𝗰𝗸𝘀. A mock verifies interactions. A fake behaves like the real thing. FakeRepository is just an in-memory adapter for your port. Same pattern you use everywhere else. → 𝗣𝗿𝗶𝗺𝗶𝘁𝗶𝘃𝗲𝘀 𝗶𝗻, 𝗽𝗿𝗶𝗺𝗶𝘁𝗶𝘃𝗲𝘀 𝗼𝘂𝘁. Service functions take strings and ints, not domain objects. The signature is thecontract. Tests and HTTP handlers use the same interface. The bottleneck with AI-generated code isn't speed. It's trust. Write behavior contracts. Run them. Green means done. You don't read the implementation - just like you don't read the adapter. I wrote a full article on this with a 4-question checklist to validate any test: Link in comments 👇
To view or add a comment, sign in
-
-
The Clean Architecture Manifesto for Node.js How to structure enterprise applications for 5+ years of growth and maintainability. The Cost of Technical Debt In the rapid lifecycle of startup development, architectural integrity is often sacrificed for speed. However, at Nodezee, our decade of experience has taught us that the "Monolithic Spaghetti" pattern is the leading cause of project failure. We implement Clean Architecture (Uncle Bob's principles) adapted for the asynchronous nature of Node.js. 1. The Dependency Rule The core of our systems is the Domain Layer (Entities and Use Cases). This layer contains the pure business logic and has zero knowledge of the database, the web server, or external APIs. By ensuring that dependencies only point inwards, we can swap out a PostgreSQL database for MongoDB or move from Express to Fastify without touching the core logic. This is essential for maintaining the 150+ systems we have deployed. 2. Interface Adapters and Controllers We use Controllers to bridge the gap between the HTTP request and our Use Cases. By using Dependency Injection, we inject repository interfaces into our services. In Node.js, this is achieved through class constructors or lightweight DI containers. This makes our code 100% unit-testable, as we can easily mock the database layer during Jest testing suites. 3. Scalability through Decoupling Clean Architecture allows our team of 30+ developers to work on separate modules of the same application without merge conflicts. One team can optimize the data persistence layer while another refines the UI logic. The result is a system that isn't just built for today, but engineered to evolve for the next 5 to 10 years. https://lnkd.in/dNQaAFZj
To view or add a comment, sign in
-
Pour développer avec Claude Code, vous pouvez placer le contenu suivante dans un fichier d'instruction [claude.md] afin que celui-ci utilise une manière de développeur aussi brillante que celle d'une développeur sénior : ---------- ## Workflow Orchestration ### 1. Plan Node Default - Enter plan mode for ANY non-trivial task (3+ steps or architectural decisions) - If something goes sideways, STOP and re-plan immediately - don't keep pushing - Use plan mode for verification steps, not just building - Write detailed specs upfront to reduce ambiguity ### 2. Subagent Strategy - Use subagents liberally to keep main context window clean - Offload research, exploration, and parallel analysis to subagents - For complex problems, throw more compute at it via subagents - One task per subagent for focused execution ### 3. Self-Improvement Loop - After ANY correction from the user: update `tasks/lessons.md` with the pattern - Write rules for yourself that prevent the same mistake - Ruthlessly iterate on these lessons until mistake rate drops - Review lessons at session start for relevant project ### 4. Verification Before Done - Never mark a task complete without proving it works - Diff behavior between main and your changes when relevant - Ask yourself: "Would a staff engineer approve this?" - Run tests, check logs, demonstrate correctness ### 5. Demand Elegance (Balanced) - For non-trivial changes : pause and ask "is there a more elegant way?" - If a fix feels hacky : 3knowing everthing I know now, implement the elegant solution" - Skip this for simple, obvious fixes - don't over engineer - Challenge your own work before presenting it ### 6. Autonomous Bug Fixing - When given a bug report: just fix it. Don"t ask for hand-holding - Point at logs, errors, failing tests - then resolve them - Zero context switching required for the user - Go fix failing CI tests without being told how ## Task Management 1. **Plan First**: Write plan to `tasks/todo.md` with checkable items 2. **Verify Plan**: Check in before starting implementation 3. **Track Progress**: Mark items complete as you go 4. **Explain Changes**: High-level summary at each step 5. **Document Result**: Add review section to `tasks/todo.md` 6. **Capture Lessons**: Update `tasks/lessons.md` after corrections ## Core Principles - **Simplicity First**: Make every change as simple as possible. Impact minimal code. - **No Laziness**: Find root causes. No temporary fixes. Senior developer standards. - **Minimal Impact**: Changes should only touch what's necessary. Avoid intoducing bugs.
To view or add a comment, sign in
-
Ever wonder why you keep choosing the same infrastructure solutions without realizing it? - Uncover the design patterns that power everyday platform decisions - Translate architecture jargon into concrete Terraform, Helm, or operator implementations - Learn how pattern awareness cuts toil and speeds up delivery - See real‑world Kubernetes and SRE examples that make the concepts stick - Get a mental toolkit you can start applying this week Which pattern have you been using unknowingly? How would naming it change your approach? Read the article to bridge the gap and subscribe for more deep‑dive pieces. Read the full article 👇 https://lnkd.in/g2ViUgcE If you found it useful, subscribe at https://parraletz.dev to stay up to date. #cncf #awscommunitybuilder #platformengineering #designpatterns #kubernetes #sre
To view or add a comment, sign in
Explore related topics
- Separation of Concerns in Modern Software Development
- How to Apply Software Design and Architecture Principles
- Clear Coding Practices for Mature Software Development
- Clean Code Practices for Scalable Software Development
- Software Engineering Best Practices for Coding and Architecture
- Significance of Software Architecture
💪 😎 💪