C++ 这是设计还是工程? 你会考虑使用一个接口和多态性来扩展这个设计吗?
专业人士C++ 这是设计还是工程? 你会考虑使用一个接口和多态性来扩展这个设计吗?,c++,polymorphism,C++,Polymorphism,专业人士 可扩展 封装 自动魔法 缺点 更多的代码 使用起来有点笨重(必须使用不同的类型名称才能获得不同的行为) 由于虚拟函数调用,可能使用效率较低 我的直觉是,对于这种特殊情况,单个if语句和布尔标志是更好的选择,但并非所有人都同意我的观点 你觉得怎么样 原创 // Connects to a local pipe, and naturally // owns that connection struct CommandWriter { CommandWriter() {
- 可扩展
- 封装
- 自动魔法
- 更多的代码
- 使用起来有点笨重(必须使用不同的类型名称才能获得不同的行为)
- 由于虚拟函数调用,可能使用效率较低
if
语句和布尔标志是更好的选择,但并非所有人都同意我的观点
你觉得怎么样
原创
// Connects to a local pipe, and naturally
// owns that connection
struct CommandWriter
{
CommandWriter() {
fd = open("/path/to/fifo", O_WRONLY);
if (fd == -1)
throw std::runtime_error("Could not establish connection to FIFO");
};
~CommandWriter() {
close(fd);
};
// (Has useful member functions here)
private:
CommandWriter(CommandWriter const&); // Not relevant to question
int fd;
};
使用布尔标志扩展
// Adds a constructor where an FD can be specified
// from the call site, and no ownership is taken
struct CommandWriter
{
CommandWriter() : owns_fd(true) {
fd = open("/path/to/fifo", O_WRONLY);
if (fd == -1)
throw std::runtime_error("Could not establish connection to FIFO");
};
CommandWriter(int fd) : fd(fd), owns_fd(false) {};
~CommandWriter() {
if (owns_fd)
close(fd);
};
// (Has useful member functions here)
private:
CommandWriter(CommandWriter const&); // Not relevant to question
int fd;
bool owns_fd;
};
用多态性扩展
// Sorry for the poor type names!
struct ICommandWriter
{
virtual ICommandWriter() {}
// (Has useful member functions here)
private:
ICommandWriter(ICommandWriter const&); // Not relevant to question
};
struct CommandWriter_Connects : ICommandWriter
{
CommandWriter_Connects() {
fd = open("/path/to/fifo", O_WRONLY);
if (fd == -1)
throw std::runtime_error("Could not establish connection to FIFO");
};
~CommandWriter_Connects() {
close(fd);
};
// (Has useful member functions here)
private:
int fd;
};
struct CommandWriter_Uses : ICommandWriter
{
CommandWriter_Uses(int fd) : fd(fd) {};
~CommandWriter_Uses() {};
// (Has useful member functions here)
private:
int fd;
};
这取决于你要用它做什么。如果您有一个大型项目,并且将多次使用该类的变体,那么使其灵活无疑是有意义的 经验法则:
当然也有很多例外,但这是一个起点。我同意你的观点,如果你不希望在将来添加更多的功能,布尔解决方案在这里是合适的
另一种解决方案是使用。这类似于Boost的智能指针的自定义删除器。 < P>我会考虑工程方面的问题。第二个代码段更加简洁,使用起来也很简单。使用标志来表示对对象的所有权并不是完全惯用的,但它可以经常看到,所以我认为大多数人会很快理解其意图 保持简单和愚蠢。 (如果确定将来需要添加更多的代码路径,我更喜欢多态解决方案)。为什么不只添加文件描述符?这样,当对象被销毁时,您只需关闭()它,让操作系统处理其余部分:
CommandWriter::CommandWriter (int _fd) : fd (dup (_fd)) {};
为此添加布尔标志就是发明了一个轮子。使用多态性正在建造一架护卫直升机。我更喜欢界面。原因是,界面的用户很清楚,可以有各种实现。也许在一个月后,您需要实现一个CommandWriter,它可以写入db而不是文件(当然,您甚至可以将布尔版本子类化,但对于用户来说,它作为一个界面并不明显) 对于单元测试,我想说接口是更干净的方法,因为您可以为要测试的类实现存根,这些类使用ICommandWriter
但是如上所述,如果只想使用一次,只需使用带有布尔标志的版本。在多态性代码中:
// (Has useful member functions here)
是吗?如果在这三个地方(基类和两个派生类)都有很多成员函数,那么拥有和不拥有的编写器就完全不同了。最好将它们划分为不同的类,而不是让一个类根据调用构造函数的布尔标志集的行为非常不同
我怀疑所有有用的成员函数都在基类中,而所有派生类所做的只是更改构造和销毁。在这种情况下,我需要一个
smart\u fd
类来保存一个fd并知道如何处理它(您需要两种情况-调用close或不执行任何操作。shared\u ptr
允许任意销毁函数,但这里可能不需要)
然后在您的CommandWriter中有一个,并根据调用CommandWriter的构造函数的不同来初始化它
经验法则:管理资源的类不应该做任何其他事情。“过度工程”是一个主观概念,或者至少取决于上下文;您打算如何处理此代码?(为什么所有这些结构,“类”在你看来这么难看?@Raveline:我选择
struct
还是class
,都没有关系。我决定对问题中的代码使用struct
,以节省使用无意义的public:
说明符所浪费的空间。为什么您不喜欢结构体?期望值通常是模糊的。我想说的是:暂时保留布尔值,如果将来在添加功能时变得混乱,如果有必要,则重构它。+1用于使整个问题变得毫无意义(至少对于这个假设性问题得到证实的现实情况是如此)。:)+1:这里的关键洞察:如果你发现自己正忙于这样的,我应该使用条件或变形来表达备选方案
决策吗,退后一步,问问你自己我需要备选方案吗?
.a.k.a。“一,二,很多”。程序员不需要能够计数;-)@史蒂夫:特别是因为任何超过两次的事情都会在一个循环中发生…;)我认为是这样的(他说,链接到一篇文章,该文章将你的短语列为一个可接受的变体)。“尽管我怀疑所有有用的成员函数都在基类中,[…]”的确如此。smart\u fd
。尽可能多地使用一些智能指针或其他接口,不要更多。可能范围内的ptr
就是模型。例如,如果CommandWriter
是不可复制的,那么我们的smart\u fd
至少目前不需要。