Article From:https://www.cnblogs.com/ToBeExpert/p/9686960.html

2018-09-21  10:07:30

Enjoy element model

  Flyweight, which uses shared technology to support a large number of fine grained objects effectively.

Shared class UML class diagram

·  

FlyWeightFactory:It is used to create and manage enjoyable objects. It is programmed for abstract enjoyable classes and stores various types of specific enjoyable objects in a enjoyable pool. The enjoyable pool is generally designed to store a collection of “key-value pairs” (or other types of collections), which can be designed in combination with factory patterns; when a user requests a toolWhen the entity enjoys a meta object, the enjoyment factory provides an instance that has been created in the enjoyment pool or creates a new instance (if it does not exist), returns the newly created instance and stores it in the enjoyment pool. Its main role is to create and manage shared meta objects to ensure a reasonable share of Flywei.Ght.

Flyweight:The common base class of all specific enjoyment classes through which Flyweight can be accepted and used as an external state.

SharedConcreteFlyweight(ConcreteFlyweight):An Abstract hedonic class is implemented. Its instance is called hedonic object. It provides storage space for the internal state in the specific hedonic class. Usually, a specific hedonic class can be designed with singleton pattern to provide a unique hedonic object for each hedonic class. Most of the time, we need to use shared object to reduce memory loss.Not all cases require shared elements, which is the necessity of the existence of UnSharedConcreteFlyweight classes.

UnSharedConcreteFlyweight:This class refers to objects that do not need to be shared, and although sharing is possible through the Flyweight design, it does not force sharing. Because there are bound to be objects that do not need to be shared when using the client. It exists to solve those needs.Share the problem of objects.

  Shared meta-schema is somewhat similar to factory schema in that on the one hand, shared meta-schema provides the ability to dynamically add objects, on the other hand, client code in shared meta-schema can not only use products created by shared meta-factories, it can directly use UnShared ConcreteF.The object of lyweight. In addition, the fundamental purpose of the shared meta-pattern is to share objects, reduce the number of code instances, but also improve the code reusability. When it is used, it is bound to have some similarity between objects, but the performance is different in the external state.

Internal state and external state

  The shared part within the enjoyable object that does not change with the environment can be called the internal state of the enjoyable object, and the non-shared state that changes with the environment is the external state, of course, the enjoyable element can have no internal state, and the external state is best by the customer code or a third party.Class trusteeship. In fact, the shared mode can avoid the expense of a large number of very similar classes. In programming to find that, sometimes we need to generate a large number of fine grained class instances to represent data. If you find that these instances are basically the same except for a few parameters, you can sometimes dramatically reduce the number of classes that need to be instantiatedQuantity. If you can move those parameters outside of a class instance and pass them in (external state) when a method is called, you can dramatically reduce the number of individual instances by sharing them.

Advantages and disadvantages of Xiang Yuan mode

Advantage:

  1.Saving memory resources by sharing objects reduces performance consumption (in some cases, too many objects can lead to resource and performance losses at runtime)

  2.The internal state of the hedonic mode is stable and unchanged, while the external state changes with the environment and does not affect the internal state. The different external state is the result of different operations of the hedonic object, which makes it possible to share objects.

Shortcomings:

  1.The hedonic mode needs to maintain a list of all the existing hedons in the system, which itself consumes resources and requires a lookup every time the hedonic is used, which reduces the efficiency of the program.

  2.Hedonic mode makes the system more complex because you need to pull out the inner and outer states of the hedonic element. The outer states of the hedonic element are different in different environments, which increases the logical complexity of the program.

Application scenario:

  1.When there are enough objects (the same or similar objects) that cause a lot of storage overhead, hedonic mode should be considered, and most of the state of the object can be detached from the external state. If the external state of the object is deleted, many groups can be replaced by relatively small shared objectsObjects can also be considered using shared mode at this time.

  2.The hedges have to be used extensively to have the value of using the hedges mode, because when using the hedges mode, you need to maintain a key-value data structure for all the existing hedges, which in itself requires resources to be consumed.

Code examples

  Problem model: Go system, in a Go system, there are black, white, as well as chessboard, chess box. There are 181 sunspots and 180 whites, totaling 361 pieces. In the process of playing chess, each piece will have its own coordinates. There are 384 checkerboards, if you are each.To instantiate a chessman object, it will consist of 384 chessmen. Here we can use the shared element mode. Next, analyze the internal and external state. For chessboard, chessboard, chessboard, they have a fixed color, this will not change, so the color is the internal state. Standard double player mode, chess box onlyThere are two, one chessboard, so they have no shared meaning (but they still have a problem showing coordinates relative to the interface, so external variables hold for them). For a chessboard, the coordinates of each object are external patterns, and the chessboard can be displayed differently depending on the coordinates.Position.

1.Abstract privilege primitive class (Flyweight)

#ifndef FLYWEIGHT_H_
#define FLYWEIGHT_H_

#include <iostream>
#include <string>

class Flyweight
{
public:
    virtual void display(const int iX,const int iY) = 0;
    Flyweight() = default;
    virtual ~Flyweight() = default;
protected:
    std::string m_strColor;
};
#endif

Flyweight

2.Shared class (SharedFlyweight)

#ifndef SHAREDFLYWEIGHTWHITE_H_
#define SHAREDFLYWEIGHTWHITE_H_
#include "Flyweight.h"

class SharedConcreteFlyweightWhite : public Flyweight
{
public:
    void display(const int iX,const int iY) override;
    SharedConcreteFlyweightWhite()
    {
    m_strColor = "White";
    }
    ~SharedConcreteFlyweightWhite() = default;
};
#endif

#include "SharedFlyweightWhite.h"

void SharedConcreteFlyweightWhite::display(const int iX,const int iY)
{
    std::cout << " I am a " << m_strColor << "chess pieces,my coordinate is (" << iX << "," << iY << ")." << std::endl;
}

#ifndef SHAREDFLYWEIGHTBLACK_H_
#define SHAREDFLYWEIGHTBLACK_H_

#include "Flyweight.h"

class SharedConcreteFlyweightBlack : public Flyweight
{
public:
   void display(const int iX,const int iY) override;
   SharedConcreteFlyweightBlack()
   {
    m_strColor = "Black";
   }
   ~SharedConcreteFlyweightBlack() = default;
};

#endif

#include "SharedFlyweightBlack.h"

void SharedConcreteFlyweightBlack::display(const int iX,const int iY)
{
    std::cout << "I am a black Chess,my coordinate is (" << iX << "," << iY << ")" << std::endl;
}

SharedFlyweight

3.Non shared privilege classes (UnsharedFlyweight)

#ifndef UNSHAREDCONCRETEFLYWEIGHTCHESSBOX_H_
#define UNSHAREDCONCRETEFLYWEIGHTCHESSBOX_H_

#include "Flyweight.h"

class UnsharedConcreteFlyweightChessbox : public Flyweight
{
public:
    void display(const int iX,const int iY) override;
    UnsharedConcreteFlyweightChessbox()
    {
    m_strColor = "Yellow";
    }
    ~UnsharedConcreteFlyweightChessbox() = default;
};
#endif 

#include "UnsharedConcreteFlyweightChessBox.h"

void UnsharedConcreteFlyweightChessbox::display(const int iX,const int iY)
{
    std::cout << "I am a " << m_strColor << " chessbox,my coordinate is (" << iX << "," << iY << ")" <<std::endl;
}

UnsharedFlyweight

4.Flyweight(Core components of Xiang Yuan mode

#ifndef FLYWEIGHTFACTORY_H_
#define FLYWEIGHTFACTORY_H_

#include "Flyweight.h"
#include "SharedFlyweightWhite.h"
#include "SharedFlyweightBlack.h"
const std::string BLACKCHESS = "Black";
const std::string WHITECHESS = "White";
#include <map>
class FlyweightFactory
{
private:
    std::map<std::string,Flyweight*> m_mapFlyweight;
public:
    Flyweight* getFlyweight(const std::string strKey);
    int getFlyweightCount()
    {
    return m_mapFlyweight.size();
    }
};
#endif

#include "FlyweightFactory.h"

// strKey is defined class name or surname of class 
Flyweight* FlyweightFactory::getFlyweight(const std::string strKey)
{
    //if find return FlyWeight object whose key is equal,otherwise new object and insert into map
    if(m_mapFlyweight.end() != m_mapFlyweight.find(strKey))
    return m_mapFlyweight[strKey];
    if(strKey == BLACKCHESS)
    {
        auto pointer = new SharedConcreteFlyweightBlack;
    m_mapFlyweight[strKey] = pointer;
        return pointer;
    }
    else if(strKey == WHITECHESS)
    {
        auto pointer  = new SharedConcreteFlyweightWhite;
        m_mapFlyweight[strKey] = pointer;
        return pointer;
    }
    else
    {
    std::cout << "The key is Error!" << std::endl;
      return nullptr;
    }
}

Flyweight

5.Client

#include "FlyweightFactory.h"
#include "UnsharedConcreteFlyweightCheckerboard.h"
#include "UnsharedConcreteFlyweightChessBox.h"

using namespace std;

int main(int argc,char *argv[])
{
    FlyweightFactory objFactory;
    auto objBlack = objFactory.getFlyweight(BLACKCHESS);
    if(nullptr != objBlack)
    objBlack->display(3,5);
    auto objBlack1 = objFactory.getFlyweight(BLACKCHESS);
    if(nullptr != objBlack1)
    objBlack1->display(1,4);
    std::cout << "count "<< objFactory.getFlyweightCount() << std::endl;
   
    auto objWhite = objFactory.getFlyweight(WHITECHESS);
    if(nullptr != objWhite)
    objWhite->display(9,9);
    std::cout << "count:" << objFactory.getFlyweightCount() << std::endl;
    auto objWhite1 = objFactory.getFlyweight(WHITECHESS);
    if(nullptr != objWhite1)
    objWhite1->display(8,8);
    std::cout << "count: "<< objFactory.getFlyweightCount() << std::endl;
    UnsharedConcreteFlyweightChessbox  unshChessbox;
    unshChessbox.display(1,2);
    std::cout <<"count:" << objFactory.getFlyweightCount() << std::endl;
    return(1);
}

Client

 

Link of this Article: The pattern of design patterns

Leave a Reply

Your email address will not be published. Required fields are marked *