首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >装饰的基础是:接口、抽象类、非抽象类。

装饰的基础是:接口、抽象类、非抽象类。
EN

Software Engineering用户
提问于 2015-04-01 08:50:02
回答 2查看 3.3K关注 0票数 7

装饰设计模式继承树的顶端应该是什么?我指的是零部件和装饰师的基础。

  • 非抽象类:有数据字段,实现方法
  • 抽象类:有数据字段,只有抽象(纯虚拟)方法
  • 接口:没有数据字段,只有抽象(纯虚拟)方法。
  • 抽象类和接口:接口是装饰器的基础,抽象类是装饰组件的基础。

简单例子

  • IText -接口声明getContent()方法
  • AbstractText -抽象类声明getContent()方法并定义txt数据字段。
  • Text -非抽象类,一般,也可以用作其他类的基础。
  • HelloWorld -非抽象类,比Text更具体
  • HelloSomeone --非抽象类,使用数据字段name扩展Text
  • 用于装饰器的Decorator抽象类(可能是冗余的?)
  • PrefixDecorator装饰器类以字符串前缀为getContent()前缀。
  • 带有字符串后缀的SuffixDecorator装饰器类后缀getContent()
  • getContent()方法,它应该返回带有可选附加数据的txt ( HelloSomeone类中的修饰器、name字段的后缀和前缀)。

应该选择哪个基类?

  • 非抽象类
  • 抽象类
  • 接口
  • 抽象类与接口

最后一个示例的代码

代码语言:javascript
复制
#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;
}
EN

回答 2

Software Engineering用户

回答已采纳

发布于 2015-04-01 14:28:22

装饰设计模式继承树的顶端应该是什么?

如何区分:

  • 非抽象类-只有在代码中在客户端代码中实例化它才有意义(另见: liskov替换)
  • 抽象类或接口--最常见的情况;客户端代码实例化它是没有意义的;区分抽象类和接口:如果您仔细查看代码,发现所有专门化都有数据,请将其移到基类中(否则,保留在接口中)。
  • 抽象类和接口--如果有两种情况,即您的专门化的一部分有公共代码,而部分没有,则提取公共代码以分离类,最后这两种情况都会发生。

我的标准通常不是从一些我所尊重的实现装饰者的纯规则中派生出来的;相反,我试图为维护而不是为了纯度而优化。

您还可以看到,我并不特别区分抽象类和接口;这是因为在C++中没有接口--只有抽象类(因此这种区别感觉有点人为的)。

票数 5
EN

Software Engineering用户

发布于 2015-04-01 10:54:47

这完全取决于你想要什么。这些变化的存在是为了你的方便,而不是因为一种方式比另一种更好。

就我个人而言,我倾向于非抽象类,因为它需要最少的类数,在我看来,这总是一个优点。但是,您可能会发现存在一个AbstractText类或IText以及一个Text实现,在这种情况下,您可以相应地建模您的装饰器模式。

如果您确实决定选择非抽象类变体,那么很可能最容易适应其他变体,因为添加类通常比删除类容易,所以我会尝试一下非抽象类变体。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/277940

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档