[JAVA] Realisieren Sie eine Entscheidungstabelle ohne bedingte Verzweigung

1. Zuallererst

Dieses Mal hatte ich die Gelegenheit, die in der Entscheidungstabelle organisierten Spezifikationen zu implementieren, daher möchte ich erklären, wie ein Programm implementiert wird, das gemäß der Definition funktioniert.

Eine Entscheidungstabelle ist eine Tabelle, in der mögliche Bedingungen und Aktionen für ein bestimmtes Problem zusammengefasst sind. Weitere Informationen finden Sie auf der leicht verständlichen Website "Erklärung der Entscheidungstabelle". Die Entscheidungstabelle (Rabattberechnung der Parkgebühr) und die folgende Abbildung, die Gegenstand dieser Zeit sind, werden ebenfalls auf dieser Website zitiert.

Zustandsbeschreibungsteil (Zustandsstummel) Bedingungseintrag
photo_2.png photo_4.png
Aktionsbeschreibungsteil (Aktionsstub) Aktionseintrag
photo_3.png photo_5.png

Die in diesem Artikel erläuterten Inhalte lauten wie folgt.

2. Implementierung der Entscheidungstabelle

class-structure.jpg

Es ist einzigartig, dass jede der Bedingungen auf Regel gesetzt ist, aber ich habe versucht, die Klasse so zu gestalten, dass sie genauso konsistent ist wie das Erscheinungsbild der Entscheidungstabelle. Als Ergebnis konnten wir dies mit 6 Klassen (3 Schnittstellen und 1 abstrakte Klasse) realisieren. Wie Sie dem Inhalt entnehmen können, wird es nur mit Standard-Java-Funktionen und ohne bedingte Verzweigung implementiert.

2.1. DecisionAction

Dies ist eine Schnittstelle zum Definieren von Aktionen, die die Beurteilungsergebnisse der Entscheidungstabelle sind. Der Inhalt kann gemäß der Entscheidungstabelle, die Sie realisieren möchten, frei definiert werden.

DecisionAction.java


public interface DecisionAction {

}

2.2. RuleInput

Eine Schnittstelle zum Definieren der Eingabedaten von Rule.

RuleInput.java


public interface RuleInput {

}

2.3. Rule

Eine Schnittstelle zum Implementieren einer bedingten Beurteilungslogik. Implementieren Sie den Prozess, um eine Bedingung in der Methode "Object Evaluate (RuleInput Input)" zu beurteilen. Der Rückgabewert ist der Wert, der bei der Beurteilung des Zustandsspezifikationsteils verwendet wird. Jeder Standard-Java-Datentyp (gültiger Wert, Zeichenfolgentyp, numerischer Typ) ist ausreichend.

Rule.java


public interface Rule<I extends RuleInput> {

    Object evaluate(RuleInput input);

    @SuppressWarnings("unchecked")
    default I getInput(RuleInput input) {
        return (I) input;
    };
}

2.4. ConditionStub

Diese Klasse ist ein Argument bei der Ausführung eines bedingten Urteils. Wie Sie sehen können, ist es nur ein Halter für Regel und Regeleingabe.

ConditionStub.java


public class ConditionStub {

    private Map<Rule<? extends RuleInput>, RuleInput> rules = new HashMap<>();

    public void when(Rule<? extends RuleInput> rule, RuleInput input) {
        rules.put(rule, input);
    }

    public Map<Rule<? extends RuleInput>, RuleInput> getRules() {
        return rules;
    }
}

2.5. ConditionEntry

Diese Klasse definiert den Bedingungsbeschreibungsteil der Entscheidungstabelle und die zu diesem Zeitpunkt bestimmte Operation. Als Datenaufbewahrungselement wird eines der in Nr. 1 bis Nr. 8 definierten Datenmuster beibehalten. Der Punkt ist, den hashCode von Set als ID zu verwenden, um ihn eindeutig zu identifizieren.

ConditionEntry.java


public class ConditionEntry<A extends DecisionAction> {

    private Set<String> resultMap = new HashSet<>();

    private A action;

    public void when(@SuppressWarnings("rawtypes") Class ruleClass, Object entry) {
        resultMap.add(ruleClass.getSimpleName() + "/" + entry);
    }

    public void then(A action) {
        this.action = action;
    }

    public int getId() {
        return resultMap.hashCode();
    }

    public A getAction() {
        return action;
    }
}

2.6. DecisionTable

Eine Klasse, die eine Entscheidungstabelle definiert. Als Daten enthält es nur "ConditionEntry" in Map. Wenn es 8 Datenmuster gibt, werden "# 1 bis # 8", 8 "ConditionEntry" in Map gespeichert. Definieren Sie bei der tatsächlichen Verwendung die Daten der Entscheidungstabelle mit "initDecisionTable ()".

Der Prozess zum Bestimmen der Aktion der Entscheidungstabelle ist die "Auflösungs" -Methode. Wie Sie dem Inhalt entnehmen können, müssen Sie lediglich die Regel nacheinander ausführen, um eine Instanz von "ConditionEntry" zu erstellen und zu überprüfen, ob die dieser ID entsprechende Instanz in der Entscheidungstabelle registriert ist.

DecisionTable.java


public abstract class DecisionTable<A extends DecisionAction> {

    private Map<Integer, ConditionEntry<A>> decisionTable;

    public DecisionTable() {
        decisionTable = initDecisionTable();
    }

    protected abstract Map<Integer, ConditionEntry<A>> initDecisionTable();

    public A resolve(ConditionStub conditionStub) {
        // execute rule
        ConditionEntry<A> result = new ConditionEntry<>();
        conditionStub.getRules().forEach((R, I) -> {
            result.when(R.getClass(), R.evaluate(I));
        });
        // search action
        Integer key = result.getId();
        if (decisionTable.containsKey(key)) {
            return decisionTable.get(key).getAction();
        }
        return null;
    }
}

3. Implementierung der Rabattberechnungsentscheidungstabelle für Parkgebühren

photo.png

Lassen Sie uns die Entscheidungstabelle "Rabattberechnung der Parkgebühr" implementieren. Es wird so implementiert, wie es wirklich aussieht. Wenn Sie es einfacher implementieren möchten, lesen Sie "[4. Implementierung der Entscheidungstabelle zur Berechnung des Parkgebührenrabattes (einfache Version)](Nr. 4 - Implementierung der einfachen Version der Entscheidungstabelle zur Berechnung des Parkgebührenrabattes)". Bitte gib mir.

3.1 Umsetzung der Entscheidungsmaßnahme

ParkingDiscountAction.java


public class ParkingDiscountAction implements DecisionAction {

    private final boolean discount30Minute;
    private final boolean discount1Hour;
    private final boolean discount2Hour30Minute;
    private final boolean discount3Hour30Minute;

    //Der Konstruktor wird weggelassen. Bereiten Sie einen Konstruktor vor, der ein Feld als Argument verwendet.
    //Getter wird weggelassen. Es wird kein Setter benötigt, da er nur die Ergebnisse der Entscheidungstabelle enthält.
    //ToString, um den Inhalt zu überprüfen()Es ist praktisch, die Methode automatisch mit Eclipse zu generieren.
}

3.2. Implementierung von RuleInput und Rule

PriceRuleInput.java


public class PriceRuleInput implements RuleInput {

    private final int paymentPrice;

    //Der Konstruktor wird weggelassen. Bereiten Sie einen Konstruktor vor, der ein Feld als Argument verwendet.
    //Getter wird weggelassen. Da der Eingabewert unveränderlich ist, ist kein Setter erforderlich.
}

PriceRule1.java


public class PriceRule1 implements Rule<PriceRuleInput> {

    //Verarbeitungslogik zur Beurteilung von "3000 Yen oder mehr und weniger als 10000 Yen"
    @Override
    public Object evaluate(RuleInput input) {
        PriceRuleInput priceRuleInput = getInput(input);
        int paymentPrice = priceRuleInput.getPaymentPrice();
        if (paymentPrice >= 3000 && paymentPrice < 10000) {
            return true;
        }
        return false;
    }
}

PriceRule2.java


public class PriceRule2 implements Rule<PriceRuleInput> {

    //Verarbeitungslogik zur Beurteilung von "10.000 Yen oder mehr und weniger als 30.000 Yen"
    @Override
    public Object evaluate(RuleInput input) {
        PriceRuleInput priceRuleInput = getInput(input);
        int paymentPrice = priceRuleInput.getPaymentPrice();
        if (paymentPrice >= 10000 && paymentPrice < 30000) {
            return true;
        }
        return false;
    }
}

PriceRule3.java


public class PriceRule3 implements Rule<PriceRuleInput> {

    //Verarbeitungslogik zur Beurteilung von "30.000 Yen oder mehr"
    @Override
    public Object evaluate(RuleInput input) {
        PriceRuleInput priceRuleInput = getInput(input);
        int paymentPrice = priceRuleInput.getPaymentPrice();
        if (paymentPrice >= 30000) {
            return true;
        }
        return false;
    }
}

CinemaRuleInput.java


public class CinemaRuleInput implements RuleInput {

    private final boolean watchCinema;

    //Der Konstruktor wird weggelassen. Bereiten Sie einen Konstruktor vor, der ein Feld als Argument verwendet.
    //Getter wird weggelassen. Da der Eingabewert unveränderlich ist, ist kein Setter erforderlich.
}

CinemaRule.java


public class CinemaRule implements Rule<CinemaRuleInput> {

    @Override
    public Object evaluate(RuleInput input) {
        CinemaRuleInput cinemaRuleInput = getInput(input);
        return cinemaRuleInput.isWatchCinema();
    }
}

3.3. Definition der Entscheidungstabelle

class-structure.jpg

Definieren Sie als "ConditionEntry" im roten Rahmen der Entscheidungstabelle. Die Bedingung wird durch die Methode "when ()" hinzugefügt, und die Operation zu diesem Zeitpunkt wird durch die Methode "then ()" definiert. Nachdem Sie die acht Datenmuster Nr. 1 bis Nr. 8 in der Entscheidungstabelle definiert haben, fügen Sie sie jeweils der Karte hinzu. Der Schlüssel zu diesem Zeitpunkt ist die ID, die von getId () of ConditionEntry erhalten wurde.

ParkingDiscountDecisionTable.java


public class ParkingDiscountDecisionTable extends DecisionTable<ParkingDiscountAction> {

    @Override
    protected Map<Integer, ConditionEntry<ParkingDiscountAction>> initDecisionTable() {
        // #1
        ConditionEntry<ParkingDiscountAction> pattern01 = new ConditionEntry<>();
        pattern01.when(PriceRule1.class, false);
        pattern01.when(PriceRule2.class, false);
        pattern01.when(PriceRule3.class, false);
        pattern01.when(CinemaRule.class, false);
        pattern01.then(new ParkingDiscountAction(true, false, false, false));
        // #2
        ConditionEntry<ParkingDiscountAction> pattern02 = new ConditionEntry<>();
        pattern02.when(PriceRule1.class, true);
        pattern02.when(PriceRule2.class, false);
        pattern02.when(PriceRule3.class, false);
        pattern02.when(CinemaRule.class, false);
        pattern02.then(new ParkingDiscountAction(false, true, false, false));
        // #3
        ConditionEntry<ParkingDiscountAction> pattern03 = new ConditionEntry<>();
        pattern03.when(PriceRule1.class, false);
        pattern03.when(PriceRule2.class, true);
        pattern03.when(PriceRule3.class, false);
        pattern03.when(CinemaRule.class, false);
        pattern03.then(new ParkingDiscountAction(false, false, true, false));
        // #4
        ConditionEntry<ParkingDiscountAction> pattern04 = new ConditionEntry<>();
        pattern04.when(PriceRule1.class, false);
        pattern04.when(PriceRule2.class, false);
        pattern04.when(PriceRule3.class, true);
        pattern04.when(CinemaRule.class, false);
        pattern04.then(new ParkingDiscountAction(false, false, false, true));
        // #5
        ConditionEntry<ParkingDiscountAction> pattern05 = new ConditionEntry<>();
        pattern05.when(PriceRule1.class, false);
        pattern05.when(PriceRule2.class, false);
        pattern05.when(PriceRule3.class, false);
        pattern05.when(CinemaRule.class, true);
        pattern05.then(new ParkingDiscountAction(false, false, true, false));
        // #6
        ConditionEntry<ParkingDiscountAction> pattern06 = new ConditionEntry<>();
        pattern06.when(PriceRule1.class, true);
        pattern06.when(PriceRule2.class, false);
        pattern06.when(PriceRule3.class, false);
        pattern06.when(CinemaRule.class, true);
        pattern06.then(new ParkingDiscountAction(false, false, true, false));
        // #7
        ConditionEntry<ParkingDiscountAction> pattern07 = new ConditionEntry<>();
        pattern07.when(PriceRule1.class, false);
        pattern07.when(PriceRule2.class, true);
        pattern07.when(PriceRule3.class, false);
        pattern07.when(CinemaRule.class, true);
        pattern07.then(new ParkingDiscountAction(false, false, true, false));
        // #8
        ConditionEntry<ParkingDiscountAction> pattern08 = new ConditionEntry<>();
        pattern08.when(PriceRule1.class, false);
        pattern08.when(PriceRule2.class, false);
        pattern08.when(PriceRule3.class, true);
        pattern08.when(CinemaRule.class, true);
        pattern08.then(new ParkingDiscountAction(false, false, false, true));
        // create map
        Map<Integer, ConditionEntry<ParkingDiscountAction>> tables = new HashMap<>();
        tables.put(pattern01.getId(), pattern01);
        tables.put(pattern02.getId(), pattern02);
        tables.put(pattern03.getId(), pattern03);
        tables.put(pattern04.getId(), pattern04);
        tables.put(pattern05.getId(), pattern05);
        tables.put(pattern06.getId(), pattern06);
        tables.put(pattern07.getId(), pattern07);
        tables.put(pattern08.getId(), pattern08);
        return tables;
    }
}

3.4. Verwendung der Entscheidungstabelle

Die Verwendung der Entscheidungstabelle ist einfach. Erstellen Sie einfach eine Instanz von ConditionStub und übergeben Sie sie dann als Argument an die resolve () Methode von ParkingDiscountDecisionTable und führen Sie sie aus.

Es wird empfohlen, die Instanz "ParkingDiscountDecisionTable" erneut zu verwenden, anstatt sie jedes Mal zu erstellen, da sich die Definition der Entscheidungstabelle während der Ausführung nicht ändert.

ParkingDiscountService.java


public class ParkingDiscountService {

    //Injektion bei Verwendung eines DI-Behälters
    PriceRule1 priceRule1;
    PriceRule2 priceRule2;
    PriceRule3 priceRule3;
    CinemaRule cinemaRule;
    ParkingDiscountDecisionTable parkingDiscountDecisionTable;
    
    public ParkingDiscountService() {
        //Instanz statt Injektion
        priceRule1 = new PriceRule1();
        priceRule2 = new PriceRule2();
        priceRule3 = new PriceRule3();
        cinemaRule = new CinemaRule();
        parkingDiscountDecisionTable = new ParkingDiscountDecisionTable();
    }
    
    public void business(int paymentPrice, boolean watchCinema) {
        // create input data
        PriceRuleInput priceRuleInput = new PriceRuleInput(paymentPrice);
        CinemaRuleInput cinemaRuleInput = new CinemaRuleInput(watchCinema);
        // create conditionStub
        ConditionStub conditionStub = new ConditionStub();
        conditionStub.when(priceRule1, priceRuleInput);
        conditionStub.when(priceRule2, priceRuleInput);
        conditionStub.when(priceRule3, priceRuleInput);
        conditionStub.when(cinemaRule, cinemaRuleInput);
        // resolve by decisionTable
        ParkingDiscountAction parkingDiscountAction = parkingDiscountDecisionTable.resolve(conditionStub);
        System.out.println("paymentPrice : " + paymentPrice + ", watchCinema : " + watchCinema);
        System.out.println(parkingDiscountAction);
    }
}

3.5 Funktionsprüfung

Demo.java


public class Demo {

    public static void main(String[] args) {
        //Wenn Sie einen DI-Container verwenden, beziehen Sie ihn von dort
        //Erstellen Sie diesmal eine Instanz vor Ort
        ParkingDiscountService service = new ParkingDiscountService();
        // # 1
        service.business(2000, false);
        // # 2
        service.business(5000, false);
        // # 3
        service.business(17000, false);
        // # 4
        service.business(45000, false);
        // # 5
        service.business(100, true);
        // # 6
        service.business(7000, true);
        // # 7
        service.business(20000, true);
        // # 8
        service.business(100000, true);
    }
}

Ausführungsergebnis


paymentPrice : 2000, watchCinema : false
ParkingDiscountAction [discount30Minute=true, discount1Hour=false, discount2Hour30Minute=false, discount3Hour30Minute=false]
paymentPrice : 5000, watchCinema : false
ParkingDiscountAction [discount30Minute=false, discount1Hour=true, discount2Hour30Minute=false, discount3Hour30Minute=false]
paymentPrice : 17000, watchCinema : false
ParkingDiscountAction [discount30Minute=false, discount1Hour=false, discount2Hour30Minute=true, discount3Hour30Minute=false]
paymentPrice : 45000, watchCinema : false
ParkingDiscountAction [discount30Minute=false, discount1Hour=false, discount2Hour30Minute=false, discount3Hour30Minute=true]
paymentPrice : 100, watchCinema : true
ParkingDiscountAction [discount30Minute=false, discount1Hour=false, discount2Hour30Minute=true, discount3Hour30Minute=false]
paymentPrice : 7000, watchCinema : true
ParkingDiscountAction [discount30Minute=false, discount1Hour=false, discount2Hour30Minute=true, discount3Hour30Minute=false]
paymentPrice : 20000, watchCinema : true
ParkingDiscountAction [discount30Minute=false, discount1Hour=false, discount2Hour30Minute=true, discount3Hour30Minute=false]
paymentPrice : 100000, watchCinema : true
ParkingDiscountAction [discount30Minute=false, discount1Hour=false, discount2Hour30Minute=false, discount3Hour30Minute=true]

4. Implementierung einer Entscheidungstabelle zur Rabattberechnung der Parkgebühr (einfache Version)

compact-desition.jpg

Ich weiß nicht, ob dies als Entscheidungstabelle bezeichnet wird, aber die angegebenen Spezifikationen stimmen mit der oben genannten Entscheidungstabelle überein. Wenn Sie dies so implementieren, wie es aussieht, ist es einfacher als die oben erwähnte Entscheidungstabelle.

4.1 Umsetzung der Entscheidungsmaßnahme

Solange die "DecisionAction" -Schnittstelle implementiert ist, gibt es keine Begrenzung für den Inhalt. Daher verwenden wir dieses Mal eine ENUM namens "Parking Discount".

ParkingDiscountAction.java


public class ParkingDiscountAction implements DecisionAction {

    private final ParkingDiscount discount;

    //Der Konstruktor wird weggelassen. Bereiten Sie einen Konstruktor vor, der ein Feld als Argument verwendet.
    //Getter wird weggelassen. Es wird kein Setter benötigt, da er nur die Ergebnisse der Entscheidungstabelle enthält.
    //ToString, um den Inhalt zu überprüfen()Es ist praktisch, die Methode automatisch mit Eclipse zu generieren.
}

ParkingDiscount.java


public enum ParkingDiscount {

    THIRTY_MINUTE(1), 
    ONE_HOUR(2), 
    TWO_HOUR_THIRTY_MINUTE(3), 
    THREE_HOUR_THIRTY_MINUTE(4);

    private int code;

    //Der Konstruktor wird weggelassen. Bereiten Sie einen Konstruktor vor, der ein Feld als Argument verwendet.
    //Getter wird weggelassen.
}

4.2 Umsetzung der Regel

Implementieren Sie die oben genannten PriceRule1, PriceRule2 und PriceRule3 zusammen. Der Rückgabewert ist diesmal ein numerischer Typ (int).

PriceRule.java


public class PriceRule implements Rule<PriceRuleInput> {

    @Override
    public Object evaluate(RuleInput input) {
        PriceRuleInput priceRuleInput = getInput(input);
        int paymentPrice = priceRuleInput.getPaymentPrice();
        if (paymentPrice >= 3000 && paymentPrice < 10000) {
            return 1;
        } else if (paymentPrice >= 10000 && paymentPrice < 30000) {
            return 2;
        } else if (paymentPrice >= 30000) {
            return 3;
        } else {
            return 0;
        }
    }
}

4.3 Definition der Entscheidungstabelle

Da der Rückgabewert von "PriceRule" ein numerischer Typ (int) ist, wird der Wert auch in der "when" -Methode entsprechend definiert. In ähnlicher Weise wurde bei der Methode "then" der Konstruktor von "ParkingDiscountAction" in ENUM geändert. Definieren Sie ihn daher entsprechend.

ParkingDiscountDecisionTable.java


public class ParkingDiscountDecisionTable extends DecisionTable<ParkingDiscountAction> {

    @Override
    protected Map<Integer, ConditionEntry<ParkingDiscountAction>> initDecisionTable() {
        // #1
        ConditionEntry<ParkingDiscountAction> pattern01 = new ConditionEntry<>();
        pattern01.when(PriceRule.class, 0);
        pattern01.when(CinemaRule.class, false);
        pattern01.then(new ParkingDiscountAction(ParkingDiscount.THIRTY_MINUTE));
        // #2
        ConditionEntry<ParkingDiscountAction> pattern02 = new ConditionEntry<>();
        pattern02.when(PriceRule.class, 1);
        pattern02.when(CinemaRule.class, false);
        pattern02.then(new ParkingDiscountAction(ParkingDiscount.ONE_HOUR));
        // #3
        ConditionEntry<ParkingDiscountAction> pattern03 = new ConditionEntry<>();
        pattern03.when(PriceRule.class, 2);
        pattern03.when(CinemaRule.class, false);
        pattern03.then(new ParkingDiscountAction(ParkingDiscount.TWO_HOUR_THIRTY_MINUTE));
        // #4
        ConditionEntry<ParkingDiscountAction> pattern04 = new ConditionEntry<>();
        pattern04.when(PriceRule.class, 3);
        pattern04.when(CinemaRule.class, false);
        pattern04.then(new ParkingDiscountAction(ParkingDiscount.THREE_HOUR_THIRTY_MINUTE));
        // #5
        ConditionEntry<ParkingDiscountAction> pattern05 = new ConditionEntry<>();
        pattern05.when(PriceRule.class, 0);
        pattern05.when(CinemaRule.class, true);
        pattern05.then(new ParkingDiscountAction(ParkingDiscount.TWO_HOUR_THIRTY_MINUTE));
        // #6
        ConditionEntry<ParkingDiscountAction> pattern06 = new ConditionEntry<>();
        pattern06.when(PriceRule.class, 1);
        pattern06.when(CinemaRule.class, true);
        pattern06.then(new ParkingDiscountAction(ParkingDiscount.TWO_HOUR_THIRTY_MINUTE));
        // #7
        ConditionEntry<ParkingDiscountAction> pattern07 = new ConditionEntry<>();
        pattern07.when(PriceRule.class, 2);
        pattern07.when(CinemaRule.class, true);
        pattern07.then(new ParkingDiscountAction(ParkingDiscount.TWO_HOUR_THIRTY_MINUTE));
        // #8
        ConditionEntry<ParkingDiscountAction> pattern08 = new ConditionEntry<>();
        pattern08.when(PriceRule.class, 3);
        pattern08.when(CinemaRule.class, true);
        pattern08.then(new ParkingDiscountAction(ParkingDiscount.THREE_HOUR_THIRTY_MINUTE));
        // create map
        Map<Integer, ConditionEntry<ParkingDiscountAction>> tables = new HashMap<>();
        tables.put(pattern01.getId(), pattern01);
        tables.put(pattern02.getId(), pattern02);
        tables.put(pattern03.getId(), pattern03);
        tables.put(pattern04.getId(), pattern04);
        tables.put(pattern05.getId(), pattern05);
        tables.put(pattern06.getId(), pattern06);
        tables.put(pattern07.getId(), pattern07);
        tables.put(pattern08.getId(), pattern08);
        return tables;
    }
}

4.4. Verwendung der Entscheidungstabelle

ParkingDiscountService.java


public class ParkingDiscountService {

    //Injektion bei Verwendung eines DI-Behälters
    PriceRule priceRule;
    CinemaRule cinemaRule;
    ParkingDiscountDecisionTable parkingDiscountDecisionTable;

    public ParkingDiscountService() {
        //Instanz statt Injektion
        priceRule = new PriceRule();
        cinemaRule = new CinemaRule();
        parkingDiscountDecisionTable = new ParkingDiscountDecisionTable();
    }

    public void business(int paymentPrice, boolean watchCinema) {
        // create input data
        PriceRuleInput priceRuleInput = new PriceRuleInput(paymentPrice);
        CinemaRuleInput cinemaRuleInput = new CinemaRuleInput(watchCinema);
        // create conditionStub
        ConditionStub conditionStub = new ConditionStub();
        conditionStub.when(priceRule, priceRuleInput);
        conditionStub.when(cinemaRule, cinemaRuleInput);
        // resolve by decisionTable
        ParkingDiscountAction parkingDiscountAction = parkingDiscountDecisionTable.resolve(conditionStub);
        System.out.println("paymentPrice : " + paymentPrice + ", watchCinema : " + watchCinema);
        System.out.println(parkingDiscountAction);
    }
}

4.5 Funktionsprüfung

Ausführungsergebnis


paymentPrice : 2000, watchCinema : false
ParkingDiscountAction [discount=THIRTY_MINUTE]
paymentPrice : 5000, watchCinema : false
ParkingDiscountAction [discount=ONE_HOUR]
paymentPrice : 17000, watchCinema : false
ParkingDiscountAction [discount=TWO_HOUR_THIRTY_MINUTE]
paymentPrice : 45000, watchCinema : false
ParkingDiscountAction [discount=THREE_HOUR_THIRTY_MINUTE]
paymentPrice : 100, watchCinema : true
ParkingDiscountAction [discount=TWO_HOUR_THIRTY_MINUTE]
paymentPrice : 7000, watchCinema : true
ParkingDiscountAction [discount=TWO_HOUR_THIRTY_MINUTE]
paymentPrice : 20000, watchCinema : true
ParkingDiscountAction [discount=TWO_HOUR_THIRTY_MINUTE]
paymentPrice : 100000, watchCinema : true
ParkingDiscountAction [discount=THREE_HOUR_THIRTY_MINUTE]

5. Schließlich

Dieses Mal habe ich erklärt, wie die Entscheidungstabelle implementiert wird, die so implementiert wird, wie sie aussieht. Durch die gute Nutzung von Sammlungen (Set, Map) konnten wir sie ohne bedingte Verzweigung implementieren. Es scheint mühsam zu sein, die "DecisionTable" -Klasse zu implementieren, die den Inhalt der Entscheidungstabelle definiert. Da der Inhalt jedoch Standard ist, scheint es besser, ihn automatisch aus dem Entwurfsdokument in einem tatsächlichen Projekt zu generieren.

Recommended Posts

Realisieren Sie eine Entscheidungstabelle ohne bedingte Verzweigung
So verbinden Sie eine Tabelle ohne DBFlute und SQL
Bedingte Verzweigung mit fließender Schnittstelle
[Android] Erstellen Sie ein Schiebemenü ohne Verwendung der Navigationsansicht
Wenn Sie eine vollständige äußere Verknüpfung ausführen, ohne die vollständige äußere Verknüpfung zu verwenden
Finden Sie den Rest geteilt durch 3, ohne eine Zahl zu verwenden