diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6ba016365a0c19353050f156b68c0bdeb24a6801..12434bf73616e26254f786f222bdc7b22aeb130e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -16,3 +16,4 @@ include:
   - local: "/trip-service-kata/.gitlab-ci.yml"
   - local: "/tcr-roman-numerals/.gitlab-ci.yml"
   - local: "/java-h2g2/.gitlab-ci.yml"
+  - local: "/factory-patterns/.gitlab-ci.yml"
diff --git a/README.md b/README.md
index 7604eb69cd8c5cd5510df2930b946346299a0ed2..b082dea0bb17bccfac75812a36780047472ce258 100644
--- a/README.md
+++ b/README.md
@@ -38,3 +38,4 @@ Ce dépôt Git a pour but de partager les différents ateliers pouvant être ré
 | [Dev pour des data scientists, un sale boulot](https://www.youtube.com/watch?v=QK3OJGAresE)                           | Discussion  |            |
 | [TCR - Roman Numerals](/tcr-roman-numerals)                                                                           | Kata        | Moyenne    |
 | [H2G2 en Java](/java-h2g2)                                                                                            | Kata        | Moyenne    |
+| [Factory patterns](/factory-patterns)                                                                                 | Code&coffee | Facile     |
diff --git a/factory-patterns/.gitlab-ci.yml b/factory-patterns/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4309563748fe7e147829ef09f731421ba429aafa
--- /dev/null
+++ b/factory-patterns/.gitlab-ci.yml
@@ -0,0 +1,11 @@
+package-factory-patterns:
+  variables:
+    PROJECT_FOLDER: "factory-patterns"
+  extends: .java
+  only:
+    refs:
+      - master
+      - merge_requests
+    changes:
+      - ".gitlab-common-ci.yml"
+      - "factory-patterns/**/*"
diff --git a/factory-patterns/pom.xml b/factory-patterns/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0990191fba221c7273feb955aa525b45e2d1fc3a
--- /dev/null
+++ b/factory-patterns/pom.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <version>1.0.0</version>
+    <groupId>fr.ippon.kata</groupId>
+    <artifactId>java-parent</artifactId>
+    <relativePath>../java-parent</relativePath>
+  </parent>
+
+  <version>1.0.0-SNAPSHOT</version>
+  <artifactId>factory-patterns</artifactId>
+
+  <name>FactoryPatterns</name>
+
+  <developers>
+    <developer>
+      <email>arey@ippon.fr</email>
+      <name>Anthony REY</name>
+    </developer>
+    <developer>
+      <email>cdamon@ippon.fr</email>
+      <name>Colin DAMON</name>
+    </developer>
+  </developers>
+</project>
diff --git a/factory-patterns/readme.md b/factory-patterns/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..675d4e27b16a847c7b33c0550a624d8f3190048d
--- /dev/null
+++ b/factory-patterns/readme.md
@@ -0,0 +1,28 @@
+# "factory" patterns
+
+Live code & coffee. Sujet proposé par le chat : les patterns factory.
+
+But de ces patterns : constuire des objets cohérents
+
+## Static factory
+
+Utilisation de méthodes statiques pour construire nos objets. Exemple dans `Firstname`.
+
+Cas d'utilisation :
+
+-   Constuire un objet en ajoutant du sens grace au nom de la méthode ;
+-   Fermer l'extension (avec un constructeur privé) ;
+-   Permettre l'utilisation d'un cache ;
+-   Renvoyer un type différent (ex: Optional<T>).
+
+## Builder
+
+Objet mutable pour constuire des objets cohérents. Ils fournissent une API fluent (comme une phrase) pour construire sans ambiguité des objets complexes. Exemple dans `Person`.
+
+## Factory method
+
+On délégue une partie des responsabilité d'un objet à un tiers. Les enfants de notre objet doivent implémenter une méthode fournissant ce tiers. De cette manière on peut avoir une logique générale dans le parent et des spécificité dans chaque enfant.
+
+## Abstract factory
+
+Abstract factory permet de construire des objets abstraits en choisissant l'implémentation en fonction d'une clé. Dans ce cas on va créer une implémentation de factory par type d'objet a créer et utiliser cette implémentation pour construire nos objets en fonction de la clé.
diff --git a/factory-patterns/src/main/java/fr/ippon/factory/Firstname.java b/factory-patterns/src/main/java/fr/ippon/factory/Firstname.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed7c1654c7ca6d98611881512fa1a4cbc5665295
--- /dev/null
+++ b/factory-patterns/src/main/java/fr/ippon/factory/Firstname.java
@@ -0,0 +1,31 @@
+package fr.ippon.factory;
+
+import java.util.Optional;
+
+public class Firstname {
+  private final String firstname;
+
+  public Firstname(String firstname) {
+    assertFirstname(firstname);
+
+    this.firstname = firstname;
+  }
+
+  private void assertFirstname(String firstname) {
+    if (firstname == null) {
+      throw new IllegalArgumentException();
+    }
+  }
+
+  public static Optional<Firstname> of(String firstname) {
+    if (firstname == null) {
+      return Optional.empty();
+    }
+
+    return Optional.of(new Firstname(firstname));
+  }
+
+  public String get() {
+    return firstname;
+  }
+}
diff --git a/factory-patterns/src/main/java/fr/ippon/factory/Lastname.java b/factory-patterns/src/main/java/fr/ippon/factory/Lastname.java
new file mode 100644
index 0000000000000000000000000000000000000000..b5fc20ef01a132a9903daa1ac01d19ef2ef38df2
--- /dev/null
+++ b/factory-patterns/src/main/java/fr/ippon/factory/Lastname.java
@@ -0,0 +1,21 @@
+package fr.ippon.factory;
+
+public class Lastname {
+  private final String lastname;
+
+  public Lastname(String lastname) {
+    assertLastname(lastname);
+
+    this.lastname = lastname;
+  }
+
+  private void assertLastname(String lastname) {
+    if (lastname == null) {
+      throw new IllegalArgumentException();
+    }
+  }
+
+  public String get() {
+    return lastname;
+  }
+}
diff --git a/factory-patterns/src/main/java/fr/ippon/factory/Person.java b/factory-patterns/src/main/java/fr/ippon/factory/Person.java
new file mode 100644
index 0000000000000000000000000000000000000000..77c9854759e1f16e9ee7fd07d588b8da298bbee5
--- /dev/null
+++ b/factory-patterns/src/main/java/fr/ippon/factory/Person.java
@@ -0,0 +1,44 @@
+package fr.ippon.factory;
+
+public class Person {
+  private final Firstname firstname;
+  private final Lastname lastname;
+
+  private Person(PersonBuilder builder) {
+    firstname = new Firstname(builder.firstname);
+    lastname = new Lastname(builder.lastname);
+  }
+
+  public static PersonBuilder builder() {
+    return new PersonBuilder();
+  }
+
+  public Firstname getFirstname() {
+    return firstname;
+  }
+
+  public Lastname getLastname() {
+    return lastname;
+  }
+
+  public static class PersonBuilder {
+    private String firstname;
+    private String lastname;
+
+    public PersonBuilder firstname(String firstname) {
+      this.firstname = firstname;
+
+      return this;
+    }
+
+    public PersonBuilder lastname(String lastname) {
+      this.lastname = lastname;
+
+      return this;
+    }
+
+    public Person build() {
+      return new Person(this);
+    }
+  }
+}
diff --git a/factory-patterns/src/test/java/fr/ippon/factory/FirstnameTest.java b/factory-patterns/src/test/java/fr/ippon/factory/FirstnameTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..208283199613c2cf9a7b419395c3cc7725a48d15
--- /dev/null
+++ b/factory-patterns/src/test/java/fr/ippon/factory/FirstnameTest.java
@@ -0,0 +1,28 @@
+package fr.ippon.factory;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+public class FirstnameTest {
+
+  @Test
+  void shouldNotBuildWithoutFirstname() {
+    assertThatThrownBy(() -> new Firstname(null)).isExactlyInstanceOf(IllegalArgumentException.class);
+  }
+
+  @Test
+  void shouldGetFirstname() {
+    assertThat(new Firstname("Jean").get()).isEqualTo("Jean");
+  }
+
+  @Test
+  void shouldGetEmptyFirstnameWithoutFirstname() {
+    assertThat(Firstname.of(null)).isEmpty();
+  }
+
+  @Test
+  void shouldGetFirstnameFromActualFirstname() {
+    assertThat(Firstname.of("Jean").get().get()).isEqualTo("Jean");
+  }
+}
diff --git a/factory-patterns/src/test/java/fr/ippon/factory/LastnameTest.java b/factory-patterns/src/test/java/fr/ippon/factory/LastnameTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e0345f3960d359a1429fe7c597f13ef470ed9682
--- /dev/null
+++ b/factory-patterns/src/test/java/fr/ippon/factory/LastnameTest.java
@@ -0,0 +1,18 @@
+package fr.ippon.factory;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+public class LastnameTest {
+
+  @Test
+  void shouldNotBuildWithoutLastname() {
+    assertThatThrownBy(() -> new Lastname(null)).isExactlyInstanceOf(IllegalArgumentException.class);
+  }
+
+  @Test
+  void shouldGetLastname() {
+    assertThat(new Lastname("Dupont").get()).isEqualTo("Dupont");
+  }
+}
diff --git a/factory-patterns/src/test/java/fr/ippon/factory/PersonTest.java b/factory-patterns/src/test/java/fr/ippon/factory/PersonTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0ce32af78855ded7548a0aabee730d20aa6a2a34
--- /dev/null
+++ b/factory-patterns/src/test/java/fr/ippon/factory/PersonTest.java
@@ -0,0 +1,17 @@
+package fr.ippon.factory;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+public class PersonTest {
+
+  @Test
+  void shouldGetPersonInformation() {
+    Person person = Person.builder().firstname("Jean").lastname("Dupont").build();
+
+    assertThat(person.getFirstname()).usingRecursiveComparison().isEqualTo(new Firstname("Jean"));
+
+    assertThat(person.getLastname()).usingRecursiveComparison().isEqualTo(new Lastname("Dupont"));
+  }
+}