[JAVA] Ich habe das Mediator-Muster verwendet, um ein Flussüberquerungs-Puzzle auszudrücken.

Der letzte Vollzeitbeschäftigte ist ein Onkel, der den Betrieb verbessert. Ich studiere Designmuster neu.

Zum besseren Verständnis des Mediator-Musters Als Beispielcode denke ich, dass es die N-te Abkochung ist ... Ich habe das Flussüberquerungspuzzle als Code verwendet.

Es ist kein Programm, das die Antwort auf das Rätsel der Flussüberquerung findet Es ist ein Programm, das ein Flussüberquerungsrätsel simuliert.

Wenn Sie beim Erkennen von Mediator einen Fehler machen, Wenn Sie möchten, würde ich es begrüßen, wenn Sie darauf hinweisen könnten.

Umgebung

Flussüberquerung Puzzle

Das ist der berühmte. Von diesem Ufer aus können Sie mit einem Schiff zum anderen Ufer fahren.

Ich denke, es gibt verschiedene Charaktere, die erscheinen, Dieses Mal habe ich Bauern, Wölfe, Ziegen und Kohl ausgewählt.

Nur Bauern können ein Schiff rudern. Nur der Bauer und ein anderer Charakter können an Bord des Schiffes gehen. Wenn ein Wolf oder eine Ziege zurückgelassen wird, wenn sich kein Bauer am selben Ufer befindet, frisst der Wolf die Ziege. Wenn Sie Ziegen und Kohl zurücklassen, wenn sich kein Bauer am selben Ufer befindet, fressen die Ziegen den Kohl.

Wie kann ich die andere Seite des Flusses sicher überqueren? Das ist.

Annahme

Farmer.java, Chabbage.java, Goat.java, Wolf.java, Es erbt Folgendes:

CharacterBase.java


public abstract class CharacterBase implements Character {
    private Position position;
    private Status status;

    public CharacterBase() {
        this.position = Position.FRONT;
        this.status = Status.ALIVE;
    }

    @Override
    public Status getStatus() {
        return this.status;
    }

    @Override
    public void setStatus(Status status) {
        this.status = status;
    }

    @Override
    public Position getPosition() {
        return this.position;
    }

    @Override
    public void setPosition(Position position) {
        this.position = position;
    }

    @Override
    public void cross() {
        switch (this.getPosition()) {
        case FRONT:
            this.setPosition(Position.BEYOND);

            break;

        case BEYOND:
            this.setPosition(Position.FRONT);

            break;

        default:
            break;
        }
    }

}

Auch nur Farmer.java, Implementiert die Kreuzmethode (Zeichen mit Zeichen).

Farmer.java


public class Farmer extends CharacterBase {
    public void cross(Character withCharacter) {
        if (withCharacter == null) {
            throw new IllegalArgumentException("Bitte geben Sie das zu kreuzende Zeichen an.");
        }

        if (withCharacter instanceof Farmer) {
            throw new IllegalArgumentException("Sie können keinen Landwirt angeben.");
        }

        if (!this.getPosition().equals(withCharacter.getPosition())) {
            throw new IllegalArgumentException("Nur Zeichen an derselben Position können sich kreuzen.");

        }

        this.cross();
        withCharacter.cross();
    }
}

Ohne Vermittler

Weil es keine Klasse gibt, die alle Charaktere kennt Überprüfen Sie den Status einzeln in der Ausführungsklasse. Ich muss die Statistiken meines Charakters aktualisieren.

CrossRiverExecutor.java



public class CrossRiverExecutor {
    private Farmer farmer;
    private Wolf wolf;
    private Goat goat;
    private Cabbage cabbage;

    public CrossRiverExecutor(Farmer farmer, Wolf wolf, Goat goat, Cabbage cabbage) {
        this.farmer = farmer;
        this.wolf = wolf;
        this.goat = goat;
        this.cabbage = cabbage;
    }

    public void execute() {
        farmer.cross(goat);
        //Dieses Ufer: Wolf, Kohl
        //Die andere Seite: Bauer, Ziege
        updateStatus();

        farmer.cross();
        //Dieses Ufer: Bauer, Wolf, Kohl
        //Die andere Seite: Ziege
        updateStatus();

        farmer.cross(cabbage);
        //Dieses Ufer: Wolf
        //Die andere Seite: Bauer, Ziege, Kohl
        updateStatus();

        farmer.cross(goat);
        //Dieses Ufer: Bauer, Ziege, Wolf
        //Die andere Seite: Kohl
        updateStatus();

        farmer.cross(wolf);
        //Dieses Ufer: Ziege
        //Die andere Seite: Bauer, Wolf, Kohl
        updateStatus();

        farmer.cross();
        //Dieses Ufer: Bauer, Ziege
        //Die andere Seite: Wolf, Kohl
        updateStatus();

        farmer.cross(goat);
        //Dieses Ufer:
        //Die andere Seite: Bauern, Wölfe, Ziegen, Kohl
        updateStatus();
    }


    private void updateStatus() {
        if (!farmer.getPosition().equals(goat.getPosition()) && wolf.getPosition().equals(goat.getPosition())) {
            goat.setStatus(Status.DEAD);
        }

        if (!farmer.getPosition().equals(cabbage.getPosition()) && cabbage.getPosition().equals(goat.getPosition())) {
            cabbage.setStatus(Status.DEAD);
        }
    }
}


Ich denke, Sie können immer noch das Rätsel der Flussüberquerung ausdrücken, Es ist schwer zu lesen und die updateStatus-Methode zu testen. Ich denke nicht, dass der Code in einem sehr guten Zustand ist.

Wenn Sie einen Mediator haben

Bereiten Sie Mediator hier darauf vor, den gesamten Charakter zu kennen.

CrossRiverMediator.java



public class CrossRiverMediator implements CrossRiver {
    private Farmer farmer;
    private Wolf wolf;
    private Goat goat;
    private Cabbage cabbage;

    public CrossRiverMediator(Farmer farmer, Wolf wolf, Goat goat, Cabbage cabbage) {
        this.farmer = farmer;
        this.wolf = wolf;
        this.goat = goat;
        this.cabbage = cabbage;
    }

    @Override
    public void cross(Character character) {

        switch (character.getPosition()) {
        case FRONT:
            character.setPosition(Position.BEYOND);

            break;

        case BEYOND:
            character.setPosition(Position.FRONT);

            break;

        default:
            break;
        }
    }

    @Override
    public void cross(Farmer character, Character withCharacter) {
        if (withCharacter == null) {
            throw new IllegalArgumentException("Bitte geben Sie das zu kreuzende Zeichen an.");
        }

        if (withCharacter instanceof Farmer) {
            throw new IllegalArgumentException("Sie können keinen Landwirt angeben.");
        }

        if (!character.getPosition().equals(withCharacter.getPosition())) {
            throw new IllegalArgumentException("Nur Zeichen an derselben Position können sich kreuzen.");

        }

        character.cross();
        withCharacter.cross();
        updateStatus();
    }

    private void updateStatus() {
        if (!farmer.getPosition().equals(goat.getPosition()) && wolf.getPosition().equals(goat.getPosition())) {
            goat.setStatus(Status.DEAD);
        }

        if (!farmer.getPosition().equals(cabbage.getPosition()) && cabbage.getPosition().equals(goat.getPosition())) {
            cabbage.setStatus(Status.DEAD);
        }

    }
}


Weil ich alle Charaktere kenne Sie können die updateStatus-Methode ausführen, um Leben und Tod jedes Charakters zu aktualisieren.

Auch zusammen mit dem CharacterBase.java, die übergeordnete Klasse jedes Zeichens, Die cross () Methode und die cross (Character) Methode von Farmer.java, Ändern Sie es so, dass es über Mediator ausgeführt wird.

CharacterBase.java



public abstract class CharacterBase implements Character {
    protected CrossRiver crossRiver;
    private Position position;
    private Status status;

    public CharacterBase() {
        this.position = Position.FRONT;
        this.status = Status.ALIVE;
    }

    @Override
    public void setMediator(CrossRiver crossRiver) {
        this.crossRiver = crossRiver;
    }

    @Override
    public Status getStatus() {
        return this.status;
    }

    @Override
    public void setStatus(Status status) {
        this.status = status;
    }

    @Override
    public Position getPosition() {
        return this.position;
    }

    @Override
    public void setPosition(Position position) {
        this.position = position;
    }

    @Override
    public void cross() {
        this.crossRiver.cross(this);
    }
}

Farmer.java



public class Farmer extends CharacterBase {
    public void cross(Character withCharacter) {
        this.crossRiver.cross(this, withCharacter);
    }
}

Dann wird die Ausführungsklasse Es wird wie folgt sein.

CrossRiverExecutor.java



public class CrossRiverExecutor {
    private Farmer farmer;
    private Wolf wolf;
    private Goat goat;
    private Cabbage cabbage;
    private CrossRiverMediator crossRiver;

    public CrossRiverExecutor() {
        farmer = new Farmer();
        wolf = new Wolf();
        goat = new Goat();
        cabbage = new Cabbage();

        crossRiver = new CrossRiverMediator(farmer, wolf, goat, cabbage);
        farmer.setMediator(crossRiver);
        wolf.setMediator(crossRiver);
        goat.setMediator(crossRiver);
        cabbage.setMediator(crossRiver);
    }

    public void execute() {
        farmer.cross(goat);     //Dieses Ufer: Wolf, Kohl Das andere Ufer: Bauer, Ziege
        farmer.cross();         //Dieses Ufer: Bauer, Wolf, Kohl Das andere Ufer: Ziege
        farmer.cross(cabbage);  //Dieses Ufer: Wolf Das andere Ufer: Bauer, Ziege, Kohl
        farmer.cross(goat);     //Dieses Ufer: Bauer, Ziege, Wolf Anderes Ufer: Kohl
        farmer.cross(wolf);     //Dieses Ufer: Ziege Das andere Ufer: Bauer, Wolf, Kohl
        farmer.cross();         //Dieses Ufer: Bauer, Ziege Das andere Ufer: Wolf, Kohl
        farmer.cross(goat);     //Dieses Ufer: Das andere Ufer: Bauern, Wölfe, Ziegen, Kohl
    }
}

Daher kann die Logik von der Ausführungsklasse getrennt werden. Wenn Sie die Logik testen, müssen Sie nur den Mediator testen. Ich denke, es ist ein relativ guter Code.

Ergebnis

Ich konnte ein Flussüberquerungspuzzle programmieren. https://github.com/naokiur/design-pattern-sample/tree/master/src/main/java/jp/ne/naokiur/design/pattern/mediator

Ich habe es als Referenz verwendet

https://github.com/iluwatar/java-design-patterns http://language-and-engineering.hatenablog.jp/entry/20120330/p1

Recommended Posts

Ich habe das Mediator-Muster verwendet, um ein Flussüberquerungs-Puzzle auszudrücken.
Ich habe versucht, die verwendeten Methoden zusammenzufassen
Ich habe versucht, das Iterator-Muster zu implementieren
Code zum Verbinden von Rails 3 mit PostgreSQL 10
Ich möchte der Kommentarfunktion eine Löschfunktion hinzufügen
Ich möchte eine Methode aufrufen und die Nummer zählen
Ich möchte dem select-Attribut einen Klassennamen geben
Ich habe versucht, die Ergebnisse vor und nach der Date-Klasse mit einer geraden Zahl auszudrücken
Ich habe versucht, den Weihnachtsbaum in einem Lebensspiel zu beleuchten
Ich habe ein Juwel gemacht, um den Text des Org-Modus in Qiita zu posten
[Java] Ich habe versucht, mit der Grabmethode ein Labyrinth zu erstellen ♪
Ich habe ein Tool erstellt, um den Unterschied zwischen CSV-Dateien auszugeben
Ich habe versucht, die Methode zu erklären
[Rails] Ich habe etwas über Migrationsdateien gelernt! (Hinzufügen einer Spalte zur Tabelle)
Eine Geschichte, der ich beim Testen der API mit MockMVC verfallen war
Ich kann nicht bauen, wenn ich das Build-Ziel mit XCode12 auf einen Simulator setze!
Es war ein Leben, in dem ich den thread-sicheren assoziativen Zähler zurücksetzen wollte
Ich habe Docker verwendet, um die Vorlage zu verfestigen, die mit Spring Boot entwickelt werden soll.