I need to decode and encode TLV (Tag, Length, Value) data which is a composite part-whole tree structure. Tag1 Len1 Tag2-Len2-Value2 Tag3-Len3-Value3 ... TagN-LenN-ValueN          ------------------------Value1------------------------Therefore, I've decided to use the Composite pattern for the TLV objects:typedef std::unique_ptr<TLVComponent> TLVComponentPtr;class TLVComponent{public:    TLVComponent();    virtual ~TLVComponent();    virtual void Decode(const std::string &packet) = 0;    virtual std::string Encode() = 0;    virtual void AddTLV(TLVComponentPtr tlv); // only used in the constructor TLV    unsigned char GetTag();    unsigned char GetLen();    std::vector<unsigned char> GetBytes();    std::string GetBytesStr();protected:    unsigned char mTag;    unsigned char mLen;    std::vector<unsigned char> mBytes;};class PrimitiveTLV : public TLVComponent{public:    PrimitiveTLV();    PrimitiveTLV(const std::string &packet);    PrimitiveTLV(int tag, const std::string &bytes);    virtual ~PrimitiveTLV();    virtual void Decode(const std::string &packet);    virtual std::string Encode();    virtual void AddTLV(TLVComponentPtr tlv); // throw exception if called};class ConstructorTLV : public TLVComponent{public:    ConstructorTLV(unsigned char tag);    ConstructorTLV(std::string packet);    virtual ~ConstructorTLV();    virtual void Decode(const std::string &packet);    virtual std::string Encode();    virtual void AddTLV(TLVComponentPtr tlv);private:    std::vector<TLVComponentPtr> mTLVs;};And here is the way I create a sample composite TLV object (please note that the real-world TLVs are not this simple and their values could be parameterized):std::string bytes = ;bytes += 0x12;bytes += 0x34;unsigned char tag = 0x10;PrimitiveTLV pTLV1(tag, bytes);bytes = ;bytes += 0x56;bytes += 0x78;tag = 0x20;PrimitiveTLV pTLV2(tag, bytes);bytes = ;bytes += 0x91;bytes += 0xA1;tag = 0x30;PrimitiveTLV pTLV3(tag, bytes);tag = 0x20;ConstructorTLV cTLV1(tag);cTLV1.AddTLV(&pTLV1);cTLV1.AddTLV(&pTLV2);tag = 0x80;ConstructorTLV cTLV3(tag);cTLV3.AddTLV(&cTLV1);cTLV3.AddTLV(&pTLV3);std::string cTLV3Encoded = cTLV3.Encode();As the creation of the cTLV3 is complex, error-prone and is done via several steps, I have decided to use the Builder Pattern to create my TLV objects:The problem is that I don't know how the Builder abstract and concrete classes fit in my design. I think the Director class of the pattern suffices for me:////// \brief The TLV maker. (Director role in the Builder pattern)///class TLVMaker{public:    TLVMaker();    virtual ~TLVMaker();    ///    /// \brief Creates the primitive TLV A    /// \return     ///    TLVComponentPtr MakeTLVA();    ///    /// \brief Creates the primitive TLV B    /// \return     ///    TLVComponentPtr MakeTLVB();    ///    /// \brief Creates the primitive TLV C    /// \return     ///    TLVComponentPtr MakeTLVC();    ///    /// \brief Creates the constructor TLV D    /// \return     ///    TLVComponentPtr MakeTLVD();    ///    /// \brief Creates the constructor TLV E    /// \return     ///    TLVComponentPtr MakeTLVE();};And the implementation of the Director:TLVComponentPtr TLVMaker::MakeTLVA(){    std::string bytes = ;    bytes += 0x12;    bytes += 0x34;    uchar tag = 0x10;    TLVComponentPtr tlv(new PrimitiveTLV(tag, bytes));    return tlv;}TLVComponentPtr TLVMaker::MakeTLVB(){    std::string bytes = ;    bytes += 0x56;    bytes += 0x78;    uchar tag = 0x20;    TLVComponentPtr tlv(new PrimitiveTLV(tag, bytes));    return tlv;}TLVComponentPtr TLVMaker::MakeTLVC(){    std::string bytes = ;    bytes += 0x91;    bytes += 0xA1;    uchar tag = 0x30;    TLVComponentPtr tlv(new PrimitiveTLV(tag, bytes));    return tlv;}TLVComponentPtr TLVMaker::MakeTLVD(){    uchar tag = 0x20;    TLVComponentPtr tlv(new ConstructorTLV(tag));    tlv->AddTLV(MakeTLVA());    tlv->AddTLV(MakeTLVB());    return tlv;}TLVComponentPtr TLVMaker::MakeTLVE(){    uchar tag = 0x80;    TLVComponentPtr tlv(new ConstructorTLV(tag));    tlv->AddTLV(MakeTLVD());    tlv->AddTLV(MakeTLVC());    return tlv;}The creation of my sample TLV object becomes very simple now:TLVMaker tlvMaker;    TLVComponentPtr tlvE = tlvMaker.MakeTLVE();std::string tlvE_Encoded = tlvE->Encode();My questions:Have I correctly decided to use the Builder pattern to create my composite objects?I have only been able to use the Director class of the Builder pattern. How can/should I include the abstract and concrete Builder classes as well?If using the Director class (TLVMaker) in my design is enough, can I still claim I have used the Builder pattern?
Creating composite objects using the builder pattern
c++;design patterns