# Refactoring 019 - Reify Email Addresses

*Sayit once and only once*

> TL;DR: Avoid duplicate email validations.

# Problems Addressed

- [Repeated email validation](https://maximilianocontieri.com/code-smell-46-repeated-code) logic in multiple places.
- Risk of inconsistent validation rules.
- Difficult to maintain validation rules.
- [Bijection](https://maximilianocontieri.com/the-one-and-only-software-design-principle) violation
- [Primitive Obsession](https://maximilianocontieri.com/code-smell-122-primitive-obsession)
- [Premature Optimization](https://maximilianocontieri.com/code-smell-20-premature-optimization)

# Related Code Smells

%[https://maximilianocontieri.com/code-smell-46-repeated-code]
 
%[https://maximilianocontieri.com/code-smell-122-primitive-obsession]

%[https://maximilianocontieri.com/code-smell-66-shotgun-surgery]

%[https://maximilianocontieri.com/code-smell-177-missing-small-objects]

# Steps

1. Identify where email validation logic is duplicated.
2. Create an `Email Address` class to encapsulate validation rules.
3. Refactor code to use the `Email Address` class instead of raw strings.

# Sample Code

## Before

[Gist Url]: # (https://gist.github.com/mcsee/1653269940ca6f9ea0618197d29eaf6f)

```java
public class Person {
    private String emailAddress;
    // Primitive Obsession

    public void setEmailAddress(String emailAddress) {
        // Duplicated code
        if (!emailAddress.matches(
            "^[\\w.%+-]+@[\\w.-]+\\.[a-zA-Z]{2,}$")) {
            throw new IllegalArgumentException(
                "Invalid email address format");
        }
        this.emailAddress = emailAddress;
    }
}

public class JobApplication {
    private String applicantEmailAddress;

    public void setApplicantEmailAddress(String emailAddress) {
        // Duplicated code
        if (!emailAddress.matches(
            "^[\\w.%+-]+@[\\w.-]+\\.[a-zA-Z]{2,}$")) {
            throw new IllegalArgumentException(
                "Invalid email address format");
        }
        this.applicantEmailAddress = emailAddress;
    }
}
```

## After

[Gist Url]: # (https://gist.github.com/mcsee/39efccf33d24bf297d200a6e9034381a)

```java
public class EmailAddress {
    // 2. Create an `EmailAddress` class to encapsulate validation rules.
    private final String value;

    public EmailAddress(String value) {
        // The rules are in a single place
        // And all objects are created valid
        if (!value.matches("^[\\w.%+-]+@[\\w.-]+\\.[a-zA-Z]{2,}$")) {
            throw new IllegalArgumentException(
                "Invalid email address format");
        }
        this.value = value;
    }
}

public class Person {
    private final EmailAddress emailAddress;

    public Person(EmailAddress emailAddress) {
        // 1. Identify where email validation logic is duplicated.
        // 3. Refactor code to use the `Email Address`
        // class instead of raw strings.
        // No validation is required
        this.emailAddress = emailAddress;
    } 
}

public class JobApplication {
    private EmailAddress applicantEmailAddress;

    public JobApplication(EmailAddress applicantEmailAddress) {
        this.applicantEmailAddress = applicantEmailAddress;
    }
}
```

# Type

[X] Semi-Automatic

# Safety

This refactoring is safe if you replace all occurrences of raw email strings with the EmailAddress class and ensure all tests pass.

# Why is the Code Better?

You make email validation consistent across your application. 

Since validation rules are centralized in one place, the code becomes easier to maintain. 

You also reduce the risk of bugs caused by inconsistent logic.

In the real world, Email Addresses are [small objects](https://maximilianocontieri.com/code-smell-177-missing-small-objects) that exist and are not strings.

The refactored code is closer to the real world [MAPPER](https://maximilianocontieri.com/what-is-wrong-with-software)

Notice that bijection names are essential. It would help to create an 'EmailAddress', not an 'Email', since the Email should [map](https://maximilianocontieri.com/what-is-wrong-with-software) to the actual message.

# Refactor with AI

| Without Proper Instructions    | With Specific Instructions |
| -------- | ------- |
| [ChatGPT](https://chat.openai.com/?q=Correct+and+explain+this+code%3A+%60%60%60java%0D%0Apublic+class+EmailAddress+%7B%0D%0A++++%2F%2F+2.+Create+an+%60EmailAddress%60+class+to+encapsulate+validation+rules.%0D%0A++++private+final+String+value%3B%0D%0A%0D%0A++++public+EmailAddress%28String+value%29+%7B%0D%0A++++++++%2F%2F+The+rules+are+in+a+single+place%0D%0A++++++++%2F%2F+And+all+objects+are+created+valid%0D%0A++++++++if+%28%21value.matches%28%22%5E%5B%5C%5Cw.%25%2B-%5D%2B%40%5B%5C%5Cw.-%5D%2B%5C%5C.%5Ba-zA-Z%5D%7B2%2C%7D%24%22%29%29+%7B%0D%0A++++++++++++throw+new+IllegalArgumentException%28%0D%0A++++++++++++++++%22Invalid+email+address+format%22%29%3B%0D%0A++++++++%7D%0D%0A++++++++this.value+%3D+value%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%0D%0Apublic+class+Person+%7B%0D%0A++++private+final+EmailAddress+emailAddress%3B%0D%0A%0D%0A++++public+Person%28EmailAddress+emailAddress%29+%7B%0D%0A++++++++%2F%2F+1.+Identify+where+email+validation+logic+is+duplicated.%0D%0A++++++++%2F%2F+3.+Refactor+code+to+use+the+%60Email+Address%60%0D%0A++++++++%2F%2F+class+instead+of+raw+strings.%0D%0A++++++++%2F%2F+No+validation+is+required%0D%0A++++++++this.emailAddress+%3D+emailAddress%3B%0D%0A++++%7D+%0D%0A%7D%0D%0A%0D%0Apublic+class+JobApplication+%7B%0D%0A++++private+EmailAddress+applicantEmailAddress%3B%0D%0A%0D%0A++++public+JobApplication%28EmailAddress+applicantEmailAddress%29+%7B%0D%0A++++++++this.applicantEmailAddress+%3D+applicantEmailAddress%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%60%60%60) | [ChatGPT](https://chat.openai.com/?q=1.+Identify+where+email+validation+logic+is+duplicated.2.+Create+an+%60Email+Address%60+class+to+encapsulate+validation+rules.3.+Refactor+code+to+use+the+%60Email+Address%60+class+instead+of+raw+strings%3A+%60%60%60java%0D%0Apublic+class+EmailAddress+%7B%0D%0A++++%2F%2F+2.+Create+an+%60EmailAddress%60+class+to+encapsulate+validation+rules.%0D%0A++++private+final+String+value%3B%0D%0A%0D%0A++++public+EmailAddress%28String+value%29+%7B%0D%0A++++++++%2F%2F+The+rules+are+in+a+single+place%0D%0A++++++++%2F%2F+And+all+objects+are+created+valid%0D%0A++++++++if+%28%21value.matches%28%22%5E%5B%5C%5Cw.%25%2B-%5D%2B%40%5B%5C%5Cw.-%5D%2B%5C%5C.%5Ba-zA-Z%5D%7B2%2C%7D%24%22%29%29+%7B%0D%0A++++++++++++throw+new+IllegalArgumentException%28%0D%0A++++++++++++++++%22Invalid+email+address+format%22%29%3B%0D%0A++++++++%7D%0D%0A++++++++this.value+%3D+value%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%0D%0Apublic+class+Person+%7B%0D%0A++++private+final+EmailAddress+emailAddress%3B%0D%0A%0D%0A++++public+Person%28EmailAddress+emailAddress%29+%7B%0D%0A++++++++%2F%2F+1.+Identify+where+email+validation+logic+is+duplicated.%0D%0A++++++++%2F%2F+3.+Refactor+code+to+use+the+%60Email+Address%60%0D%0A++++++++%2F%2F+class+instead+of+raw+strings.%0D%0A++++++++%2F%2F+No+validation+is+required%0D%0A++++++++this.emailAddress+%3D+emailAddress%3B%0D%0A++++%7D+%0D%0A%7D%0D%0A%0D%0Apublic+class+JobApplication+%7B%0D%0A++++private+EmailAddress+applicantEmailAddress%3B%0D%0A%0D%0A++++public+JobApplication%28EmailAddress+applicantEmailAddress%29+%7B%0D%0A++++++++this.applicantEmailAddress+%3D+applicantEmailAddress%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%60%60%60) |
| [Claude](https://claude.ai/new?q=Correct+and+explain+this+code%3A+%60%60%60java%0D%0Apublic+class+EmailAddress+%7B%0D%0A++++%2F%2F+2.+Create+an+%60EmailAddress%60+class+to+encapsulate+validation+rules.%0D%0A++++private+final+String+value%3B%0D%0A%0D%0A++++public+EmailAddress%28String+value%29+%7B%0D%0A++++++++%2F%2F+The+rules+are+in+a+single+place%0D%0A++++++++%2F%2F+And+all+objects+are+created+valid%0D%0A++++++++if+%28%21value.matches%28%22%5E%5B%5C%5Cw.%25%2B-%5D%2B%40%5B%5C%5Cw.-%5D%2B%5C%5C.%5Ba-zA-Z%5D%7B2%2C%7D%24%22%29%29+%7B%0D%0A++++++++++++throw+new+IllegalArgumentException%28%0D%0A++++++++++++++++%22Invalid+email+address+format%22%29%3B%0D%0A++++++++%7D%0D%0A++++++++this.value+%3D+value%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%0D%0Apublic+class+Person+%7B%0D%0A++++private+final+EmailAddress+emailAddress%3B%0D%0A%0D%0A++++public+Person%28EmailAddress+emailAddress%29+%7B%0D%0A++++++++%2F%2F+1.+Identify+where+email+validation+logic+is+duplicated.%0D%0A++++++++%2F%2F+3.+Refactor+code+to+use+the+%60Email+Address%60%0D%0A++++++++%2F%2F+class+instead+of+raw+strings.%0D%0A++++++++%2F%2F+No+validation+is+required%0D%0A++++++++this.emailAddress+%3D+emailAddress%3B%0D%0A++++%7D+%0D%0A%7D%0D%0A%0D%0Apublic+class+JobApplication+%7B%0D%0A++++private+EmailAddress+applicantEmailAddress%3B%0D%0A%0D%0A++++public+JobApplication%28EmailAddress+applicantEmailAddress%29+%7B%0D%0A++++++++this.applicantEmailAddress+%3D+applicantEmailAddress%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%60%60%60) | [Claude](https://claude.ai/new?q=1.+Identify+where+email+validation+logic+is+duplicated.2.+Create+an+%60Email+Address%60+class+to+encapsulate+validation+rules.3.+Refactor+code+to+use+the+%60Email+Address%60+class+instead+of+raw+strings%3A+%60%60%60java%0D%0Apublic+class+EmailAddress+%7B%0D%0A++++%2F%2F+2.+Create+an+%60EmailAddress%60+class+to+encapsulate+validation+rules.%0D%0A++++private+final+String+value%3B%0D%0A%0D%0A++++public+EmailAddress%28String+value%29+%7B%0D%0A++++++++%2F%2F+The+rules+are+in+a+single+place%0D%0A++++++++%2F%2F+And+all+objects+are+created+valid%0D%0A++++++++if+%28%21value.matches%28%22%5E%5B%5C%5Cw.%25%2B-%5D%2B%40%5B%5C%5Cw.-%5D%2B%5C%5C.%5Ba-zA-Z%5D%7B2%2C%7D%24%22%29%29+%7B%0D%0A++++++++++++throw+new+IllegalArgumentException%28%0D%0A++++++++++++++++%22Invalid+email+address+format%22%29%3B%0D%0A++++++++%7D%0D%0A++++++++this.value+%3D+value%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%0D%0Apublic+class+Person+%7B%0D%0A++++private+final+EmailAddress+emailAddress%3B%0D%0A%0D%0A++++public+Person%28EmailAddress+emailAddress%29+%7B%0D%0A++++++++%2F%2F+1.+Identify+where+email+validation+logic+is+duplicated.%0D%0A++++++++%2F%2F+3.+Refactor+code+to+use+the+%60Email+Address%60%0D%0A++++++++%2F%2F+class+instead+of+raw+strings.%0D%0A++++++++%2F%2F+No+validation+is+required%0D%0A++++++++this.emailAddress+%3D+emailAddress%3B%0D%0A++++%7D+%0D%0A%7D%0D%0A%0D%0Apublic+class+JobApplication+%7B%0D%0A++++private+EmailAddress+applicantEmailAddress%3B%0D%0A%0D%0A++++public+JobApplication%28EmailAddress+applicantEmailAddress%29+%7B%0D%0A++++++++this.applicantEmailAddress+%3D+applicantEmailAddress%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%60%60%60) |
| [Perplexity](https://perplexity.ai/?q=Correct+and+explain+this+code%3A+%60%60%60java%0D%0Apublic+class+EmailAddress+%7B%0D%0A++++%2F%2F+2.+Create+an+%60EmailAddress%60+class+to+encapsulate+validation+rules.%0D%0A++++private+final+String+value%3B%0D%0A%0D%0A++++public+EmailAddress%28String+value%29+%7B%0D%0A++++++++%2F%2F+The+rules+are+in+a+single+place%0D%0A++++++++%2F%2F+And+all+objects+are+created+valid%0D%0A++++++++if+%28%21value.matches%28%22%5E%5B%5C%5Cw.%25%2B-%5D%2B%40%5B%5C%5Cw.-%5D%2B%5C%5C.%5Ba-zA-Z%5D%7B2%2C%7D%24%22%29%29+%7B%0D%0A++++++++++++throw+new+IllegalArgumentException%28%0D%0A++++++++++++++++%22Invalid+email+address+format%22%29%3B%0D%0A++++++++%7D%0D%0A++++++++this.value+%3D+value%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%0D%0Apublic+class+Person+%7B%0D%0A++++private+final+EmailAddress+emailAddress%3B%0D%0A%0D%0A++++public+Person%28EmailAddress+emailAddress%29+%7B%0D%0A++++++++%2F%2F+1.+Identify+where+email+validation+logic+is+duplicated.%0D%0A++++++++%2F%2F+3.+Refactor+code+to+use+the+%60Email+Address%60%0D%0A++++++++%2F%2F+class+instead+of+raw+strings.%0D%0A++++++++%2F%2F+No+validation+is+required%0D%0A++++++++this.emailAddress+%3D+emailAddress%3B%0D%0A++++%7D+%0D%0A%7D%0D%0A%0D%0Apublic+class+JobApplication+%7B%0D%0A++++private+EmailAddress+applicantEmailAddress%3B%0D%0A%0D%0A++++public+JobApplication%28EmailAddress+applicantEmailAddress%29+%7B%0D%0A++++++++this.applicantEmailAddress+%3D+applicantEmailAddress%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%60%60%60) | [Perplexity](https://perplexity.ai/?q=1.+Identify+where+email+validation+logic+is+duplicated.2.+Create+an+%60Email+Address%60+class+to+encapsulate+validation+rules.3.+Refactor+code+to+use+the+%60Email+Address%60+class+instead+of+raw+strings%3A+%60%60%60java%0D%0Apublic+class+EmailAddress+%7B%0D%0A++++%2F%2F+2.+Create+an+%60EmailAddress%60+class+to+encapsulate+validation+rules.%0D%0A++++private+final+String+value%3B%0D%0A%0D%0A++++public+EmailAddress%28String+value%29+%7B%0D%0A++++++++%2F%2F+The+rules+are+in+a+single+place%0D%0A++++++++%2F%2F+And+all+objects+are+created+valid%0D%0A++++++++if+%28%21value.matches%28%22%5E%5B%5C%5Cw.%25%2B-%5D%2B%40%5B%5C%5Cw.-%5D%2B%5C%5C.%5Ba-zA-Z%5D%7B2%2C%7D%24%22%29%29+%7B%0D%0A++++++++++++throw+new+IllegalArgumentException%28%0D%0A++++++++++++++++%22Invalid+email+address+format%22%29%3B%0D%0A++++++++%7D%0D%0A++++++++this.value+%3D+value%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%0D%0Apublic+class+Person+%7B%0D%0A++++private+final+EmailAddress+emailAddress%3B%0D%0A%0D%0A++++public+Person%28EmailAddress+emailAddress%29+%7B%0D%0A++++++++%2F%2F+1.+Identify+where+email+validation+logic+is+duplicated.%0D%0A++++++++%2F%2F+3.+Refactor+code+to+use+the+%60Email+Address%60%0D%0A++++++++%2F%2F+class+instead+of+raw+strings.%0D%0A++++++++%2F%2F+No+validation+is+required%0D%0A++++++++this.emailAddress+%3D+emailAddress%3B%0D%0A++++%7D+%0D%0A%7D%0D%0A%0D%0Apublic+class+JobApplication+%7B%0D%0A++++private+EmailAddress+applicantEmailAddress%3B%0D%0A%0D%0A++++public+JobApplication%28EmailAddress+applicantEmailAddress%29+%7B%0D%0A++++++++this.applicantEmailAddress+%3D+applicantEmailAddress%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%60%60%60) |
| [Copilot](https://www.bing.com/chat?showconv=1&sendquery=1&q=Correct+and+explain+this+code%3A+%60%60%60java%0D%0Apublic+class+EmailAddress+%7B%0D%0A++++%2F%2F+2.+Create+an+%60EmailAddress%60+class+to+encapsulate+validation+rules.%0D%0A++++private+final+String+value%3B%0D%0A%0D%0A++++public+EmailAddress%28String+value%29+%7B%0D%0A++++++++%2F%2F+The+rules+are+in+a+single+place%0D%0A++++++++%2F%2F+And+all+objects+are+created+valid%0D%0A++++++++if+%28%21value.matches%28%22%5E%5B%5C%5Cw.%25%2B-%5D%2B%40%5B%5C%5Cw.-%5D%2B%5C%5C.%5Ba-zA-Z%5D%7B2%2C%7D%24%22%29%29+%7B%0D%0A++++++++++++throw+new+IllegalArgumentException%28%0D%0A++++++++++++++++%22Invalid+email+address+format%22%29%3B%0D%0A++++++++%7D%0D%0A++++++++this.value+%3D+value%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%0D%0Apublic+class+Person+%7B%0D%0A++++private+final+EmailAddress+emailAddress%3B%0D%0A%0D%0A++++public+Person%28EmailAddress+emailAddress%29+%7B%0D%0A++++++++%2F%2F+1.+Identify+where+email+validation+logic+is+duplicated.%0D%0A++++++++%2F%2F+3.+Refactor+code+to+use+the+%60Email+Address%60%0D%0A++++++++%2F%2F+class+instead+of+raw+strings.%0D%0A++++++++%2F%2F+No+validation+is+required%0D%0A++++++++this.emailAddress+%3D+emailAddress%3B%0D%0A++++%7D+%0D%0A%7D%0D%0A%0D%0Apublic+class+JobApplication+%7B%0D%0A++++private+EmailAddress+applicantEmailAddress%3B%0D%0A%0D%0A++++public+JobApplication%28EmailAddress+applicantEmailAddress%29+%7B%0D%0A++++++++this.applicantEmailAddress+%3D+applicantEmailAddress%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%60%60%60) | [Copilot](https://www.bing.com/chat?showconv=1&sendquery=1&q=1.+Identify+where+email+validation+logic+is+duplicated.2.+Create+an+%60Email+Address%60+class+to+encapsulate+validation+rules.3.+Refactor+code+to+use+the+%60Email+Address%60+class+instead+of+raw+strings%3A+%60%60%60java%0D%0Apublic+class+EmailAddress+%7B%0D%0A++++%2F%2F+2.+Create+an+%60EmailAddress%60+class+to+encapsulate+validation+rules.%0D%0A++++private+final+String+value%3B%0D%0A%0D%0A++++public+EmailAddress%28String+value%29+%7B%0D%0A++++++++%2F%2F+The+rules+are+in+a+single+place%0D%0A++++++++%2F%2F+And+all+objects+are+created+valid%0D%0A++++++++if+%28%21value.matches%28%22%5E%5B%5C%5Cw.%25%2B-%5D%2B%40%5B%5C%5Cw.-%5D%2B%5C%5C.%5Ba-zA-Z%5D%7B2%2C%7D%24%22%29%29+%7B%0D%0A++++++++++++throw+new+IllegalArgumentException%28%0D%0A++++++++++++++++%22Invalid+email+address+format%22%29%3B%0D%0A++++++++%7D%0D%0A++++++++this.value+%3D+value%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%0D%0Apublic+class+Person+%7B%0D%0A++++private+final+EmailAddress+emailAddress%3B%0D%0A%0D%0A++++public+Person%28EmailAddress+emailAddress%29+%7B%0D%0A++++++++%2F%2F+1.+Identify+where+email+validation+logic+is+duplicated.%0D%0A++++++++%2F%2F+3.+Refactor+code+to+use+the+%60Email+Address%60%0D%0A++++++++%2F%2F+class+instead+of+raw+strings.%0D%0A++++++++%2F%2F+No+validation+is+required%0D%0A++++++++this.emailAddress+%3D+emailAddress%3B%0D%0A++++%7D+%0D%0A%7D%0D%0A%0D%0Apublic+class+JobApplication+%7B%0D%0A++++private+EmailAddress+applicantEmailAddress%3B%0D%0A%0D%0A++++public+JobApplication%28EmailAddress+applicantEmailAddress%29+%7B%0D%0A++++++++this.applicantEmailAddress+%3D+applicantEmailAddress%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%60%60%60) |
| [Gemini](https://gemini.google.com/?q=Correct+and+explain+this+code%3A+%60%60%60java%0D%0Apublic+class+EmailAddress+%7B%0D%0A++++%2F%2F+2.+Create+an+%60EmailAddress%60+class+to+encapsulate+validation+rules.%0D%0A++++private+final+String+value%3B%0D%0A%0D%0A++++public+EmailAddress%28String+value%29+%7B%0D%0A++++++++%2F%2F+The+rules+are+in+a+single+place%0D%0A++++++++%2F%2F+And+all+objects+are+created+valid%0D%0A++++++++if+%28%21value.matches%28%22%5E%5B%5C%5Cw.%25%2B-%5D%2B%40%5B%5C%5Cw.-%5D%2B%5C%5C.%5Ba-zA-Z%5D%7B2%2C%7D%24%22%29%29+%7B%0D%0A++++++++++++throw+new+IllegalArgumentException%28%0D%0A++++++++++++++++%22Invalid+email+address+format%22%29%3B%0D%0A++++++++%7D%0D%0A++++++++this.value+%3D+value%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%0D%0Apublic+class+Person+%7B%0D%0A++++private+final+EmailAddress+emailAddress%3B%0D%0A%0D%0A++++public+Person%28EmailAddress+emailAddress%29+%7B%0D%0A++++++++%2F%2F+1.+Identify+where+email+validation+logic+is+duplicated.%0D%0A++++++++%2F%2F+3.+Refactor+code+to+use+the+%60Email+Address%60%0D%0A++++++++%2F%2F+class+instead+of+raw+strings.%0D%0A++++++++%2F%2F+No+validation+is+required%0D%0A++++++++this.emailAddress+%3D+emailAddress%3B%0D%0A++++%7D+%0D%0A%7D%0D%0A%0D%0Apublic+class+JobApplication+%7B%0D%0A++++private+EmailAddress+applicantEmailAddress%3B%0D%0A%0D%0A++++public+JobApplication%28EmailAddress+applicantEmailAddress%29+%7B%0D%0A++++++++this.applicantEmailAddress+%3D+applicantEmailAddress%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%60%60%60) | [Gemini](https://gemini.google.com/?q=1.+Identify+where+email+validation+logic+is+duplicated.2.+Create+an+%60Email+Address%60+class+to+encapsulate+validation+rules.3.+Refactor+code+to+use+the+%60Email+Address%60+class+instead+of+raw+strings%3A+%60%60%60java%0D%0Apublic+class+EmailAddress+%7B%0D%0A++++%2F%2F+2.+Create+an+%60EmailAddress%60+class+to+encapsulate+validation+rules.%0D%0A++++private+final+String+value%3B%0D%0A%0D%0A++++public+EmailAddress%28String+value%29+%7B%0D%0A++++++++%2F%2F+The+rules+are+in+a+single+place%0D%0A++++++++%2F%2F+And+all+objects+are+created+valid%0D%0A++++++++if+%28%21value.matches%28%22%5E%5B%5C%5Cw.%25%2B-%5D%2B%40%5B%5C%5Cw.-%5D%2B%5C%5C.%5Ba-zA-Z%5D%7B2%2C%7D%24%22%29%29+%7B%0D%0A++++++++++++throw+new+IllegalArgumentException%28%0D%0A++++++++++++++++%22Invalid+email+address+format%22%29%3B%0D%0A++++++++%7D%0D%0A++++++++this.value+%3D+value%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%0D%0Apublic+class+Person+%7B%0D%0A++++private+final+EmailAddress+emailAddress%3B%0D%0A%0D%0A++++public+Person%28EmailAddress+emailAddress%29+%7B%0D%0A++++++++%2F%2F+1.+Identify+where+email+validation+logic+is+duplicated.%0D%0A++++++++%2F%2F+3.+Refactor+code+to+use+the+%60Email+Address%60%0D%0A++++++++%2F%2F+class+instead+of+raw+strings.%0D%0A++++++++%2F%2F+No+validation+is+required%0D%0A++++++++this.emailAddress+%3D+emailAddress%3B%0D%0A++++%7D+%0D%0A%7D%0D%0A%0D%0Apublic+class+JobApplication+%7B%0D%0A++++private+EmailAddress+applicantEmailAddress%3B%0D%0A%0D%0A++++public+JobApplication%28EmailAddress+applicantEmailAddress%29+%7B%0D%0A++++++++this.applicantEmailAddress+%3D+applicantEmailAddress%3B%0D%0A++++%7D%0D%0A%7D%0D%0A%60%60%60) | 

# Tags

- Encapsulation

# Related Refactorings

%[https://maximilianocontieri.com/refactoring-007-extract-class]
 
%[https://maximilianocontieri.com/refactoring-012-reify-associative-arrays]

%[https://maximilianocontieri.com/refactoring-002-extract-method]

# Credits

Image by [Gerd Altmann](https://pixabay.com/users/geralt-9301/) on [Pixabay](https://pixabay.com/)

* * * 

This article is part of the Refactoring Series.

%[https://maximilianocontieri.com/how-to-improve-your-code-with-easy-refactorings]
