经典装饰器模式,装饰器本身是一种聚合aggregation。装饰器类和被装饰对象应该有共同接口(比如read
和write
)。在实现这些接口的时候,应该调用被装饰对象的方法。
方法可以被装饰(Python常见),同时类也可以被装饰!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 class DataSource { public : virtual ~DataSource () {} virtual void writeData (std::string& data) const = 0 ; virtual std::string readData () const = 0 ; }; class FileDataSource : public DataSource { public : FileDataSource (std::string& filename) { } void writeData (std::string& data) override { } std::string readData () override { } }; class DataSourceDecorator : public DataSource { protected : DataSource* wrappee; public : DataSourceDecorator (DataSource* datasource): wrappee (datasource) { if (!datasource) { throw std::invalid_argument ("DataSource cannot be nullptr" ); } } void writeData (std::string& data) override { wrappee->writeData (data); } std::string readData () override { return wrappee->readData (data); } virtual ~DataSourceDecorator () { delete wrappee; } }; class EncryptionDecorator : public DataSourceDecorator { void writeData (std::string& data) override { std::string encryptedData = encrypt (data); wrappee->writeData (encryptedData); } std::string readData () override { std::string data = wrappee->readData (); return decrypt (data); } }; class CompressionDecorator : public DataSourceDecorator { void writeData (std::string& data) override { std::string encryptedData = compress (data); wrappee->writeData (encryptedData); } std::string readData () override { std::string data = wrappee->readData (); return decompress (data); } }; int main (int argc, char * argv[]) { FileDataSource* source = new FileDataSource ("file.dat" ); source->writeData ("salary records" ); source = new CompressionDecorator (source); source->writeData ("another salary records" ); source = new EncryptionDecorator (source); source->writeData ("last salary records" ); delete source; return 0 ; }