黄国强 2023/06/02
前文说到 Data 类作为基类,它有2个派生类,一个是 String 类,一个是 Image 类。
当面对一个系统或一个领域,我们认为,事物分三种情形,分别是不存在、存在一个和无数个。
用面向对象来描述,即为空对象(Null Object)模式,单例(Singleton)模式和组合(Composite)模式。
下面这里例子类拥有访问这三种情形的方法,类似这种设计很常见。
/////////////////////////////////////////////////////////////////////////////////////////
// 数据类
class Data;
using DataPtr = std::shared_ptr<Data>;
class Data
{
public:
// 创建一个指定类型的对象,比如,参数传入"string",返回一个 String 数据对象指针
static DataPtr CreateObj(const char * pszTypeName);
// 获得一个空对象
static DataPtr NullObj();
// 获得一个单例对象,即全局唯一对象
static Data * Singleton();
// 如果对象是一个组合,返回子对象个数,否则返回 0
int Size() const { return DoSize(); }
// 如果对象是一个组合,返回 Index 指定的第几个子对象,否则返回一个空对象
Data * At(int Index) { return DoAt(Index); }
// 是否是空对象
bool IsNullObj() const { return DoNullObj(); }
// 是否是组合对象
bool IsComposite() const { return DoComposite(); }
protected: // 下面是 NVI 模式的虚函数
virtual Data * DoAt(int Index) const { return NullObj().get(); }
virtual bool DoComposite() const { return false; }
virtual bool DoNullObj() const { return false; }
virtual int DoSize() const { return 0; }
};
具体实现类从 Data 类继承,可以不断扩展新的类型,调用者对此一无所知。
[参考链接]