Quale dovrebbe essere nella parte superiore dell'albero di ereditarietà del pattern di progettazione Decorator? Intendo la base per entrambi i componenti e decoratori
- Classe non astratta : ha campi dati, metodi implementa
- classe astratta : ha campi dati, ha solo metodi astratti (puramente virtuali)
- interfaccia : nessun campo dati, ha solo metodi astratti (puramente virtuali)
- classe astratta & interfaccia : l'interfaccia è la base del decoratore, la classe astratta è la base per i componenti decorati
Semplice esempio
-
IText
- l'interfaccia dichiara il metodogetContent()
-
AbstractText
- la classe astratta dichiara il metodogetContent()
e definiscetxt
dati campo -
Text
- la classe non astratta, generale, può essere utilizzata anche come base per altre classi -
HelloWorld
- classe non astratta, più specifica diText
-
HelloSomeone
- classe non astratta, estendeText
con il campo datiname
-
Decorator
classe astratta per decoratori (potrebbe essere ridondante?) -
PrefixDecorator
prefisso di classe decoratoregetContent()
con un prefisso di stringa -
SuffixDecorator
decoratore suffissi di classegetContent()
con un suffisso di stringa -
getContent()
metodo che dovrebbe restituire txt con dati aggiuntivi facoltativi (suffissi e prefissi dai decoratori, camponame
nella classeHelloSomeone
)
Quale classe base dovrebbe essere scelta?
-
classe non astratta
classeastratta
-
interfaccia
classeastratta&interfaccia
Codice per l'ultimo esempio
#include <iostream>
#include <string>
using namespace std;
/* Base for decorator & abstract: no fields, getContent() is pure virtual */
class IText {
public:
virtual string getContent() = 0;
virtual ~IText() { }
};
/* Base: has a field, getContent() is pure virtual */
class AbstractText : public IText {
protected:
string txt;
public:
virtual ~AbstractText() { cout << " AbstractText dtor" << endl; }
AbstractText(string t = "...") : txt(t) { }
virtual string getContent() = 0;
};
/* Concrete, general */
class Text : public AbstractText {
public:
virtual ~Text() { cout << " Text dtor" << endl; }
Text(string t) : AbstractText(t) { }
virtual string getContent() { return txt; }
};
/* Concrete, more specific */
class HelloWorld : public AbstractText {
public:
virtual ~HelloWorld() { cout << " HelloWorld dtor" << endl; }
HelloWorld() : AbstractText("Hello world") {}
virtual string getContent() { return txt; }
};
/* Additional field */
class HelloSomeone : public AbstractText {
private:
string name;
public:
virtual ~HelloSomeone() { cout << " HelloSomeone dtor" << endl; }
HelloSomeone(string n) : AbstractText("Hello, "), name(n) { }
string getContent() { return (txt + name + "!"); }
};
class Decorator : public IText {
public:
virtual string getContent() = 0;
virtual ~Decorator() { cout << " Decorator dtor" << endl; }
};
class PrefixDecorator : public Decorator {
private:
IText *t;
public:
PrefixDecorator(IText *te) { t = te; }
virtual ~PrefixDecorator() { cout << " PrefixDecorator dtor" << endl; delete t; }
virtual string getContent() { return "---" + t->getContent(); }
};
class SuffixDecorator : public Decorator {
private:
IText *t;
public:
SuffixDecorator(IText *te) { t = te; }
virtual ~SuffixDecorator() { cout << " SuffixDecorator dtor" << endl; delete t; }
virtual string getContent() { return t->getContent() + "---"; }
};
int main() {
IText *t = new Text("some text");
IText *hw = new HelloWorld();
IText *hs = new HelloSomeone("Mark");
cout << t->getContent() << endl;
cout << hw->getContent() << endl;
cout << hs->getContent() << endl;
t = new PrefixDecorator(t);
hw = new PrefixDecorator(hw);
hw = new SuffixDecorator(hw);
cout << t->getContent() << endl;
cout << hw->getContent() << endl;
cout << "DELETE Text" << endl;
delete t;
cout << "DELETE Helloworld" << endl;
delete hw;
cout << "DELETE HelloSomeone" << endl;
delete hs;
}