<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gabriela Goudromihos Puig</title>
    <description>The latest articles on DEV Community by Gabriela Goudromihos Puig (@gabrielapuig).</description>
    <link>https://dev.to/gabrielapuig</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3313401%2Fa87425f2-5674-4d37-90d7-40fb405f0118.jpg</url>
      <title>DEV Community: Gabriela Goudromihos Puig</title>
      <link>https://dev.to/gabrielapuig</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gabrielapuig"/>
    <language>en</language>
    <item>
      <title>🧠 From Chaos to Clean Code: My Java Refactor Journey - Part 4 of 6</title>
      <dc:creator>Gabriela Goudromihos Puig</dc:creator>
      <pubDate>Tue, 08 Jul 2025 08:04:38 +0000</pubDate>
      <link>https://dev.to/gabrielapuig/from-chaos-to-clean-code-my-java-refactor-journey-part-4-of-6-4go1</link>
      <guid>https://dev.to/gabrielapuig/from-chaos-to-clean-code-my-java-refactor-journey-part-4-of-6-4go1</guid>
      <description>&lt;p&gt;Now that our architecture is modular and our input/output boundaries are well-defined, it’s time to make the system more robust and less fragile.&lt;/p&gt;

&lt;p&gt;Because clean code is not just about structure — it’s about behavior under pressure.&lt;/p&gt;

&lt;p&gt;In this part of the journey, we’ll:&lt;/p&gt;

&lt;p&gt;✅ Centralize error handling so unexpected exceptions don’t leak into the user’s face&lt;br&gt;
✅ Add meaningful error messages and proper HTTP responses&lt;br&gt;
✅ Start writing unit tests to protect behavior and refactors&lt;br&gt;
✅ Learn how to test services, controllers, and edge cases confidently&lt;/p&gt;

&lt;p&gt;We’ve cleaned up the house — now we’re adding locks to the doors and alarms to the windows.&lt;br&gt;
Let’s make it reliable. 🛡️&lt;/p&gt;
&lt;h2&gt;
  
  
  🛡️ Step 1: Global Error Handling — Clean, Scoped &amp;amp; Scalable
&lt;/h2&gt;

&lt;p&gt;A clean architecture doesn’t stop at structure — it must also handle errors predictably and clearly. Instead of generic stack traces or inconsistent messages, we now return standardized and meaningful responses across the entire API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔹 Scoped Handlers per Domain&lt;/strong&gt;&lt;br&gt;
We created three focused @ControllerAdvice classes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.example.spaghetti.adapter.exception
  └── ThingExceptionHandler.java ← Handles errors from the ThingController
  └── ItemExceptionHandler.java ← Handles errors from the ItemController
  └── ValidationExceptionHandler.java ← Catches validation failures and generic exceptions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This structure avoids bloated global handlers and keeps each domain's behavior isolated and easy to reason about.&lt;/p&gt;

&lt;p&gt;📦 All handlers are placed under &lt;strong&gt;adapter.exception&lt;/strong&gt;, since they're part of how the application communicates with the outside world — not core business logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔹 Domain Exceptions with Meaning&lt;/strong&gt;&lt;br&gt;
We introduced custom exceptions that live in the domain layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.example.spaghetti.domain.exception
  └── ThingNotFoundException.java
  └── ItemNotFoundException.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They extend a shared base:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.example.spaghetti.adapter.exceptionEntityNotFoundException
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows us to:&lt;/p&gt;

&lt;p&gt;✅ Express business rules clearly in the domain&lt;br&gt;
✅ Share logic for testing and centralized error mapping&lt;br&gt;
✅ Keep the application layer free of hardcoded strings and magic messages&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔹 Ready to Scale&lt;/strong&gt;&lt;br&gt;
This setup follows Clean Architecture and DDD principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Domain stays isolated — no HTTP, no annotations&lt;/li&gt;
&lt;li&gt;Adapter layer deals with translation to REST responses&lt;/li&gt;
&lt;li&gt;Each new domain can have its own exceptions and handler&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 The result: when your app grows, your error handling doesn’t get messier — it grows with it, cleanly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧹 Adjusting Error Handling and Responsibilities&lt;/strong&gt;&lt;br&gt;
During the project cleanup, we removed the name validation from the ItemController:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (!nameValidator.test(itemRequest.getName())) {
    throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Name must start with uppercase");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is because this validation represents a business rule, and according to Clean Architecture and DDD principles, business rules belong in the application or domain layer, not in the controller (adapter) layer.&lt;/p&gt;

&lt;p&gt;Now, this validation lives inside the ItemService, which throws a specific exception (InvalidItemNameException) when the rule is violated. This exception is caught by the ItemExceptionHandler and translated into the proper HTTP response.&lt;/p&gt;

&lt;p&gt;This adjustment keeps the controller lean and centralizes business logic in the right place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📝 What about the letter count log in the ThingController?&lt;/strong&gt;&lt;br&gt;
On the other hand, we kept the letter count logging in the ThingController:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int letterCount = utils.countLetters(thingRequest.getName());
System.out.println("Name has " + letterCount + " letters.");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code does not affect application logic or control flow — it’s just a utility for logging or debugging, with no business impact.&lt;/p&gt;

&lt;p&gt;Therefore, it’s fine to leave it in the controller.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 What’s Next: Unit and Integration Testing, with Purpose
&lt;/h2&gt;

&lt;p&gt;With error handling centralized and domain boundaries protected, our system is no longer fragile — but it’s not battle-tested yet.&lt;/p&gt;

&lt;p&gt;In the next sessions, we’ll dedicate entire steps to testing, because clean architecture without tests is like building a fortress with no guards.&lt;/p&gt;

&lt;p&gt;🔬 We’ll start with unit tests, focusing on services and core use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validate business logic in isolation&lt;/li&gt;
&lt;li&gt;Protect against regressions&lt;/li&gt;
&lt;li&gt;Speed up development with confidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔗 Then, we’ll move to integration tests, making sure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Controllers, mappers, and dependencies work as a system&lt;/li&gt;
&lt;li&gt;HTTP endpoints behave correctly under real conditions&lt;/li&gt;
&lt;li&gt;The whole app remains stable during changes and refactors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Testing is not a checkbox — it’s part of designing resilient software.&lt;br&gt;
So in the next chapters, we’ll not only write tests — we’ll structure them with the same discipline we applied to the rest of the code.&lt;/p&gt;

&lt;p&gt;🧱 Architecture is foundation.&lt;br&gt;
🛡️ Error handling is protection.&lt;br&gt;
🔁 Testing is confidence.&lt;/p&gt;

&lt;p&gt;Let’s move forward with that confidence — and make this codebase bulletproof. 💥&lt;/p&gt;

</description>
      <category>api</category>
      <category>java</category>
      <category>architecture</category>
      <category>programming</category>
    </item>
    <item>
      <title>🧠 From Chaos to Clean Code: My Java Refactor Journey - Part 3 of 6</title>
      <dc:creator>Gabriela Goudromihos Puig</dc:creator>
      <pubDate>Fri, 04 Jul 2025 17:43:28 +0000</pubDate>
      <link>https://dev.to/gabrielapuig/from-chaos-to-clean-code-my-java-refactor-journey-part-3-of-6-5h6a</link>
      <guid>https://dev.to/gabrielapuig/from-chaos-to-clean-code-my-java-refactor-journey-part-3-of-6-5h6a</guid>
      <description>&lt;p&gt;Now that we’ve separated concerns and cleaned up the code, it’s time for the next step:&lt;br&gt;
introducing Clean Architecture layers and applying DDD concepts with proper domain modeling.&lt;/p&gt;

&lt;p&gt;Let’s make the design clearer, scalable, and truly domain-focused. 🚀&lt;/p&gt;
&lt;h2&gt;
  
  
  🔧 Step 1: Laying the Groundwork for Clean Architecture
&lt;/h2&gt;

&lt;p&gt;Before we can apply Clean Architecture and DDD properly, we need to rethink our folder structure.&lt;/p&gt;

&lt;p&gt;Right now, everything is grouped by technical role:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.example.spaghetti
├── controller
│   └── ThingController.java
│   └── ItemController.java
├── service
│   └── ThingService.java
│   └── ItemService.java
├── repository
│   └── ThingRepository.java
│   └── ItemRepository.java
├── model
│   └── Thing.java
│   └── Item.java
├── config
│   └── MainConfig.java
├── util
│   └── Utils.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s a good start — but Clean Architecture is not just about naming layers, it’s about isolating responsibilities and controlling dependencies between them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ 1. Define the main layers&lt;/strong&gt;&lt;br&gt;
Here’s the structure we’re aiming for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.example.spaghetti
├── domain           ← business rules and core entities (pure Java)
├── application      ← use cases (calls domain logic)
├── infrastructure   ← technical details (config, persistence, utilities)
├── adapter          ← I/O layers (controllers, REST APIs, DTOs)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡 Rule of thumb:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Domain is the core.&lt;/li&gt;
&lt;li&gt;Application uses the domain.&lt;/li&gt;
&lt;li&gt;Infrastructure supports them.&lt;/li&gt;
&lt;li&gt;Adapter is how the outside world talks to the app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ 2. Move your classes to the right packages&lt;/strong&gt;&lt;br&gt;
Let’s organize your existing code into those layers:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;🔹 domain&lt;/em&gt;&lt;br&gt;
Core entities and domain contracts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.example.spaghetti.domain.model
  └── Thing.java
  └── Item.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.example.spaghetti.domain.repository
  └── ThingRepository.java
  └── ItemRepository.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;🔹 application&lt;/em&gt;&lt;br&gt;
Business coordination logic&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.example.spaghetti.application.service
  └── ThingService.java
  └── ItemService.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;🔹 infrastructure&lt;/em&gt;&lt;br&gt;
Low-level details like config and utility classes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.example.spaghetti.infrastructure.config
  └── MainConfig.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.example.spaghetti.infrastructure.util
  └── Utils.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;🔹 adapter&lt;/em&gt;&lt;br&gt;
Web interface and DTOs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.example.spaghetti.adapter.controller
  └── ThingController.java
  └── ItemController.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.example.spaghetti.adapter.dto
  └── (we'll add DTOs in the next steps)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This new structure aligns your code with Clean Architecture principles, making it easier to scale, test, and evolve over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔧 Step 2: Introducing DTOs, Mappers, and Validation for Clear Separation
&lt;/h2&gt;

&lt;p&gt;After reorganizing our project structure and separating concerns, the next essential step was to make the boundary between our API and domain logic explicit — by introducing DTOs (Data Transfer Objects), validation, and mappers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📂 Organizing DTOs and Mappers&lt;/strong&gt;&lt;br&gt;
We created dedicated packages to keep the code clean and scalable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.example.spaghetti.adapter.dto.request    ← Input DTOs (ThingRequest, ItemRequest)
com.example.spaghetti.adapter.dto.response   ← Output DTOs (ThingResponse, ItemResponse)
com.example.spaghetti.adapter.dto.mapper     ← Mappers to convert between DTOs and domain entities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This separation keeps the API contract clear, prevents domain leakage, and isolates transformations, following Clean Architecture’s adapter layer principle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📄 Why DTOs?&lt;/strong&gt;&lt;br&gt;
DTOs define exactly what data enters and leaves our system. To ensure data integrity, we added validation annotations from Jakarta Validation API, such as &lt;strong&gt;NotBlank&lt;/strong&gt; and &lt;strong&gt;NotNull&lt;/strong&gt;, on the request DTO fields.&lt;/p&gt;

&lt;p&gt;This guarantees that only valid and well-formed data reaches the business logic layer.&lt;/p&gt;

&lt;p&gt;By doing this, our domain entities remain clean and focused solely on business rules — an important DDD principle to avoid coupling domain models to external layers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠️ Using MapStruct for Mapping&lt;/strong&gt;&lt;br&gt;
To avoid boilerplate code when converting between DTOs and entities, we introduced MapStruct, a code generator that creates type-safe mappers automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Mapper(componentModel = "spring")
public interface ThingMapper {
    Thing toEntity(ThingRequest request);
    ThingResponse toResponse(Thing thing);
    List&amp;lt;ThingResponse&amp;gt; toResponse(List&amp;lt;Thing&amp;gt; things);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Mapper(componentModel = "spring")
public interface ItemMapper {
    Item toEntity(ItemRequest request);
    ItemResponse toResponse(Item item);
    List&amp;lt;ItemResponse&amp;gt; toResponseList(List&amp;lt;Item&amp;gt; things);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mappers live in the adapter layer and keep our domain pure from external concerns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚙️ Controller Adjustments&lt;/strong&gt;&lt;br&gt;
Controllers were updated to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accept validated request DTOs (annotated with Jakarta Validation constraints)&lt;/li&gt;
&lt;li&gt;Use mappers to convert requests into domain entities&lt;/li&gt;
&lt;li&gt;Call the service layer with domain entities&lt;/li&gt;
&lt;li&gt;Convert service results back into response DTOs for the client&lt;/li&gt;
&lt;li&gt;This keeps the controller’s responsibility to a simple orchestrator — no business logic inside, fully aligned with Clean Architecture.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ What this achieved&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear separation of API and domain models&lt;/li&gt;
&lt;li&gt;Early validation of input data via Jakarta Validation annotations&lt;/li&gt;
&lt;li&gt;Reduced boilerplate with MapStruct generated code&lt;/li&gt;
&lt;li&gt;Improved maintainability and scalability of the codebase&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧠 What’s next?
&lt;/h2&gt;

&lt;p&gt;With DTOs, validation, and mapping in place, our code is now clean, scalable, and aligned with Clean Architecture and DDD principles.&lt;br&gt;
Next up, we’ll focus on improving reliability by implementing global error handling and writing unit tests.&lt;/p&gt;

</description>
      <category>api</category>
      <category>java</category>
      <category>architecture</category>
      <category>programming</category>
    </item>
    <item>
      <title>🧠 From Chaos to Clean Code: My Java Refactor Journey - Part 2 of 6</title>
      <dc:creator>Gabriela Goudromihos Puig</dc:creator>
      <pubDate>Thu, 03 Jul 2025 07:25:36 +0000</pubDate>
      <link>https://dev.to/gabrielapuig/from-chaos-to-clean-code-my-java-refactor-journey-part-2-of-6-4n2k</link>
      <guid>https://dev.to/gabrielapuig/from-chaos-to-clean-code-my-java-refactor-journey-part-2-of-6-4n2k</guid>
      <description>&lt;h2&gt;
  
  
  🔧 Step 1: Separating Responsibilities – From Spaghetti to Structure
&lt;/h2&gt;

&lt;p&gt;The first class I refactored was a typical all-in-one mess: controller, business logic, and in-memory storage were all crammed into the same place.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestController
@RequestMapping("/things")
public class ControllerService {
    private List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
    // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestController
@RequestMapping("/items")
public class ModelRepoController {
    private Map&amp;lt;Long, Item&amp;gt; storage = new HashMap&amp;lt;&amp;gt;();
    // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This class did everything — which is exactly what we want to avoid in domain-oriented architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔄 The refactor
&lt;/h3&gt;

&lt;p&gt;Split the logic into four separate components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;ThingController&lt;/em&gt;/&lt;em&gt;ItemController&lt;/em&gt;: exposes the HTTP API&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;ThingService&lt;/em&gt;/&lt;em&gt;ItemService&lt;/em&gt;: handles the business logic&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;ThingRepository&lt;/em&gt;/&lt;em&gt;ItemRepository&lt;/em&gt;: manages data access (in-memory for now)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Thing&lt;/em&gt;/&lt;em&gt;Item&lt;/em&gt;: represents the domain entity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The logic stayed the same, but now it's clean, testable, and aligned with Clean Architecture principles.&lt;/p&gt;

&lt;p&gt;💡 Before: logic and storage were tightly coupled in the controller&lt;br&gt;
💡 After: the controller simply orchestrates calls to the service&lt;/p&gt;

&lt;p&gt;🔗 Check out the before and after in the repo.&lt;/p&gt;
&lt;h3&gt;
  
  
  🗂️ Project structure after the refactor:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.example.spaghetti
├── controller
│   └── ThingController.java
│   └── ItemController.java
├── service
│   └── ThingService.java
│   └── ItemService.java
├── repository
│   └── ThingRepository.java
│   └── ItemRepository.java
├── model
│   └── Thing.java
│   └── Item.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  🔧 Step 2: From “Useless Bean” to Simple Validation
&lt;/h2&gt;

&lt;p&gt;In the initial version of the code, I had a leftover bean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Bean
public String uselessBean() {
    return "I am a useless bean";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🫠 It did absolutely nothing — until now.&lt;/p&gt;

&lt;p&gt;Instead of deleting it, I replaced it with a ✨ simple validation rule:&lt;br&gt;
✅ check if a name starts with an uppercase letter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Bean
public Predicate&amp;lt;String&amp;gt; nameStartsWithUppercaseValidator() {
    return name -&amp;gt; name != null &amp;amp;&amp;amp; !name.isEmpty() &amp;amp;&amp;amp; Character.isUpperCase(name.charAt(0));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I then injected it into the controller and used it to validate input before saving a new item.&lt;br&gt;
No big framework, no annotation magic — just a good old &lt;a class="mentioned-user" href="https://dev.to/bean"&gt;@bean&lt;/a&gt; doing something useful.&lt;/p&gt;

&lt;p&gt;📦 Where should this bean live?&lt;/p&gt;

&lt;p&gt;Since this is a generic validation, not part of the domain logic itself, I moved it to a dedicated config package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;com.example.spaghetti
├── config
│   └── MainConfig.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;According to DDD principles, reusable and infrastructure-related beans like this one shouldn't live inside your domain or application logic.&lt;br&gt;
Placing it under config (or infrastructure.config) keeps your architecture clean and responsibilities well separated.&lt;/p&gt;

&lt;p&gt;💡 Small win: the bean now enforces a business rule — and the code stays clean and reusable.&lt;/p&gt;

&lt;p&gt;🧠 Even small refactors like this help keep things tidy and meaningful.&lt;/p&gt;
&lt;h2&gt;
  
  
  🔧 Step 3: Giving Purpose to the Utils Class
&lt;/h2&gt;

&lt;p&gt;Previously, our Utils class had two static methods that weren’t actually used anywhere.&lt;/p&gt;

&lt;p&gt;Now, we brought it to life by adding a new method that counts the number of letters in a given string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public int countLetters(String input) {
    if (input == null) return 0;
    return (int) input.chars()
            .filter(Character::isLetter)
            .count();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method helps us process input names more meaningfully.&lt;/p&gt;

&lt;p&gt;In the controller, we call this method to log how many letters the submitted name has before saving it.&lt;/p&gt;

&lt;p&gt;Small steps like this turn “unused helpers” into valuable tools for our application!&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Conclusion: Setting the Stage for Clean Architecture and DDD
&lt;/h2&gt;

&lt;p&gt;We’ve cleaned up the code by separating responsibilities and giving purpose to unused parts like the validation bean and utils. 🧹✨&lt;/p&gt;

&lt;p&gt;This foundation makes our codebase cleaner and easier to maintain. 🏗️🧱&lt;/p&gt;

&lt;p&gt;Next, we’ll introduce Clean Architecture layers and apply proper domain modeling with DDD to take our design to the next level. 📐📚&lt;/p&gt;

&lt;p&gt;Stay tuned! 👀&lt;/p&gt;

</description>
      <category>api</category>
      <category>java</category>
      <category>architecture</category>
      <category>programming</category>
    </item>
    <item>
      <title>Whether you’re new to server modding or just curious about how MCP works, this tutorial makes it easy to get started</title>
      <dc:creator>Gabriela Goudromihos Puig</dc:creator>
      <pubDate>Wed, 02 Jul 2025 07:46:19 +0000</pubDate>
      <link>https://dev.to/gabrielapuig/whether-youre-new-to-server-modding-or-just-curious-about-how-mcp-works-this-tutorial-makes-it-24p2</link>
      <guid>https://dev.to/gabrielapuig/whether-youre-new-to-server-modding-or-just-curious-about-how-mcp-works-this-tutorial-makes-it-24p2</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/debs_obrien/building-your-first-mcp-server-a-beginners-tutorial-5fag" class="crayons-story__hidden-navigation-link"&gt;Building Your First MCP Server: A Beginners Tutorial&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/debs_obrien" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F212929%2F947ba7e0-41fe-464a-a4f3-abb66a3170c6.jpg" alt="debs_obrien profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/debs_obrien" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Debbie O'Brien
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Debbie O'Brien
                
              
              &lt;div id="story-author-preview-content-2640328" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/debs_obrien" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F212929%2F947ba7e0-41fe-464a-a4f3-abb66a3170c6.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Debbie O'Brien&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/debs_obrien/building-your-first-mcp-server-a-beginners-tutorial-5fag" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jul 1 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/debs_obrien/building-your-first-mcp-server-a-beginners-tutorial-5fag" id="article-link-2640328"&gt;
          Building Your First MCP Server: A Beginners Tutorial
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/mcp"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;mcp&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/typescript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;typescript&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/debs_obrien/building-your-first-mcp-server-a-beginners-tutorial-5fag" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;146&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/debs_obrien/building-your-first-mcp-server-a-beginners-tutorial-5fag#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              6&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            9 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>mcp</category>
      <category>webdev</category>
      <category>ai</category>
      <category>typescript</category>
    </item>
    <item>
      <title>🧠 From Chaos to Clean Code: My Java Refactor Journey - Part 1 of 6</title>
      <dc:creator>Gabriela Goudromihos Puig</dc:creator>
      <pubDate>Wed, 02 Jul 2025 07:36:41 +0000</pubDate>
      <link>https://dev.to/gabrielapuig/from-chaos-to-clean-code-my-java-refactor-journey-1elp</link>
      <guid>https://dev.to/gabrielapuig/from-chaos-to-clean-code-my-java-refactor-journey-1elp</guid>
      <description>&lt;p&gt;I wanted to challenge myself to apply Clean Architecture and Domain-Driven Design (DDD) from the ground up — not in a greenfield project, but starting from total mess.&lt;/p&gt;

&lt;p&gt;So I built Spaghetti API: a deliberately chaotic Spring Boot project, full of bad practices, no architecture, and zero tests.&lt;/p&gt;

&lt;p&gt;It looks like this 👇&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/main/java/com/example/spaghetti
├── ControllerService.java     // controller acting as service
├── ModelRepoController.java   // model + repo + controller in one
├── Utils.java                 // weird helpers
├── MainConfig.java            // useless bean
├── SpaghettiApplication.java

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧩 Why?
&lt;/h2&gt;

&lt;p&gt;Because most real-life projects don’t start clean — they evolve from chaos. I wanted to document how I bring order, step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ My refactoring path
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Separate responsibilities (controller, service, repo, model)&lt;/li&gt;
&lt;li&gt;Introduce Clean Architecture layers&lt;/li&gt;
&lt;li&gt;Apply DDD concepts with proper domain modeling&lt;/li&gt;
&lt;li&gt;Add DTOs, validations, global error handling&lt;/li&gt;
&lt;li&gt;Implement unit and integration tests&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✅ Technologies
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Java 17&lt;/li&gt;
&lt;li&gt;Spring Boot 3&lt;/li&gt;
&lt;li&gt;Maven&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔗 Source Code
&lt;/h2&gt;

&lt;p&gt;👉 github.com/gabrielapuig/spaghetti-api&lt;/p&gt;

&lt;p&gt;If you're dealing with a messy legacy codebase 🧹, or want to level up your architecture skills in Java ☕️, follow along — I’ll be sharing each refactor stage 🔄 and breaking it down step-by-step.&lt;/p&gt;

&lt;p&gt;Ever worked on a project like this? 🤔 I'd love to hear how you handled it!&lt;/p&gt;

</description>
      <category>api</category>
      <category>java</category>
      <category>architecture</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
