What kind of base for Decorator: interface, abstract class, non-abstract

What should be at the top of inheritance tree of Decorator design pattern?
I mean the base for both components and decorators

  • non-abstract class: has data fields, implements methods
  • abstract class: has data fields, has only abstract (pure virtual) methods
  • interface: no data fields, has only abstract (pure virtual) methods
  • abstract class & interface: interface is the base for decorator, abstract class is the base for decorated components

Simple example

  • IText – interface declares getContent() method
  • AbstractText – abstract class declares getContent() method and defines txt data
    field
  • Text – non-abstract class, general, can be also used as base for other classes
  • HelloWorld – non-abstract class, more specific than Text
  • HelloSomeone – non-abstract class, extends Text with the data field name
  • Decorator abstract class for decorators (might be redundant?)
  • PrefixDecorator decorator class prefixes getContent() with a string prefix
  • SuffixDecorator decorator class suffixes getContent() with a string suffix
  • getContent() method that should return txt with optional additional data (suffixes and prefixes from decorators, name field in the HelloSomeone class)

What base class should be chosen?

  • non-abstract class
    enter image description here

  • abstract class
    enter image description here

  • interface
    enter image description here

  • abstract class & interface
    enter image description here

Code for last example

#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;
}

2

What should be at the top of inheritance tree of Decorator design pattern?

How to discriminate:

  • non-abstract class – Only if it makes sense in your code to instantiate it in client code (also see: liskov substitution)
  • abstract class or interface – most common case; This is when it doesn’t make sense for client code to instantiate it; To distinguish between abstract class and interface: If you look through your code and find that all specializations have data in common, move it to the base class (otherwise, remain with the interface).
  • abstract class and interface – if there are two cases when a part of your specializations have common code and a part don’t, extract common code to separate class, and you end up with both cases.

My criteria is usually not derived from some pure rules that I respect to implement the decorator; Instead, I try to optimize for maintenance instead of purity.

You can also see that I do not particularly differentiate between abstract classes and interfaces; this is because in C++ there are no interfaces – only abstract classes (so the distinction feels a bit artificial).

It depends entirely on what you want. These variations exist for your convenience, not because one way is a better way than another.

Personally I’m partial to the non-abstract class, because it requires the fewest number of classes, which in my opinion is always a plus. However, you may find yourself in the situation in which there is an AbstractText class or IText and an Text implementation, in which case you may model your Decorator pattern accordingly.

If you do decide to choose the non-abstract class variation, it is probably the easiest to adapt into the other variations later since it is usually easier to add classes than to remove them, so I would give the non-abstract class variation a try.

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật