Strategy Pattern Problem beim Interface



  • Ich habe ein sehr einfaches Strategy Pattern in c++ passend zu diesem Diagramm

    http://www.philipphauer.de/study/se/design-pattern/strategy/strategy-gr.png

    Context.cpp

    #include "stdafx.h"
    #include "Context.h"
    #include "Strategy.h"
    #include <iostream>
    
    using namespace std;
    
    Context::Context( void ) {
    	Strategy_ = new ConcreteStrategyA();
    }
    
    void Context::execute() {
    	Strategy_->executeAlgorithm();
    }
    
    void Context::setStrategy(Strategy *Strategy) {
    	cout << "Neue Strategie" << endl;
    	Strategy_ = Strategy;
    }
    

    Context.h

    #pragma once
    #ifndef _CONTEXT_H_
    #define _CONTEXT_H_
    
    #include "stdafx.h"
    #include "Strategy.h"
    
    class Context {
    public:
    	Strategy *Strategy_;
    
    	Context( void );
    	void execute();
    	void setStrategy(Strategy *Strategy);
    };
    
    #endif // _CONTEXT_H_
    

    Strategy.cpp

    #include "stdafx.h"
    #include "Strategy.h"
    #include <iostream>
    
    using namespace std;
    
    void ConcreteStrategyA::executeAlgorithm() {
    	cout << "Strategie A" << endl; 
    }
    
    void ConcreteStrategyB::executeAlgorithm() {
    	cout << "Strategie B" << endl; 
    }
    

    Strategy.h

    #pragma once
    #ifndef _STRATEGY_H_
    #define _STRATEGY_H_
    
    class Strategy {
    public:
    	virtual void executeAlgorithm() = 0;
    };
    
    class ConcreteStrategyA : public Strategy {
    public:
    	void executeAlgorithm();
    };
    
    class ConcreteStrategyB : public Strategy {
    public:
    	void executeAlgorithm();
    };
    
    #endif // _STRATEGY_H_
    

    Client

    #include "stdafx.h"
    #include "Context.h"
    #include "Strategy.h"
    
    using namespace System;
    
    int main( void ) {
    
    	//Default Verhalten
    	Context *ContextObj = new Context();
    	ContextObj->execute();
    
    	//Verhalten ändern
    	ContextObj->setStrategy(new ConcreteStrategyB());
    	ContextObj->execute();
    
    	return 0;
    }
    

    Ich möchte nun Parameter über ein struct einbinden und in den konkrekten Strategien ausgeben und entsprechende setter und getter vorsehen:

    struct Parameter {
        int A;
        int B;
        int C;
    };
    
    Parameter Parameter_;
    
    void setParameter( Parameter &Parameter ) {
        Parameter_ = Parameter;
    }
    
    void getParameter( Parameter &Parameter ) {
        Parameter = Parameter_;
    }
    

    Die execute Methode der konkreten Strategien würde dann beispielsweise so aussehen:

    void ConcreteStrategyA::executeAlgorithm() {
        cout << "Strategie A" << endl;
        cout << Parameter_.A << endl;
        cout << Parameter_.B << endl;
        cout << Parameter_.C << endl;
    }
    

    Ich kam auf die Idee die Drei im Strategy "Interface" zu implementieren, da die konkreten Strategien vom Interface erben und so direkt auf das Parameter_ zugreifen können.

    Das hat jedoch zur folge, dass ich auch im Context das gleiche struct definieren muss und dann in etwa so "durchreiche":

    Context::setParameter( Parameter &Parameter ) {
        Strategy::Parameter StrategyParameter;
        StrategyParameter.A = Parameter.A;
        StrategyParameter.B = Parameter.B;
        StrategyParameter.C = Parameter.C;
        Strategy_.->setParameter( StrategyParameter );
    }
    

    Nun zu meiner Frage: Gibt es eine Möglichkeit das struct Parameter in Context anzulegen und die konkreten Strategien darauf zugreifen zu lassen?



  • Zisko schrieb:

    Nun zu meiner Frage: Gibt es eine Möglichkeit das struct Parameter in Context anzulegen und die konkreten Strategien darauf zugreifen zu lassen?

    erstelle das struct in einer eigenen Header-Datei, die du überall dort einbindest, wo du sie brauchst.



  • Und wo packe ich die Instanz Parameter_ (nicht public) des structs hin?



  • Zisko schrieb:

    Und wo packe ich die Instanz Parameter_ (nicht public) des structs hin?

    in die Strategy-Basisklasse



  • Einige deiner new-Aufrufe sind überflüssig, außerdem hast du tonnenweise Speicherlecks. C++ ist nicht Java, also solltest du C++ auch nicht wie Java behandeln...



  • pumuckl schrieb:

    Einige deiner new-Aufrufe sind überflüssig, außerdem hast du tonnenweise Speicherlecks. C++ ist nicht Java, also solltest du C++ auch nicht wie Java behandeln...

    Dazu habe ich im anderem Thread( http://www.c-plusplus.net/forum/p2241803#2241803 ) einiges geschrieben. (Nur so zur Sicherheit, damit sich hier nicht nochmal jemand unnötig die gleiche Mühe macht. ;))



  • Danke für den Hinweis, aber keine Sorge die Speicherlecks sind mir bewusst und werden im "Original" entsprechend behandelt. Das hier ist auch nur ein quick'n'dirty Beispiel um mein Problem besser zu beschreiben und da die Programmierung bei mir nur eine Nebenbeschäftigung ist, bin ich nicht so firm, dass ich bei ersten heruntertippen alles berücksichtige.

    Ich würde gerne wissen welche meiner Aufrufe überflüssig sind?



  • Zisko schrieb:

    Danke für den Hinweis, aber keine Sorge die Speicherlecks sind mir bewusst und werden im "Original" entsprechend behandelt. Das hier ist auch nur ein quick'n'dirty Beispiel um mein Problem besser zu beschreiben und da die Programmierung bei mir nur eine Nebenbeschäftigung ist, bin ich nicht so firm, dass ich bei ersten heruntertippen alles berücksichtige.

    Aus dem Grund solltest du auch ein reduziertes Original posten, damit man sich um die eigentliche Problematik kümmern kann und die nicht hinter dem "dirty"-Teil (d.h. den ganzen Fehlern) untergeht.


Anmelden zum Antworten