From 1b71cb14dee748f1b5ce310c4efbd053879e67fd Mon Sep 17 00:00:00 2001 From: Jakub Vojvoda Date: Sat, 17 Sep 2016 14:19:27 +0200 Subject: [PATCH] add Flyweight pattern --- flyweight/Flyweight.cpp | 102 ++++++++++++++++++++++++++++++++++++++++ flyweight/README.md | 5 +- 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 flyweight/Flyweight.cpp diff --git a/flyweight/Flyweight.cpp b/flyweight/Flyweight.cpp new file mode 100644 index 0000000..c37b370 --- /dev/null +++ b/flyweight/Flyweight.cpp @@ -0,0 +1,102 @@ +/* + * C++ Design Patterns: Flyweight + * Author: Jakub Vojvoda [github.com/JakubVojvoda] + * 2016 + * + * Source code is licensed under MIT licence + * (for more details see LICENCE) + * + */ + +#include +#include + +/* + * Flyweight + * declares an interface through which flyweights can receive + * and act on extrinsic state + */ +class Flyweight { +public: + virtual ~Flyweight() { /* ... */ } + virtual void operation() = 0; + // ... +}; + +/* + * UnsharedConcreteFlyweight + * not all subclasses need to be shared + */ +class UnsharedConcreteFlyweight : public Flyweight { +public: + UnsharedConcreteFlyweight(int intrinsic_state) : + state(intrinsic_state) {} + + void operation() { + std::cout << "Unshared Flyweight with state " << state << std::endl; + } + // ... + +private: + int state; + // ... +}; + +/* + * ConcreteFlyweight + * implements the Flyweight interface and adds storage + * for intrinsic state + */ +class ConcreteFlyweight : public Flyweight { +public: + ConcreteFlyweight(int all_state) : + state(all_state) {} + + void operation() { + std::cout << "Concrete Flyweight with state " << state << std::endl; + } + // ... + +private: + int state; + // ... +}; + +/* + * FlyweightFactory + * creates and manages flyweight objects and ensures + * that flyweights are shared properly + */ +class FlyweightFactory { +public: + virtual ~FlyweightFactory() { + for (auto it = flies.begin(); it != flies.end(); it++) { + delete it->second; + } + flies.clear(); + } + + Flyweight *getFlyweight(int key) { + if (flies.find(key) != flies.end()) { + return flies[key]; + } + Flyweight *fly = new ConcreteFlyweight(key); + flies.insert(std::pair(key, fly)); + return fly; + } + // ... + +private: + std::map flies; + // ... +}; + + +int main() +{ + FlyweightFactory *factory = new FlyweightFactory; + factory->getFlyweight(1)->operation(); + factory->getFlyweight(2)->operation(); + + return 0; +} diff --git a/flyweight/README.md b/flyweight/README.md index da65bf9..a26ee4b 100644 --- a/flyweight/README.md +++ b/flyweight/README.md @@ -1,9 +1,12 @@ ## Flyweight -Use sharing to support large numbers of fine-grained objects efficiently. +Flyweight pattern has has structural purpose, applies to objects and uses sharing to support +large numbers of fine-grained objects efficiently. The pattern can be used to reduce +memory usage when you need to create a large number of similar objects. ### When to use +* when one instance of a class can be used to provide many "virtual instances" * when all of the following are true * an application uses a large number of objects * storage costs are high because of the sheer quantity of objects