将数据成员放在接口中可以吗?
Is it alright to put data members in an interface?
最近,我了解了 composite pattern
。我想在我必须实现文件和文件夹 类 的作业中使用它。我意识到像 CFile
和 Cfolder
这样的子 类 必须具有相同的属性(name
和 size
)。那我把属性放到interface
里可以吗?据我所知,这样做不是好的做法。但是,我不明白为什么我不应该这样做。或者还有其他解决方案吗?
其实不是"is it a good practice"的问题。通过创建一个接口,您正在定义一个标准。问题是,你需要接口的实现来包含那些数据成员吗?您最了解您的实现,因此您确实是唯一可以回答这个问题的人。
作为一般规则,实现接口的 class 应该是一个黑盒子,外界不应该访问任何内部(包括成员数据)。接口定义了支持接口所需的通用功能,我希望这些实现细节仅作为一般规则隐藏在 class 的底层实现中。 YMMV。
我会说这不是问题。区别在于,你有一个 抽象基础 class 而不是 纯接口 class。但是,如果您想保留使用 interface 的灵活性来实现不依赖于那些特定成员变量的实现,那么您总是可以创建一个 interface class 以及一个 抽象基础 class 以获得完全的灵活性。虽然这可能很快就会变得过于复杂,但如果需要,您可以随时将 接口 从 抽象基础 中拆分出来。
using CItemUPtr = std::unique_ptr<class CItem>;
/**
* Interface class
*/
class CItem
{
public:
virtual ~CItem() {}
virtual CItemUPtr findByName(std::string const& name) = 0;
virtual void setHidden(bool a, bool b) = 0;
};
/**
* Abstract base class
*/
class AbstractCItem
: public CItem
{
protected:
std::string name;
std::size_t size;
};
class CFile
: public AbstractCItem
{
public:
CItemUPtr findByName(std::string const& name) override
{
// stuff
return {};
}
void setHidden(bool a, bool b) override {}
};
class 的设计原则应该是:
'It is impossible to break the class invariant from the outside'
如果构造函数设置 class 不变量,并且所有成员
坚持class不变量,这就实现了。
但是,如果 class 没有 class 不变量,则有
public 成员实现了同样的目标。
// in C++, this is a perfectly fine, first order class
struct Pos
{
int x,y;
Pos& operator+=(const Pos&);
};
最近,我了解了 composite pattern
。我想在我必须实现文件和文件夹 类 的作业中使用它。我意识到像 CFile
和 Cfolder
这样的子 类 必须具有相同的属性(name
和 size
)。那我把属性放到interface
里可以吗?据我所知,这样做不是好的做法。但是,我不明白为什么我不应该这样做。或者还有其他解决方案吗?
其实不是"is it a good practice"的问题。通过创建一个接口,您正在定义一个标准。问题是,你需要接口的实现来包含那些数据成员吗?您最了解您的实现,因此您确实是唯一可以回答这个问题的人。
作为一般规则,实现接口的 class 应该是一个黑盒子,外界不应该访问任何内部(包括成员数据)。接口定义了支持接口所需的通用功能,我希望这些实现细节仅作为一般规则隐藏在 class 的底层实现中。 YMMV。
我会说这不是问题。区别在于,你有一个 抽象基础 class 而不是 纯接口 class。但是,如果您想保留使用 interface 的灵活性来实现不依赖于那些特定成员变量的实现,那么您总是可以创建一个 interface class 以及一个 抽象基础 class 以获得完全的灵活性。虽然这可能很快就会变得过于复杂,但如果需要,您可以随时将 接口 从 抽象基础 中拆分出来。
using CItemUPtr = std::unique_ptr<class CItem>;
/**
* Interface class
*/
class CItem
{
public:
virtual ~CItem() {}
virtual CItemUPtr findByName(std::string const& name) = 0;
virtual void setHidden(bool a, bool b) = 0;
};
/**
* Abstract base class
*/
class AbstractCItem
: public CItem
{
protected:
std::string name;
std::size_t size;
};
class CFile
: public AbstractCItem
{
public:
CItemUPtr findByName(std::string const& name) override
{
// stuff
return {};
}
void setHidden(bool a, bool b) override {}
};
class 的设计原则应该是:
'It is impossible to break the class invariant from the outside'
如果构造函数设置 class 不变量,并且所有成员
坚持class不变量,这就实现了。
但是,如果 class 没有 class 不变量,则有
public 成员实现了同样的目标。
// in C++, this is a perfectly fine, first order class
struct Pos
{
int x,y;
Pos& operator+=(const Pos&);
};