Heim  >  Artikel  >  Java  >  Implementierung von Strategiemustern in Java Design Patterns

Implementierung von Strategiemustern in Java Design Patterns

王林
王林nach vorne
2023-04-24 23:37:061877Durchsuche

1 Übersicht

In der täglichen Entwicklung stoßen wir häufig auf Situationen, in denen es viele Algorithmen oder Strategien zur Implementierung einer Funktion gibt. Wir können diese Funktion basierend auf verschiedenen Algorithmen oder Strategien implementieren. Beispiel: Wenn Sie eine Logistikberechnungsmethode berechnen möchten, werden alle unterschiedlichen Expresszustellungen in Rechnung gestellt, z. B. JD Express, Best Express und YTO Express. Die Art und Weise, wie die Versandkosten berechnet werden, ist unterschiedlich. Wie erreichen wir es? Die einfachen sind if...else...or switch...case... Diese beiden Implementierungen werden als Hard-Coding bezeichnet. Wenn es eine neue Abrechnungsmethode wie Yunda Express gibt, müssen wir den Quellcode unseres Algorithmus ändern. Dadurch wird der Code aufgebläht und schwer zu warten.

Wir müssen also eine Methode implementieren, bei der jeder seinen eigenen Algorithmus hat, und wir müssen nur auswählen, welche Methode auf dem Client aufgerufen werden soll.

2 Strategiemuster

2.1 Komponenten

Umgebungsklasse (Kontext): Konfiguriert mit einem ConcreteStrategy-Objekt. Pflegen Sie einen Verweis auf das Strategieobjekt. Sie können eine Schnittstelle definieren, um Strategy den Zugriff auf seine Daten zu ermöglichen.

Abstrakte Strategieklasse (Strategie): Definiert die öffentliche Schnittstelle aller unterstützten Algorithmen. Context verwendet diese Schnittstelle, um einen durch eine ConcreteStrategy definierten Algorithmus aufzurufen.

Concrete Strategy-Klasse (ConcreteStrategy): implementiert spezifische Algorithmen mit der Strategy-Schnittstelle.

2.2 Codebeispiel

Nehmen Sie die Frachtraten verschiedener Expressunternehmen als Beispiel:

Schritt 1: Definieren Sie eine abstrakte Strategieklasse (Abrechnungsmethode)

public interface CommandStrategy {
    /**
     * 计费方式
     * @param message
     */
    void calMoney(String message);
}

Schritt 2: Definieren Sie eine bestimmte Strategieklasse (verschiedene Algorithmusklassen implementieren dies Schnittstelle)

public class BaiShiCommand implements CommandStrategy {
    /**
     * 百世快递计费方式
     * @param message
     */
    @Override
    public void calMoney(String message) {
        System.out.println("百世快递收费方式:"+"起步20,每公斤6元");
    }
}
ee
public class JingDongCommand implements CommandStrategy {
    /**
     * 京东快递计费方式
     * @param message
     */
    @Override
    public void calMoney(String message) {
        System.out.println("京东快递收费方式:"+"起步30,每公斤5元");
    }
}

Schritt 3: Definieren Sie die Umgebungsklasse

public class YuanTongCommand implements CommandStrategy {
    /**
     * 圆通快递计费方式
     * @param message
     */
    @Override
    public void calMoney(String message) {
        System.out.println("圆通快递收费方式:"+"起步10,每公斤8元");
    }
}

Definieren Sie eine Aufzählungsklasse:

public class CommandContext {
    public CommandStrategy getInstance(String commandType) {
        CommandStrategy commandStrategy = null;
        Map<String, String> allClazz = CommandEnum.getAllClazz();
        //拿到对应算法类对应的路径
        String clazz = allClazz.get(commandType.trim().toLowerCase());
        if (StringUtils.isNotEmpty(clazz)) {
            try {
                try {
                    //创建一个对象实例
                    commandStrategy = (CommandStrategy) Class.forName(clazz).newInstance();//调用无参构造器创建实例
                } catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        System.out.println("commandStrategy:"+commandStrategy);
        return commandStrategy;
    }
}

Client:

public enum CommandEnum {
    JingDong("京东", "com.liubujun.design.command.JingDongCommand"), BaiShi("百世", "com.liubujun.design.command.BaishiCommand"), YuanTong("圆通", "com.liubujun.design.command.YuanTongCommand");
    private String name;
    private String clazz;
    public static Map<String, String> getAllClazz() {
        Map<String, String> map = new HashMap<>(8);
        System.out.println("==================="+Arrays.toString(CommandEnum.values())+"================");
        for (CommandEnum commandEnum : CommandEnum.values()) {
            map.put(commandEnum.getCommand(), commandEnum.getClazz());
        }
        return map;
    }
    public String getCommand() {
        return name;
    }
    CommandEnum(String command, String clazz) {
        this.name = command;
        this.clazz = clazz;
    }
    public void setCommand(String command) {
        this.name = command;
    }
    public String getClazz() {
        return clazz;
    }
    public void setClazz(String clazz) {
        this.clazz = clazz;
    }
}

Auf diese Weise kann der Client direkt aufrufen, welche Express-Abrechnungsmethode verwendet wird

Implementierung von Strategiemustern in Java Design Patterns

2.3 Vorteil Vorteile

Vorteile:

1) Verwandte Algorithmusserien Die Strategieklassenhierarchie definiert eine Reihe wiederverwendbarer Algorithmen oder Verhaltensweisen für den Kontext. Durch Vererbung können gemeinsame Funktionen in diesen Algorithmen extrahiert werden.

2) Bietet eine Möglichkeit, die Vererbungsbeziehung zu ersetzen: Vererbung bietet eine weitere Möglichkeit, mehrere Algorithmen oder Verhaltensweisen zu unterstützen. Sie können die Context-Klasse direkt in eine Unterklasse umwandeln, um ihr ein anderes Verhalten zu verleihen. Dadurch wird das Verhalten jedoch fest in den Kontext codiert und die Implementierung des Algorithmus mit der Implementierung des Kontexts vermischt, wodurch der Kontext schwer zu verstehen, zu warten und zu erweitern ist und der Algorithmus nicht dynamisch geändert werden kann. Am Ende erhalten Sie eine Reihe verwandter Klassen. Der einzige Unterschied zwischen ihnen besteht im verwendeten Algorithmus oder Verhalten. Durch die Kapselung des Algorithmus in einer unabhängigen Strategieklasse können Sie ihn unabhängig von seinem Kontext ändern, sodass er einfacher zu wechseln, zu verstehen und zu erweitern ist.

3) Eliminieren Sie einige if else-Bedingungsanweisungen: Der Strategiemodus bietet eine Alternative zur Auswahl des gewünschten Verhaltens mit Bedingungsanweisungen. Wenn unterschiedliche Verhaltensweisen in einer Klasse gestapelt werden, ist es schwierig, die Verwendung von bedingten Anweisungen zur Auswahl des geeigneten Verhaltens zu vermeiden. Durch die Kapselung des Verhaltens in separaten Strategieklassen entfallen diese bedingten Anweisungen. Code mit vielen bedingten Anweisungen weist normalerweise darauf hin, dass der Strategiemodus verwendet werden muss.

4) Wahl der Implementierung Der Strategiemodus kann verschiedene Implementierungen desselben Verhaltens bereitstellen. Kunden können aus verschiedenen Strategien wählen, die auf unterschiedlichen Zeit-/Raum-Kompromissanforderungen basieren.

Nachteile:

1) Der Kunde muss alle Strategieklassen kennen und entscheiden, welche Strategieklasse er verwenden möchte: Dieses Modell hat einen potenziellen Nachteil, das heißt, wenn ein Kunde eine geeignete Strategie auswählen möchte, muss er diese Strategien kennen Was für einen Unterschied. An diesem Punkt müssen dem Kunden möglicherweise spezifische Implementierungsprobleme offengelegt werden. Daher wird der Strategiemodus nur benötigt, wenn diese unterschiedlichen Verhaltensvarianten mit dem Kundenverhalten in Zusammenhang stehen.

2) Kommunikationsaufwand zwischen Strategie und Kontext: Unabhängig davon, ob der von jeder ConcreteStrategy implementierte Algorithmus einfach oder komplex ist, teilen sie alle die von Strategy definierte Schnittstelle. Daher ist es möglich, dass einige ConcreteStrategy nicht alle Informationen nutzen, die ihnen über diese Schnittstelle übermittelt werden; ein einfaches ConcreteStrategy verwendet möglicherweise keine der Informationen! Dies bedeutet, dass der Kontext manchmal Parameter erstellt und initialisiert, die niemals verwendet werden. Wenn ein solches Problem besteht, ist eine engere Kopplung zwischen Strategie und Kontext erforderlich.

3) Das Strategiemuster führt zur Generierung vieler Strategieklassen: Durch die Verwendung des Fliegengewichtsmusters kann die Anzahl der Objekte bis zu einem gewissen Grad reduziert werden. Die Strategie „Erhöhte Anzahl an Objekten“ erhöht die Anzahl der Objekte in einer Anwendung. Manchmal können Sie diesen Overhead reduzieren, indem Sie die Strategie als zustandsloses Objekt implementieren, das von verschiedenen Kontexten gemeinsam genutzt werden kann. Jeder verbleibende Zustand wird vom Kontext beibehalten. Der Kontext übergibt diesen Status bei jeder Anfrage an das Strategy-Objekt. Eine gemeinsame Strategie sollte den Status zwischen Aufrufen nicht aufrechterhalten.

Das obige ist der detaillierte Inhalt vonImplementierung von Strategiemustern in Java Design Patterns. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen