Was ist der Unterschied zwischen der Vorlagenmethode und den Strategiemustern?

161

Kann mir bitte jemand erklären, was der Unterschied zwischen dem Muster der Vorlagenmethode und dem Strategiemuster ist?

Soweit ich das beurteilen kann, sind sie zu 99% gleich - der einzige Unterschied besteht darin, dass das Muster der Vorlagenmethode eine abstrakte Klasse als Basisklasse hat, während die Strategieklasse eine Schnittstelle verwendet, die von jeder konkreten Strategieklasse implementiert wird.

Für den Kunden werden sie jedoch genauso konsumiert - ist das richtig?

Calanus
quelle
2
Dieser Beitrag in SO hat eine bessere Antwort auf die gleiche Frage: stackoverflow.com/questions/464524/…
Gob00st
12
Die Frage, mit der gob00st verbunden ist, ist der Unterschied zwischen Strategie und Brücke. Es ist überhaupt nicht die Antwort auf diese Frage.
Bluekeys

Antworten:

135

Der Hauptunterschied zwischen den beiden besteht darin, dass der konkrete Algorithmus gewählt wird.

Beim Muster der Vorlagenmethode geschieht dies zur Kompilierungszeit durch Unterklassen der Vorlage. Jede Unterklasse bietet einen anderen konkreten Algorithmus, indem die abstrakten Methoden der Vorlage implementiert werden. Wenn ein Client Methoden der externen Schnittstelle der Vorlage aufruft, ruft die Vorlage ihre abstrakten Methoden (ihre interne Schnittstelle) nach Bedarf auf, um den Algorithmus aufzurufen.

class ConcreteAlgorithm : AbstractTemplate
{
    void DoAlgorithm(int datum) {...}
}

class AbstractTemplate
{
    void run(int datum) { DoAlgorithm(datum); }

    virtual void DoAlgorithm() = 0; // abstract
}

Im Gegensatz dazu ermöglicht das Strategiemuster die Auswahl eines Algorithmus zur Laufzeit durch Eindämmung . Die konkreten Algorithmen werden durch separate Klassen oder Funktionen implementiert, die als Parameter an ihren Konstruktor oder an eine Setter-Methode an die Strategie übergeben werden. Welcher Algorithmus für diesen Parameter ausgewählt wird, kann je nach Programmstatus oder Eingaben dynamisch variieren.

class ConcreteAlgorithm : IAlgorithm
{
    void DoAlgorithm(int datum) {...}
}

class Strategy
{
    Strategy(IAlgorithm algo) {...}

    void run(int datum) { this->algo.DoAlgorithm(datum); }
}

Zusammenfassend:

  • Muster der Vorlagenmethode: Auswahl des Algorithmus zur Kompilierungszeit durch Unterklassen
  • Strategiemuster: Auswahl des Laufzeitalgorithmus durch Eindämmung
das Haus
quelle
47
Beide Muster unterstützen die Laufzeitauswahl des verwendeten Algorithmus (für die Vorlagenmethode würden Sie so etwas tun if (config.useAlgoA) impl = new AlgoA() else impl = new AlgoB()), sodass diese Antwort falsch ist.
Borek Bernard
13
Sicher könnten Sie das tun, aber dann verwenden Sie nicht das Vorlagenmuster. Genau so sieht der Code aus, der die Strategy-Instanz erstellt!
Thehouse
21
-1, ich denke, diese Antwort (obwohl nicht völlig falsch) verfehlt den Punkt, an dem die wirklichen Unterschiede liegen. @ tvanfosson Antwort ist viel besser.
Doc Brown
1
@Karoly Nyisztor Beide können "Verhalten ersetzen" und "Erweiterungspunkte bereitstellen". Ob es sich um ein Verhalten oder eine Erweiterung handelt, es hängt wirklich davon ab, wo Sie ein bestimmtes Muster anwenden. Sie können jede Unterklasse des Vorlagenmethodenmusters auch als "Strategie" oder jede Strategieklasse im Strategiemuster als "Erweiterung" bezeichnen, es handelt sich lediglich um eine Formulierung. Tatsache ist, dass sie dasselbe tun, mit Ausnahme des Unterschieds, den diese Antwort erwähnt. Das ist also die richtige Antwort.
Andy
1
Ein konkreter Algorithmus wird für beide Muster auf die gleiche Weise gewählt. Die Wahl wird durch Aufrufen von new ConcreteAlgorithm1()versus getroffen new ConcreteAlgorithm2(). Offensichtlich erfolgt die Auswahl zur Laufzeit (eine Auswahl des Algorithmus zur Kompilierungszeit würde eine harte Codierung bedeuten). Der Hauptunterschied zwischen beiden besteht darin, wie der konkrete Algorithmus implementiert wird. Ist es als Unterklasse oder als separate Schnittstelle implementiert? Ersteres ist eine Vorlage. Letzteres ist eine Strategie. Der Unterschied kann als Zusammensetzung gegenüber Vererbung zusammengefasst werden, was ein allgemeines Thema des GoF-Buches ist.
jaco0646
138

Das Vorlagenmuster wird verwendet, wenn eine bestimmte Operation ein unveränderliches Verhalten aufweist, das im Hinblick auf andere unterschiedliche primitive Verhaltensweisen definiert werden kann. Die abstrakte Klasse definiert die invarianten Verhaltensweisen, während die implementierenden Klassen die abhängigen Methoden definieren.

In einer Strategie sind die Verhaltensimplementierungen unabhängig - jede implementierende Klasse definiert das Verhalten und es gibt keinen Code, der zwischen ihnen geteilt wird. Beide sind Verhaltensmuster und werden als solche von Kunden auf die gleiche Weise konsumiert. In der Regel haben Strategien eine einzige öffentliche Methode - die execute()Methode, während Vorlagen eine Reihe öffentlicher Methoden sowie eine Reihe unterstützender privater Grundelemente definieren können, die von Unterklassen implementiert werden müssen.

Die zwei Muster könnten leicht zusammen verwendet werden. Möglicherweise haben Sie ein Strategiemuster, bei dem mehrere Implementierungen zu einer Familie von Strategien gehören, die mithilfe eines Vorlagenmusters implementiert wurden.

Tvanfosson
quelle
Das klingt für mich richtig, aber warum erwähnt WikiPedia , dass "das Strategiemuster darin besteht, dass das Verhalten eines Algorithmus zur Laufzeit ausgewählt wird"? Es könnte auch zur Auswahl des Verhaltens des Algorithmus zur Kompilierungszeit verwendet werden, genau wie die Vorlagenmethode? Vermisse ich etwas
BornToCode
2
@BornToCode Ich würde annehmen, dass sie zur Laufzeit eine bestimmte Strategie auswählen. Zum Beispiel gibt es verschiedene Möglichkeiten, die Wurzeln einer Gleichung numerisch zu finden. Abhängig von der Problemdomäne oder den Daten können Sie Newton-Raphson, Euler oder eine andere Strategie zur Lösung der Gleichung wählen. Jeder von ihnen ist eine Strategie. Der größere Algorithmus, von dem das Lösen der Gleichung ein Teil ist, wählt die zu verwendende Strategie basierend auf einer gewissen Qualität des Problems.
Tvanfosson
Ja, aber es ist nicht so, dass das Strategiemuster NUR für diese Fälle verwendet werden sollte. Ich meine, wenn ich nur das Verhalten des Algorithmus zur Kompilierungszeit auswählen muss, sollte ich dann immer noch ein Strategiemuster verwenden, oder sollte es nicht so verwendet werden?
BornToCode
1
@BornToCode Ich würde sagen, dass eine Strategie am nützlichsten ist, wenn die Auswahl dynamisch ist. Vorlage ist im Grunde eine Möglichkeit, verschiedene, verwandte Verhaltensweisen für bekannte aufzubauen. Sie würden eine Strategie verwenden (obwohl nicht unbedingt das Strategiemuster), um das zu verwendende Vorlagenverhalten auszuwählen. Beispiel: Produktvererbung: Sie würden ein Basisprodukt erstellen und Funktionen für verschiedene Produkte hinzufügen. Die Auswahl des zu instanziierenden Produkttyps (der zu instanziierenden Klasse) hängt möglicherweise davon ab, aus welchen Tabellen / Ansichten es geladen wird. Das Strategiemuster kommt dort nicht wirklich ins Spiel.
Tvanfosson
2
@BornToCode es ist kein entweder / oder Ding, es ist ja-und. Wenden Sie das Muster dort an, wo es angemessen ist, und kombinieren Sie Muster dort, wo es nützlich ist.
Tvanfosson
26

Ich denke, die Klassendiagramme beider Muster zeigen die Unterschiede.

Strategie
Verkapselt einen Algorithmus innerhalb einer Klasse.
Link zum Bild Geben Sie hier die Bildbeschreibung ein

Vorlagenmethode
Verschieben Sie die genauen Schritte eines Algorithmus auf eine Unterklasse
Link to Image Geben Sie hier die Bildbeschreibung ein

Ludwig Wensauer
quelle
24

Sie meinen wahrscheinlich Muster der Vorlagenmethode. Sie haben Recht, sie dienen sehr ähnlichen Bedürfnissen. Ich würde sagen, es ist besser, die Vorlagenmethode zu verwenden, wenn Sie einen "Vorlagen" -Algorithmus mit definierten Schritten haben, bei dem Unterklassen diese Schritte überschreiben, um einige Details zu ändern. Im Falle einer Strategie müssen Sie eine Schnittstelle erstellen und anstelle der Vererbung verwenden Sie die Delegierung. Ich würde sagen, es ist ein etwas leistungsfähigeres Muster und vielleicht besser gemäß den DIP-Abhängigkeitsinversionsprinzipien. Es ist leistungsfähiger, weil Sie eine neue Abstraktion der Strategie klar definieren - eine Art, etwas zu tun, die für die Vorlagenmethode nicht gilt. Wenn diese Abstraktion also Sinn macht, verwenden Sie sie. Die Verwendung der Vorlagenmethode kann jedoch in einfachen Fällen zu einfacheren Designs führen, was ebenfalls wichtig ist. Überlegen Sie, welche Wörter besser passen: Haben Sie einen Vorlagenalgorithmus? Oder ist der Schlüssel hier, dass Sie eine Abstraktion der Strategie haben - eine neue Art, etwas zu tun

Beispiel einer Vorlagenmethode:

Application.main()
{
Init();
Run();
Done();
}

Hier erben Sie von der Anwendung und ersetzen, was genau auf init, run und done getan wird.

Beispiel einer Strategie:

array.sort (IComparer<T> comparer)

Hier erben Sie beim Schreiben eines Vergleichers nicht von einem Array. Array delegiert den Vergleichsalgorithmus an einen Vergleicher.

Paul Kapustin
quelle
3
Ich denke, das ist eine großartige Antwort
Calanus
23

Unterschied zwischen Strategie und Vorlagenmethode Musterstrategie und Vorlagenmethode


Ähnlichkeiten

Strategie- und Vorlagenmethodenmuster weisen viele Ähnlichkeiten auf. Sowohl Strategie- als auch Vorlagenmethodenmuster können verwendet werden, um das Open-Closed-Prinzip zu erfüllen und das Softwaremodul einfach zu erweitern, ohne seinen Code zu ändern. Beide Muster repräsentieren die Trennung der generischen Funktionalität von der detaillierten Implementierung dieser Funktionalität. Sie unterscheiden sich jedoch geringfügig in der Granularität, die sie bieten.


Unterschiede

Hier sind einige der Unterschiede, die ich beim Studium dieser beiden Muster beobachtet habe:

  1. In der Strategie ist die Kopplung zwischen Client und Strategie lockerer, während in der Vorlagenmethode die beiden Module enger gekoppelt sind.
  2. In der Strategie wird meistens eine Schnittstelle verwendet, obwohl je nach Situation auch eine abstrakte Klasse verwendet werden kann und keine konkrete Klasse verwendet wird, während in der Vorlagenmethode meistens eine abstrakte Klasse oder eine konkrete Klasse verwendet wird, wird keine Schnittstelle verwendet.
  3. Im Strategiemuster wird im Allgemeinen das gesamte Verhalten der Klasse in Form einer Schnittstelle dargestellt. Andererseits wird die Template-Methode zum Reduzieren der Codeduplizierung verwendet und der Boilerplate-Code wird im Basisframework oder in der abstrakten Klasse definiert. In der Vorlagenmethode kann es sogar eine konkrete Klasse mit Standardimplementierung geben.
  4. Mit einfachen Worten, Sie können die gesamte Strategie (Algorithmus) im Strategiemuster ändern. Bei der Vorlagenmethode ändern sich jedoch nur einige Dinge (Teile des Algorithmus) und der Rest der Dinge bleibt unverändert. In der Vorlagenmethode werden die invarianten Schritte in einer abstrakten Basisklasse implementiert, während die Variantenschritte entweder eine Standardimplementierung oder gar keine Implementierung erhalten. Bei der Vorlagenmethode schreibt der Komponentendesigner die erforderlichen Schritte eines Algorithmus und die Reihenfolge der Schritte vor, ermöglicht es dem Komponentenclient jedoch, einige dieser Schritte zu erweitern oder zu ersetzen.

Das Bild stammt aus dem beißenden Blog.

Yogesh Umesh Vaity
quelle
19

Vererbung versus Aggregation (is-a versus has-a). Es gibt zwei Möglichkeiten, um dasselbe Ziel zu erreichen.

Diese Frage zeigt einige Kompromisse zwischen den Auswahlmöglichkeiten: Vererbung vs. Aggregation

flicken
quelle
11

Beide sind sehr ähnlich und werden vom Client-Code auf ähnliche Weise verwendet. Im Gegensatz zu den oben genannten Antworten ermöglichen beide die Auswahl von Algorithmen zur Laufzeit .

Der Unterschied zwischen den beiden besteht darin, dass das Strategiemuster es verschiedenen Implementierungen ermöglicht, völlig unterschiedliche Wege zum Erreichen des gewünschten Ergebnisses zu verwenden, das Muster der Vorlagenmethode jedoch einen übergreifenden Algorithmus (die "Vorlagen" -Methode) angibt, mit dem das Ergebnis erzielt wird. - Die einzige Möglichkeit für die spezifischen Implementierungen (Unterklassen) sind bestimmte Details der Vorlagenmethode. Dies geschieht, indem die Template-Methode eine oder mehrere abstrakte Methoden aufruft, die von den Unterklassen überschrieben (dh implementiert) werden, im Gegensatz zu der Template-Methode, die selbst nicht abstrakt ist und von den Unterklassen nicht überschrieben wird .

Der Client-Code ruft die Template-Methode mit einem Verweis / Zeiger des abstrakten Klassentyps auf, der auf eine Instanz einer der konkreten Unterklassen verweist, die zur Laufzeit genau wie bei Verwendung des Strategiemusters ermittelt werden kann.

Himanshu P.
quelle
9

Vorlagenmethode:

  1. Es basiert auf Vererbung
  2. Definiert das Skelett des Algorithmus, das von Unterklassen nicht geändert werden kann. In Unterklassen können nur bestimmte Operationen überschrieben werden
  3. Die übergeordnete Klasse steuert den Algorithmus vollständig und unterscheidet nur bestimmte Schritte von konkreten Klassen
  4. Die Bindung erfolgt zur Kompilierungszeit

Template_method Struktur:

Geben Sie hier die Bildbeschreibung ein

Strategie:

  1. Es basiert auf Delegation / Zusammensetzung
  2. Es ändert die Eingeweide des Objekts, indem es das Methodenverhalten ändert
  3. Es wird verwendet, um zwischen einer Familie von Algorithmen zu wechseln
  4. Es ändert das Verhalten des Objekts zur Laufzeit, indem ein Algorithmus zur Laufzeit vollständig durch einen anderen Algorithmus ersetzt wird
  5. Die Bindung erfolgt zur Laufzeit

Strategiestruktur :

Geben Sie hier die Bildbeschreibung ein

Schauen Sie sich zum besseren Verständnis die Artikel zur Vorlagenmethode und zur Strategie an .

Zusammenhängende Posts:

Das Vorlagenentwurfsmuster in JDK konnte keine Methode finden, die eine Reihe von Methoden definiert, die in der angegebenen Reihenfolge ausgeführt werden sollen

Beispiel aus der Praxis für das Strategiemuster

Ravindra Babu
quelle
3

Nein, sie werden nicht unbedingt auf die gleiche Weise konsumiert. Das Muster "Vorlagenmethode" ist eine Möglichkeit, zukünftigen Implementierern "Anleitung" zu geben. Sie sagen ihnen: "Alle Personenobjekte müssen eine Sozialversicherungsnummer haben" (das ist ein triviales Beispiel, aber es vermittelt die Idee richtig).

Das Strategiemuster ermöglicht das Ein- und Ausschalten mehrerer möglicher Implementierungen. Es wird (normalerweise) nicht durch Vererbung implementiert, sondern indem der Aufrufer die gewünschte Implementierung übergeben wird. Ein Beispiel könnte sein, dass ein ShippingCalculator mit einer von mehreren verschiedenen Methoden zur Berechnung von Steuern ausgestattet werden kann (eine NoSalesTax-Implementierung und möglicherweise eine PercentageBasedSalesTax-Implementierung).

Manchmal teilt der Client dem Objekt tatsächlich mit, welche Strategie verwendet werden soll. Wie in

myShippingCalculator.CalculateTaxes(myCaliforniaSalesTaxImpl);

Der Client würde dies jedoch niemals für ein Objekt tun, das auf der Vorlagenmethode basiert. Tatsächlich weiß der Client möglicherweise nicht einmal, dass ein Objekt auf der Vorlagenmethode basiert. Diese abstrakten Methoden im Muster der Vorlagenmethode sind möglicherweise sogar geschützt. In diesem Fall würde der Client nicht einmal wissen, dass sie vorhanden sind.

Charlie Flowers
quelle
3

Ich würde Ihnen empfehlen, diesen Artikel zu lesen . Es erklärt die Unterschiede an einem realen Fallbeispiel.

Zitat aus dem Artikel

" Wie man sehen kann, hängt das Implementieren von Klassen auch von der Klasse der Vorlagenmethode ab. Diese Abhängigkeit führt dazu, dass die Vorlagenmethode geändert wird, wenn einige der Schritte des Algorithmus geändert werden sollen. Auf der anderen Seite kapselt die Strategie den Algorithmus vollständig. Sie gibt die Implementierung Klassen, um einen Algorithmus vollständig zu definieren. Wenn also eine Änderung eintrifft, muss der Code für zuvor geschriebene Klassen geändert werden. Dies war der Hauptgrund, warum ich mich für eine Strategie zum Entwerfen der Klassen entschieden habe.

Ein Merkmal der Vorlagenmethode ist, dass die Vorlagenmethode den Algorithmus steuert. Was in anderen Situationen gut sein kann, aber in meinem Problem hat mich dies darauf beschränkt, die Klassen zu entwerfen. Auf der anderen Seite steuert die Strategie nicht die Schritte eines Algorithmus, der es mir ermöglicht, völlig andere Konvertierungsmethoden hinzuzufügen. Daher hilft mir in meinem Fall die Strategie bei der Umsetzung.

Ein Nachteil der Strategie besteht darin, dass zu viel Code-Redundanz und weniger Code-Sharing vorhanden sind. Wie aus dem vorgestellten Beispiel dieses Artikels hervorgeht, muss ich denselben Code in vier Klassen immer wieder wiederholen. Daher ist es schwierig zu warten, denn wenn die Implementierung unseres Systems wie Schritt 4, die allen gemeinsam ist, geändert wird, muss ich dies in allen 5 Klassen aktualisieren. Andererseits kann ich in der Vorlagenmethode nur die Oberklasse ändern, und die Änderungen werden in den Unterklassen wiedergegeben. Daher bietet die Vorlagenmethode eine sehr geringe Redundanz und eine hohe Codefreigabe zwischen den Klassen.

Die Strategie ermöglicht auch das Ändern des Algorithmus zur Laufzeit. Bei der Vorlagenmethode muss das Objekt neu initialisiert werden. Dieses Merkmal der Strategie bietet ein hohes Maß an Flexibilität. Aus gestalterischer Sicht muss man die Komposition der Vererbung vorziehen. Daher wurde die Verwendung von Strategiemustern auch zur Hauptwahl für die Entwicklung. "

Iulian Rosca
quelle
2

Das Vorlagenmuster ähnelt dem Strategiemuster. Diese beiden Muster unterscheiden sich in Umfang und Methodik.

Die Strategie wird verwendet, um Anrufern das Variieren eines gesamten Algorithmus zu ermöglichen, z. B. das Berechnen verschiedener Steuertypen, während die Vorlagenmethode zum Variieren von Schritten in einem Algorithmus verwendet wird. Aus diesem Grund ist die Strategie gröber. Die Vorlage ermöglicht feinkörnigere Steuerelemente in der Reihenfolge der Vorgänge und ermöglicht dennoch, dass die Implementierungen dieser Details variieren.

Der andere Hauptunterschied besteht darin, dass die Strategie die Delegierung verwendet, während die Vorlagenmethode die Vererbung verwendet. In Strategy wird der Algorithmus an eine andere xxxStrategy-Klasse delegiert, auf die der Betreff verweist. Mit Template können Sie jedoch die Basis- und Überschreibungsmethoden unterordnen, um Änderungen vorzunehmen.

von http://cyruscrypt.blogspot.com/2005/07/template-vs-strategy-patterns.html

iRunner
quelle
2

In Strategiemustern führen Unterklassen die Show aus und steuern den Algorithmus. Hier wird der Code über die Unterklassen hinweg dupliziert. Das Wissen über den Algorithmus und dessen Implementierung ist auf viele Klassen verteilt.

Im Vorlagenmuster verfügt die Basisklasse über einen Algorithmus. Es maximiert die Wiederverwendung unter den Unterklassen. Da der Algorithmus an einer Stelle liegt, schützt ihn die Basisklasse.

Ruju
quelle
2

Strategie-Design-Muster

  • Unterstützt die Komposition.
  • Bietet Ihnen die Flexibilität, das Verhalten von Objekten zur Laufzeit zu ändern.
  • Weniger Kopplung zwischen dem Client-Code und dem Lösungs- / Algorithmus-Code.

Entwurfsmuster für Vorlagenmethode

  • Bevorzugt die Vererbung gegenüber der Komposition
  • Definieren Sie den Algorithmus in Ihrer Basisklasse. Einzelne Algorithmen können in untergeordneten Klassen angepasst werden.
Mangu Singh Rajpurohit
quelle
1

Vorlagenmuster:

Bei der Vorlagenmethode geht es darum, Unterklassen bestimmte Schritte des Algorithmus neu definieren zu lassen, ohne die in der Basisklasse definierte Hauptstruktur und die Schritte des Algorithmus zu ändern. Das Vorlagenmuster verwendet normalerweise die Vererbung, sodass eine generische Implementierung von Algorithmen in der Basisklasse bereitgestellt werden kann, die die Unterklasse bei Bedarf möglicherweise überschreibt.

public abstract class RobotTemplate {
    /* This method can be overridden by a subclass if required */
    public void start() {
        System.out.println("Starting....");
    }

    /* This method can be overridden by a subclass if required */
    public void getParts() {
        System.out.println("Getting parts....");
    }

    /* This method can be overridden by a subclass if required */
    public void assemble() {
        System.out.println("Assembling....");
    }

    /* This method can be overridden by a subclass if required */
    public void test() {
        System.out.println("Testing....");
    }

    /* This method can be overridden by a subclass if required */
    public void stop() {
        System.out.println("Stopping....");
    }

    /*
     * Template algorithm method made up of multiple steps, whose structure and
     * order of steps will not be changed by subclasses.
     */
    public final void go() {
        start();
        getParts();
        assemble();
        test();
        stop();
    }
}


/* Concrete subclass overrides template step methods as required for its use */
public class CookieRobot extends RobotTemplate {
    private String name;

    public CookieRobot(String n) {
        name = n;
    }

    @Override
    public void getParts() {
        System.out.println("Getting a flour and sugar....");
    }

    @Override
    public void assemble() {
        System.out.println("Baking a cookie....");
    }

    @Override
    public void test() {
        System.out.println("Crunching a cookie....");
    }

    public String getName() {
        return name;
    }
}

Beachten Sie im obigen Code, dass die Schritte des go () -Algorithmus immer gleich sind, die Unterklassen jedoch möglicherweise ein anderes Rezept für die Ausführung eines bestimmten Schritts definieren.

Strategiemuster:

Beim Strategiemuster geht es darum, den Client zur Laufzeit die Implementierung konkreter Algorithmen auswählen zu lassen. Alle Algorithmen sind isoliert und unabhängig, implementieren jedoch eine gemeinsame Schnittstelle, und es gibt keine Vorstellung davon, bestimmte Schritte innerhalb des Algorithmus zu definieren.

/**
 * This Strategy interface is implemented by all concrete objects representing an
 * algorithm(strategy), which lets us define a family of algorithms.
 */
public interface Logging {
    void write(String message);
}

/**
 * Concrete strategy class representing a particular algorithm.
 */
public class ConsoleLogging implements Logging {

    @Override
    public void write(String message) {
        System.out.println(message); 
    }

}

/**
 * Concrete strategy class representing a particular algorithm.
 */
public class FileLogging implements Logging {

    private final File toWrite;

    public FileLogging(final File toWrite) {
        this.toWrite = toWrite;
    }

    @Override
    public void write(String message) {
        try {
            final FileWriter fos = new FileWriter(toWrite);
            fos.write(message);
            fos.close();
        } catch (IOException e) {
            System.out.println(e);
        }
    }

}

Den vollständigen Quellcode finden Sie in meinem Github- Repository .

Saad
quelle
0

Strategie wird als Schnittstellen- und Vorlagenmethode als abstrakte Klasse verfügbar gemacht. Dies wird normalerweise häufig in Frameworks verwendet. Beispiel: Die MessageSource-Klasse von Spring Framework ist eine Strategie-Schnittstelle zum Auflösen von Nachrichten. Der Client verwendet eine bestimmte Implementierung (Strategie) dieser Schnittstelle.

Und die abstrakte Implementierung derselben Schnittstelle AbstractMessageSource, die eine gemeinsame Implementierung zum Auflösen von Nachrichten hat und die abstrakte Methode resolveCode () verfügbar macht, damit Unterklassen sie auf ihre Weise implementieren können. AbstractMessageSource ist ein Beispiel für eine Vorlagenmethode.

http://docs.spring.io/spring/docs/4.1.7.RELEASE/javadoc-api/org/springframework/context/support/AbstractMessageSource.html

Amolu
quelle
0

Bei der Vorlagenmethode dieses Entwurfsmusters können ein oder mehrere Algorithmusschritte von Unterklassen überschrieben werden, um unterschiedliche Verhaltensweisen zuzulassen und gleichzeitig sicherzustellen, dass der übergeordnete Algorithmus weiterhin befolgt wird (Wiki).

Der Mustername Template-Methode bedeutet, was es ist. Angenommen, wir haben eine Methode CalculateSomething () und möchten diese Methode vorlegen. Diese Methode wird in der Basisklasse als nicht virtuelle Methode deklariert. Angenommen, die Methode sieht so aus.

CalculateSomething(){
    int i = 0;
    i = Step1(i);
    i++;
    if (i> 10) i = 5;
    i = Step2(i);
    return i;

} Die Implementierung der Step1- und Step2-Methoden kann durch abgeleitete Klassen erfolgen.

In Strategy Pattern wird keine Implementierung von der Basis bereitgestellt (Dies ist der Grund, warum die Basis wirklich eine Schnittstelle im Klassendiagramm ist).

Das klassische Beispiel ist das Sortieren. Basierend auf der Anzahl der zu sortierenden Objekte wird die entsprechende Algorithmusklasse (Zusammenführen, Blasen, Schnell usw.) erstellt und der gesamte Algorithmus in jede Klasse eingekapselt.

Können wir nun die Sortierung als Vorlagenmethode implementieren? Sicher können Sie, aber Sie werden nicht viel / keine Gemeinsamkeiten finden, die abstrahiert und in die Basisimplementierung eingefügt werden könnten. Damit wird der Zweck des Template-Methodenmusters zunichte gemacht.

Siby
quelle