[JAVA] DDD persönliche Notizen

Einführung

Verschiedene Gefühle auf dem Weg

――Wenn Sie die Erläuterungen zum Domain-Modell und zum Domain-Service lesen, bin ich der festen Überzeugung, dass die Kenntnis der Geschäftsregeln zu einer Problemisolierung führen wird.

Hmmm, ich habe das Gefühl, dass die Todo-App ein schlechtes Beispiel hat. Im Fall von Todo bleibt keine andere Wahl, als es einzugeben oder zu löschen, und es gibt fast keine Berechnung. Die einzige Berechnung, die ein Sammlungsobjekt haben sollte, besteht darin, DueDate in aufsteigender Reihenfolge zu sortieren, Favoriten (true) zu sammeln und sie vorne und den Rest hinten auszurichten. Sie können die Verdaulichkeit von Task berechnen. Es gibt keine Verantwortung, etwas mit einem Todo zu berechnen.

layer

+-- domain
|    |
|    +-- model
|    |    |
|    |    +-- Entity -- Aggregate
|    |    |
|    |    `-- Value Object
|    |
|    +-- Factory
|    |
|    +-- Repository ( command , query )
|    |
|    +-- Service
|    |
|    `-- ( shared )
|
+-- infrastructure - service
|    |                |
|    |                `-- ( mail sender )
|    |
|    `-- ( Repository Implementation )
|         |
|         +-- ( db I/O )
|         |
|         +-- ( file I/O )
|         |
|         `-- ( cache I/O )
|
+-- application -- Service
|
`-- interfaces
     |
     +-- ( controller )
     |    |
     |    `-- ( REST )
     |          |
     |          +-- ( XML )
     |          |
     |          `-- ( JSON )
     |
     +-- ( view )
     |    |
     |    `-- ( HTML )
     |
     `-- ( socket )


domain model

Nachschlagewerke:

--Konzept / Erklärung

Entity

Entitätsübersicht



//Andere Variablenattribute als Bezeichner
//Weil die Attribute in dieser Klasse unabhängig voneinander sind@Setter ist angegeben
//Wenn Attribute miteinander verknüpft sind, führen Sie Attributoperationen über diese Klasse von Geschäftslogik aus.
@Getter
@Setter
public final class Todo extends AbstractEntity<Todo> implements ValueObject {

    // (AbstractEntity::private final UUID identifier)
    private Title title;
    private DueDate dueDate;
    private TaskList taskList;
    private Memo memo;
    private Favorite favorite;

    public Todo(final EntityIdentifier<Todo> identifier, final Title title, final DueDate dueDate, final TaskList taskList, final Memo memo, final Favorite favorite) {
        super(identifier);
        Validate.notNull(title);
        Validate.notNull(dueDate);
        Validate.notNull(taskList);
        Validate.notNull(memo);
        Validate.notNull(favorite);

        this.title = title;
        this.dueDate = dueDate;
        this.taskList = taskList;
        this.memo = memo;
        this.favorite = favorite;
    }

    @Override
    public Todo clone() {
        return super.clone();
    }

    @Override
    public boolean equals(final Object that) {
        if (this == that) {
            return true;
        }
        if (that == null || getClass() != that.getClass()) {
            return false;
        }
        Todo o = (Todo) that;
        if(!entityIdentifier.equals(o.entityIdentifier)){
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int result = Objects.hashCode(entityIdentifier);
        result = 31 * result;
        return result;
    }
}

Value Object

ValueObject-Übersicht



// ----Grundsätzlich das--------------------------

//Attribute sind unveränderlich
@Getter
public final class Task implements ValueObject {
    private final String value;
    private final Boolean done;

    public Task(final String value) {
        Validate.notNull(value);

        this.value = value;
        this.done = false;
    }

    public Task(final String value, final Boolean done) {
        Validate.notNull(value);
        Validate.notNull(done);

        this.value = value;
        this.done = done;
    }

    @Override
    public boolean equals(final Object that) {
        if (this == that) {
            return true;
        }
        if (that == null || getClass() != that.getClass()) {
            return false;
        }
        Task o = (Task) that;
        if (!value.equals(o.value)) {
            return false;
        }
        if (!done.equals(o.done)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int result = Objects.hashCode(value);
        result = 31 * result + Objects.hashCode(done);
        return result;
    }
}



// ----Haben Sie ein Wertobjekt im Kind--------------------------

//Attribute sind unveränderlich
//Wenn es sich bei dem Attribut jedoch um ein Objekt wie List handelt, ist ein gewisser Einfallsreichtum erforderlich.
public final class TaskList implements ValueObjectList<TaskList, Task> {
    private final List<Task> taskList;

    public TaskList() {
        taskList = Collections.unmodifiableList(new ArrayList<>());
    }

    public TaskList(final List<Task> list) {
        Validate.notNull(list);

        // unmodifiableList()Der Grund ist
        //Liste, die durch Übergabe als Referenz zurückgegeben wird<Task>Stellen Sie sicher, dass der Inhalt nicht neu geschrieben werden kann
        //Wenn Sie es neu schreiben möchten, möchten Sie die Verwendung des Konstruktors erzwingen.
        //Da die endgültige Deklaration auch im Element nicht funktioniert, wird sie an dieser Stelle auch im deklarativen Sinne verwendet.
        taskList = Collections.unmodifiableList(list);
    }

/*
  Collections.unmodifiableList()Der Grund für die Verwendung
Wenn Sie es nicht verwenden, wird der folgende Testcode nicht bestanden und Sie können nicht garantieren, dass sich die Attribute nicht ändern.

Wenn Sie taskList verwenden.set(0, after)UnsupportedOperationException tritt in auf
Wenn Sie das Element ArrayList neu schreiben möchten<>(taskList)Durch Übergabe an den Konstruktor von TaskList
Beim Umschreiben der Elemente kann garantiert werden, dass die Attribute unveränderlich sind (= ein anderes Objekt mit anderen Attributen, da der Konstruktor verwendet wird).

        TaskList target = new TaskList();

        Task before = new Task("Milch kaufen", false);
        target.add(before);
        assertEquals(1, target.getList().size());

        //Überschreiben Sie den ersten Teil der abgerufenen Liste mit einem anderen Objekt
        List<Task> taskList = target.getList();
        Task after = new Task("Milch verkaufen", true);
        taskList.set(0, after);

        //Der überschriebene Betrag wird nicht in der Variablen berücksichtigt, bevor er vor dem Überschreiben gesichert wurde.
       assertEquals(before.getFavorite(), target.getList().get(0).getFavorite());
 */

    private static void accept(final Task w) {
    }

    public Optional<Task> find(final Task searchTask) {
        Validate.notNull(searchTask);

        Optional<Task> ret = Optional.empty();

        for (Task existTask : getList()) {
            if (existTask.equals(searchTask)) {
                ret = Optional.of(existTask);
                break;
            }
        }

        return ret;
    }

    public List<Task> getList() {
        return taskList;
    }

    public TaskList add(final Task... t) {
        Arrays.stream(t).forEach(Validate::notNull);

        List<Task> result = new ArrayList<>(taskList);
        Arrays.stream(t).forEach(
                v -> find(v).ifPresentOrElse(
                        TaskList::accept,
                        () -> result.add(v)
                )
        );

        return new TaskList(result);
    }

/*
Der Grund, mich zu regenerieren und zurückzukehren, ist
Internes Attribut ist Sammlungen#unmodifiableList()Es kann nicht geändert werden, da es sich nicht geändert hat.

Als Einschränkung List#add(Object):Wenn Sie es als Booleschen Wert verwenden, wird dies nicht aktualisiert und Sie erhalten keine neuen Werte.
*/

    public TaskList remove(final Task... t) {
        Arrays.stream(t).forEach(Validate::notNull);

        List<Task> result = new ArrayList<>(taskList);
        Arrays.stream(t).forEach(
                v -> find(v).ifPresent(result::remove)
        );

        return new TaskList(result);
    }

    @Override
    public boolean equals(final Object that) {
        if (this == that) {
            return true;
        }
        if (that == null || getClass() != that.getClass()) {
            return false;
        }
        TaskList o = (TaskList) that;
        if (!taskList.equals(o.taskList)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int result = Objects.hashCode(taskList);
        result = 31 * result;
        return result;
    }
}

factory

Werksübersicht


public class TodoFactory implements EntityFactory<Todo> {

    @Override
    public Todo create() {
        return create("");
    }

    @Override
    public Todo create(final EntityIdentifier<Todo> identifier) {
        Validate.notNull(identifier);

        Title t = new Title("");
        DueDate d = new DueDate();
        TaskList l = new TaskList();
        Memo m = new Memo();
        Favorite f = new Favorite();

        return new Todo(identifier, t, d, l, m, f);
    }

    /**
     * {@link Title}Angeben{@link Todo}erstellen
     *
     * @param title
     * @return
     */
    public Todo create(final String title) {
        Validate.notNull(title);

        EntityIdentifier<Todo> identifier = new DefaultEntityIdentifier<>(Todo.class, UUID.randomUUID());
        Title t = new Title(title);
        DueDate d = new DueDate();
        TaskList l = new TaskList();
        Memo m = new Memo();
        Favorite f = new Favorite();

        return new Todo(identifier, t, d, l, m, f);
    }
}

repository

Anhäufung

domain service

  1. Die Operation beinhaltet das Konzept einer Domäne, die kein ** natürlicher Bestandteil einer Entität oder eines Wertobjekts ** ist.
  2. Die Schnittstelle wird aus der Perspektive ** anderer Elemente des Domänenmodells ** definiert.
  3. Es gibt keinen ** Zustand in der Operation **.

application service

infrastructure service

interfaces

--GET / POST / PUT / DELETE und andere Orte zum Empfangen

Recommended Posts

DDD persönliche Notizen
spielen Framework persönliche Notizen
Apache POI persönliches Memo Crossfish21
Persönliche Notizen des First Play Framework
In Liste sortieren, für persönliches Memo
JUnit 4 Notizen
Java Note
synchronisierte Notizen
Rails-Validierung und null: false Persönliche Notizen