So lösen Sie Ausdrucksprobleme in Java

Was ist ein Ausdrucksproblem?

http://maoe.hatenadiary.jp/entry/20101214/1292337923

Wie kann ich neue Datentypen oder neue Funktionen in einer statisch typisierten Sprache hinzufügen, ohne sie neu zu kompilieren?

Ist das Problem. Wenn Sie eine Klasse ohne nachzudenken entwerfen,

  1. Einfach hinzuzufügende Datenstruktur, aber schwierig hinzuzufügende Operation
  2. Einfach hinzuzufügende Operationen, aber schwierig hinzuzufügende Datenstrukturen Es ist auch leicht zu werden. Das Problembewusstsein des Ausdrucksproblems besteht darin, wie Datenstrukturen und Operationen hinzugefügt werden.

Java-Lösung

Haskell, OCaml, Scala usw. sind bereits für Lösungen mit erweiterten Sprachfunktionen (?) Berühmt. Es wird jedoch gezeigt, dass das Ausdrucksproblem auch mit Java-Sprachfunktionen gelöst werden kann.

  1. Verwendung der Untertypisierung + Kovariation des Rückgabewerts
  2. Verwendung von Subtyping + Generics

Es gibt die beiden oben genannten Methoden. Dieser Artikel stellt zwei Methoden vor.

Beispiel

Betrachten Sie zunächst einen einfachen Interpreter als Beispiel. Beachten Sie, dass Lombok zur Vereinfachung des Codes verwendet wird.

import lombok.AllArgsConstructor;
import lombok.Data;

interface Exp {
    int eval();
}

@Data
@AllArgsConstructor
class Add<E extends Exp> implements Exp {
    private E e1;
    private E e2;

    @Override
    public int eval() {
        return e1.eval() + e2.eval();
    }
}

@Data
@AllArgsConstructor
class Lit implements Exp {
    private int x;

    @Override
    public int eval() {
        return x;
    }
}

Die Stelle, an der das Feld der Add-Klasse ein Typparameter namens E ist, ist ein Fehler.

Operation hinzufügen

Fügen Sie dieser Klasse einen Druckvorgang hinzu.

interface ExpP extends Exp {
    String print();
}

class LitP extends Lit implements ExpP {

    LitP(int x) {
        super(x);
    }

    @Override
    public String print() {
        return String.valueOf(getX());
    }
}

class AddP<E extends ExpP> extends Add<E> implements ExpP {

    AddP(E e1, E e2) {
        super(e1, e2);
    }

    @Override
    public String print() {
        return getE1().print() + " + " + getE2().print();
    }
}

Ich konnte die vorhandene Klasse problemlos hinzufügen.

Klasse hinzufügen

Fügen Sie eine Klasse hinzu, die Sub darstellt (Subtraktion).

@Data
@AllArgsConstructor
class Sub<E extends Exp> implements Exp {
    private E e1;
    private E e2;

    @Override
    public int eval() {
        return e1.eval() - e2.eval();
    }
}

class SubP<E extends ExpP> extends Sub<E> implements ExpP {

    SubP(E e1, E e2) {
        super(e1, e2);
    }

    @Override
    public String print() {
        return getE1().print() + " - " + getE2().print();
    }
}

In beiden Fällen können Operationen hinzugefügt / Klassen hinzugefügt werden, ohne die vorhandene Klasse zu ändern. Die Klasse, die diese verwendet, ist wie folgt.

public class Main {

    public static void main(String[] args) {
        new Add<Exp>(new Lit(1), new Lit(3)).eval();
        new Sub<Exp>(new Lit(1), new Lit(3)).eval();

        new AddP<ExpP>(new LitP(1), new LitP(3)).print();
        new SubP<ExpP>(new LitP(1), new LitP(3)).print();
    }
}

In Situationen, in denen eine hohe Erweiterbarkeit erforderlich ist (von denen erwartet wird, dass sie sowohl die Datenstruktur als auch den Betrieb erweitern), lohnt es sich, sich an dieses Entwurfsmuster zu erinnern (unbekannter Name?). Wenn Sie sich auch für die Methode "Verwenden von Subtypisierung + Kovariation des Rückgabewerts" interessieren, lesen Sie bitte die folgenden Referenzen. (* Der Inhalt dieses Artikels ist das runde Pakuri des folgenden Papiers.)

Verweise

Wang, Yanlin, and Bruno C. D. S. Oliveira. "The expression problem, trivially!." Proceedings of the 15th International Conference on Modularity. ACM, 2016.

Recommended Posts

So lösen Sie Ausdrucksprobleme in Java
Versuchen Sie, ein eingeschränktes FizzBuzz-Problem in Java zu lösen
Wie man JAVA in 7 Tagen lernt
Versuchen Sie einen If-Ausdruck in Java
Wie verwende ich Klassen in Java?
So benennen Sie Variablen in Java
So verketten Sie Zeichenfolgen mit Java
Was ist in "Java 8 bis Java 11" passiert und wie wird eine Umgebung erstellt?
So implementieren Sie die Datumsberechnung in Java
So implementieren Sie den Kalman-Filter mit Java
Mehrsprachige Unterstützung für Java Verwendung des Gebietsschemas
Versuchen Sie, Project Euler in Java zu lösen
So führen Sie eine Basiskonvertierung in Java durch
So erzwingen Sie Codierungskonventionen in Java
Einbetten von Janus Graph in Java
So erhalten Sie das Datum mit Java
So beheben Sie den unbekannten Fehler, der bei der Verwendung von slf4j in Java aufgetreten ist
So ermitteln Sie die Länge einer Audiodatei mit Java
Ich möchte eine E-Mail in Java senden.
So zeigen Sie eine Webseite in Java an
Zweite Abkochung: Versuchen Sie einen If-Ausdruck in Java
So erhalten Sie eine Klasse von Element in Java
Verwendung der Java-API mit Lambda-Ausdrücken
So verbergen Sie Nullfelder als Antwort in Java
Ich möchte für jedes Array mit Lambda-Ausdruck in Java
So erstellen Sie ein ausführbares JAR in Maven
Wie schreibe ich Java String # getBytes in Kotlin?
[Java] Versuchen Sie, das Fizz Buzz-Problem zu lösen
So machen Sie ein Bild mit Processing teilweise transparent
Aufrufen von Funktionen in großen Mengen mit Java Reflection
So erstellen Sie eine Java-Umgebung in nur 3 Sekunden
[Java] So lassen Sie den privaten Konstruktor in Lombok weg
Wie kann ich IBM Mainframe-Dateien in Java eingeben / ausgeben?
[Java] Ich habe versucht, Paizas B-Rang-Problem zu lösen
So erstellen Sie einen Daten-URI (base64) in Java
So konvertieren Sie A in a und a in A mit logischem Produkt und Summe in Java
So konvertieren Sie eine Datei in ein Byte-Array in Java
Zusammenfassung der Implementierung von Standardargumenten in Java
Wie man altes Java (8er) in macOS 10.15 Catalina einfügt
[Schienen] So zeigen Sie Bilder in der Ansicht an
Hinweise zur Verwendung regulärer Ausdrücke in Java
So senken Sie die Java-Version
So deinstallieren Sie Java 8 (Mac)
Java - So erstellen Sie JTable
Verwendung von Java Optional
So minimieren Sie Java-Images
Wie schreibe ich einen Java-Kommentar
Verwendung der Java-Klasse
[Java] Verwendung von removeAll ()
[Java] So zeigen Sie Wingdings an
Verwendung von Java Map
So legen Sie Java-Konstanten fest
Verwendung von Java-Variablen