Strategy

The strategy pattern encapsulates algorithms that do the same general task into objects. It allows for the specific algorithm to be applied as needed at run time.

Quick Reference

Pattern Name Strategy
Other Names Policy
Classification Object Behavioural
Intent Defines subclasses to encapsulate various algorithms that perform the same general task

General Structure

The context stores internal data for an application. Some or all of this data is needed by the algorithms. The strategy (an abstract class that serves as the interface) defines the interface for a specific version of the algorithms.

The context keeps a reference to a strategy object. When it needs to perform the algorithm, the function from the concrete strategy class is called through the reference to the strategy object.

Example

The strategy pattern involves encapsulating related algorithms as separate objects. Depending on the situation, the apporpriate algorithm can be chosen. For example, suppose we have a paint program. The way that an image is represented in memory is different than the way it is stored. Furthermore, there are multiple formats for storing an images. Some with compression, some without. Thus, we can create 3 separate Exporter objects that will export to the 3 different file formats. All three implement the same interface as the abstract Exporter object. Thus the client can be written to the interface of the exporter object while being able to choose the appropriate concrete exporter when appropriate.

#include <iostream>
#include <string>
using namespace std;

class Image;

//this is the abstract base class that forms
//the interface for the strategy
class Exporter{
public:
    //this function is implemented in each
    //of the different exporters
    virtual void writeToFile(const char* fname, Image& s)=0;
};
class PNGExporter:public Exporter{
public:
    virtual void writeToFile(const char* fname, Image& s);
};

class JPEGExporter:public Exporter{
public:
    virtual void writeToFile(const char* fname, Image& s);
};
class GIFExporter:public Exporter{
public:
    virtual void writeToFile(const char* fname, Image& s);
};

//this is an example of a context. It contains
//the information needed by the algorithm
class Image{
    string pixels_;
    Exporter* exp_;
public:
    Image(){
        pixels_="the picture";
    }
    string pixels() {return pixels_;}
    void setExporter(Exporter* e){
        exp_=e;
    }
    void exportImage(){
        if(exp_)    
            exp_->writeToFile("myPicture", *this);
    }

};
void PNGExporter::writeToFile(const char* fname, Image& s){
    cout << "printing to: " << fname << ".png" << endl;
    cout << s.pixels() << endl;
}
void JPEGExporter::writeToFile(const char* fname, Image& s){
    cout << "printing to: " << fname << ".jpg" << endl;
    cout << "compressing" << endl;
    cout << s.pixels() << endl;
}
void GIFExporter::writeToFile(const char* fname, Image& s){
    cout << "printing to: " << fname << ".gif" << endl;
    cout << s.pixels() << endl;
}

//at run time, the appropriate stategy can be set (and even changed)
int main(void){
    Image img;
    Exporter* e;
    int choice;
    cout << "would you like to print to png, jpeg, or gif format?" << endl;
    cout << "1) png" << endl;
    cout << "2) jpeg" << endl;
    cout << "3) gif" << endl;
    cin >> choice;
    if(choice == 1)
        e=new PNGExporter();
    else if(choice==2)
        e=new JPEGExporter();
    else if(choice==3)
        e=new GIFExporter();
    img.setExporter(e);
    img.exportImage();

}

results matching ""

    No results matching ""