Heim  >  Artikel  >  Java  >  Einführung in Strategiemuster und Vorlagenmethodenmuster in Java (mit Code)

Einführung in Strategiemuster und Vorlagenmethodenmuster in Java (mit Code)

不言
不言nach vorne
2019-02-19 15:56:372501Durchsuche

Dieser Artikel bietet Ihnen eine Einführung in das Strategiemuster und das Vorlagenmethodenmuster in Java. Ich hoffe, dass er Ihnen als Referenz dienen wird.

Strategiemuster

Einführung

Strategiemuster gehört zum Verhaltensmuster eines Objekts. Sein Zweck besteht darin, jeden Algorithmus in einer unabhängigen Klasse mit einer gemeinsamen Schnittstelle für eine Reihe von Algorithmen zu kapseln, damit diese untereinander ersetzt werden können. Das Strategiemuster ermöglicht eine Änderung des Algorithmus, ohne dass sich dies auf den Client auswirkt.
Der Hauptzweck besteht darin, das Schreiben von if else-Anweisungen durch die Definition ähnlicher Algorithmen zu ersetzen, und diese können jederzeit miteinander ersetzt werden.

Strategiemodus besteht hauptsächlich aus diesen drei Rollen: Umweltrolle (Kontext), abstrakte Strategierolle (Strategy) und konkrete Strategierolle (ConcreteStrategy).

  • Umgebungsrolle (Kontext): enthält einen Verweis auf eine Strategieklasse und stellt ihn dem Client zur Verfügung.

  • Abstrakte Strategierolle (Strategie): Dies ist eine abstrakte Rolle, die normalerweise von einer Schnittstelle oder einer abstrakten Klasse implementiert wird. Diese Rolle stellt alle Schnittstellen bereit, die für die spezifischen Richtlinienklassen erforderlich sind.

  • Concrete Strategy Role (ConcreteStrategy): Paketiert verwandte Algorithmen oder Verhaltensweisen.

Das Beispieldiagramm sieht wie folgt aus:
Einführung in Strategiemuster und Vorlagenmethodenmuster in Java (mit Code)

Um das Verständnis zu erleichtern, nehmen wir die Berechnungsmethode, die wir verwendet haben, als wir Java zum ersten Mal gelernt haben.
Bei der Verwendung eines Taschenrechners für Berechnungen werden häufig Additions-, Subtraktions-, Multiplikations- und Divisionsmethoden verwendet. Wenn wir die Summe der Addition zweier Zahlen erhalten möchten, müssen wir das „+“-Zeichen verwenden, um die Differenz der Subtraktion zu erhalten, müssen wir das „-“-Zeichen verwenden und so weiter. Obwohl wir eine allgemeine Methode mit if/else durch String-Vergleich schreiben können, müssen wir jedes Mal, wenn das berechnete Symbol hinzugefügt wird, den entsprechenden Code zur ursprünglichen Methode hinzufügen. Wenn die nachfolgende Berechnungsmethode hinzugefügt, geändert oder gelöscht wird, wird dies der Fall sein erschweren spätere Wartungsarbeiten.
Aber unter diesen Methoden haben wir festgestellt, dass die grundlegende Methode zu diesem Zeitpunkt festgelegt ist und wir mithilfe des Strategiemodus effektiv vermeiden können, Urteile zu fällen, selbst wenn später andere Berechnungsregeln hinzugefügt werden Anpassungen vorzunehmen.

Definieren Sie zunächst eine abstrakte Strategierolle und verfügen Sie über eine Berechnungsmethode.

interface CalculateStrategy {
   int doOperation(int num1, int num2);
}

Definieren Sie dann die spezifischen strategischen Rollen der Addition, Subtraktion, Multiplikation und Division und implementieren Sie sie.

Dann lautet der Code wie folgt:

class OperationAdd implements CalculateStrategy {
   @Override   public int doOperation(int num1, int num2) {
          return num1 + num2;
   }
}
class OperationSub implements CalculateStrategy {
   @Override   public int doOperation(int num1, int num2) {
          return num1 - num2;
   }
}
class OperationMul implements CalculateStrategy {
   @Override   public int doOperation(int num1, int num2) {
          return num1 * num2;
   }
}
class Operationp implements CalculateStrategy {
   @Override   public int doOperation(int num1, int num2) {
          return num1 / num2;
   }
}

Definieren Sie abschließend eine Umgebungsrolle und stellen Sie dem Client eine Computerschnittstelle zur Verfügung.
Der Code lautet wie folgt:

class  CalculatorContext {
    private CalculateStrategy strategy;
    public CalculatorContext(CalculateStrategy strategy) {
            this.strategy = strategy;
    }    
    public int executeStrategy(int num1, int num2) {
            return strategy.doOperation(num1, num2);
    }
}

Nachdem wir ihn geschrieben haben, testen wir ihn.
Der Testcode lautet wie folgt:

    public static void main(String[] args) {
          int a=4,b=2;
          CalculatorContext context = new CalculatorContext(new OperationAdd());    
          System.out.println("a + b = "+context.executeStrategy(a, b));
     
          CalculatorContext context2 = new CalculatorContext(new OperationSub());      
          System.out.println("a - b = "+context2.executeStrategy(a, b));
     
          CalculatorContext context3 = new CalculatorContext(new OperationMul());    
          System.out.println("a * b = "+context3.executeStrategy(a, b));
    
          CalculatorContext context4 = new CalculatorContext(new Operationp());    
          System.out.println("a / b = "+context4.executeStrategy(a, b));
}

Ausgabeergebnis:

a + b = 6
a - b = 2
a * b = 8
a / b = 2

Vorteile des Strategiemodus:

Gute Skalierbarkeit, Sie können neue Klassen hinzufügen, um neue Algorithmen zu implementieren, ohne die Objektstruktur zu ändern;
Gute Flexibilität, Sie können Algorithmen frei wechseln; >

Nachteile des Strategiemodus:

Die Verwendung weiterer Strategieklassen erhöht die Komplexität des Systems. ;

Der Kunde muss alle Versicherungsklassen kennen, bevor er anruft;

Nutzungsszenarien:

Wenn es viele Klassen in einem System gibt und der Unterschied zwischen ihnen nur ihr Verhalten ist, kann die Verwendung des Strategiemusters einem Objekt dynamisch ein Verhalten unter vielen Verhaltensweisen auswählen lassen

A Das System muss dynamisch einen von mehreren Algorithmen auswählen;
Wenn ein Objekt viele Verhaltensweisen ohne geeignete Muster aufweist, müssen diese Verhaltensweisen mehrere bedingte Auswahlanweisungen verwenden. Um dies zu erreichen;
Template Pattern

Einführung

In Template Pattern definiert eine abstrakte Klasse öffentlich die Art und Weise/Vorlage der Methode, sie auszuführen. Seine Unterklassen können die Methodenimplementierung nach Bedarf überschreiben, die Aufrufe erfolgen jedoch auf die in der abstrakten Klasse definierte Weise. Diese Art von Entwurfsmuster ist ein Verhaltensmuster. Definieren Sie das Grundgerüst eines Algorithmus in einer Operation und verlagern Sie einige Schritte auf Unterklassen.

Vorlagenmodus, dessen Hauptidee darin besteht, eine Vorlage zu erstellen und diese dem Kunden zum Aufrufen zur Verfügung zu stellen. Zusätzlich zu Lebenslaufvorlagen, Vertragsvorlagen usw., die wir im Leben häufig verwenden, gibt es auch sehr klassische Vorlagen, die in Java verwendet werden, nämlich Servlet Die HttpService-Klasse stellt eine service()-Methode bereit, die eine der sieben do-Methoden aufruft oder mehrere vollständige Antworten auf Kundenanrufe. Diese Do-Methoden müssen von der spezifischen Unterklasse von HttpServlet bereitgestellt werden.

Der Vorlagenmodus

besteht hauptsächlich aus der Rolle „Abstrakte Vorlage“ und der Rolle „Konkrete Vorlage“.

  • 抽象模板(Abstract Template): 定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤;定义并实现了一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。

  • 具体模板(Concrete Template): 实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤;每一个抽象模板角色都可以有任意多个具体模板角色与之对应,而每一个具体模板角色都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。

示例图如下:
Einführung in Strategiemuster und Vorlagenmethodenmuster in Java (mit Code)

这里为了方便理解,我们依旧使用一个简单的示例来加以说明。
我们以前在玩魂斗罗、双截龙、热血物语、忍者神龟等等游戏的时候,都需要在小霸王游戏机上插卡,然后启动游戏才能玩,其中魂斗罗这种游戏,启动游戏之后就可以直接玩了,但是忍者神龟这种游戏则在启动游戏之后,需要选择其中一个角色才能开始玩。那么我们可以根据这个场景写出一个通用的模板,主要包含启动游戏,玩游戏,结束游戏这几个必须实现的方法,选择人物这个方法改成可选。

那么这个抽象类的代码如下:

abstract class  Game{    
    //启动游戏    
    protected abstract void  runGame();    
    //选择人物    
    protected  void choosePerson() {};    
    //开始玩游戏    
    protected abstract void startPlayGame();    
    //结束游戏    
    protected abstract void endPlayGame();    
    //模板方法    
    public final void play() {
        runGame();
        choosePerson();
        startPlayGame();
        endPlayGame();
    }
    
}

定义好该抽象类之后,我们再来定义具体模板实现类。这里定义两个游戏类,一个是魂斗罗,一个忍者神龟。

那么代码如下:

class ContraGame extends Game{   @Override   protected void runGame() {
       System.out.println("启动魂斗罗II...");
   }   
@Override   protected void startPlayGame() {
          System.out.println("1P正在使用S弹打aircraft...");
   }   
@Override   protected void endPlayGame() {
          System.out.println("1P被流弹打死了,游戏结束!");
   }
}
class TMNTGame extends Game{
   @Override   protected void runGame() { 
         System.out.println("启动忍者神龟III...");
   }   
   @Override   protected void choosePerson() {       System.out.println("1P选择了Raph !");
   }   
   @Override   protected void startPlayGame() {
          System.out.println("Raph正在使用绝技 “火箭头槌” ");
   }   
   @Override   protected void endPlayGame() {
          System.out.println("Raph 掉进井盖里死了,游戏结束了! ");
   }
}

最后再来进行测试,测试代码如下:

public static void main(String[] args) {
       Game game = new ContraGame();
       game.play();
       System.out.println();
       game = new TMNTGame();
       game.play();

}

输出结果:

启动魂斗罗II...1P正在使用S弹打aircraft...1P被流弹打死了,游戏结束!

启动忍者神龟III...1P选择了Raph !
Raph正在使用绝技 “火箭头槌” 
Raph 掉进井盖里死了,游戏结束了!

模板模式优点:

扩展性好,对不变的代码进行封装,对可变的进行扩展;
可维护性好,因为将公共代码进行了提取,使用的时候直接调用即可;

模板模式缺点:

因为每一个不同的实现都需要一个子类来实现,导致类的个数增加,会使系统变得复杂;

使用场景:

有多个子类共有逻辑相同的方法;
重要的、复杂的方法,可以考虑作为模板方法。

注意事项:

为防止恶意操作,一般模板方法都加上 final 关键词!

Das obige ist der detaillierte Inhalt vonEinführung in Strategiemuster und Vorlagenmethodenmuster in Java (mit Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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