我正在编写一个小地址簿应用程序,并且在数据源/后端的接口方面存在设计困境。
我有以下数据源类的抽象基类:
class DataSource
{
private:
public:
virtual std::auto_ptr<Contact> getContact(int id) = 0;
virtual ContactRecordSet getAllContacts() = 0;
virtual bool addContact(const Contact& c) = 0;
virtual bool updateContact(int id, const Contact& c) = 0;
virtual bool deleteContact(int id)=0;
virtual ~DataSource() {};
};
下面是我的记录结构,tmy 记录集是这些对象的 STL 向量的 typedef。
class Contact
{
public:
std::string firstName;
std::string lastName;
std::string phoneNumber;
std::string address;
std::string email;
};
typedef std::vector<Contact> ContactRecordSet;
我的问题涉及用于 DataSource::getContact() 方法和 DataSource::getAllContacts() 方法的返回值类型以及即将添加的搜索方法,它将根据查询获取记录。
DataSource::getContact() 将返回零或 1 条记录,因为我正在通过唯一 ID 查找。DataSource::getAllContacts() 将返回零个或多个联系人。即将到来的搜索方法将返回零个或多个联系人。
正如我现在所拥有的那样,getContact() 方法正在将 auto_ptr 返回给联系人,因为如果我确定它们永远不会超过一个,那么返回 ContactRecordSet 似乎很浪费,并且如果没有记录,它允许我返回 NULL有那个id。
让 getContact() 也返回一个 ContactRecordSet 会更好吗,只是为了让接口保持一致?
我的一部分对为单个对象返回类似的数据结构的想法感到恼火,但另一方面它更加一致,并且用于检查是否为该 id 找到值的语义似乎更符合整体抽象设计(检查返回记录集的长度与检查 NULL auto_ptr)。
大家怎么看?
(注意 - 我知道我可能对一个简单的地址簿应用程序进行了过度设计,但我希望能够轻松交换不同的后端(平面文件、SQL 等),前提是它们实现了常见的接口。目标是实践良好的模块化设计和关注点分离。)
更新
我想我可以从相反的角度来看,并使多个记录方法将 auto_ptrs 返回到 ContactRecordSet objectcs。那样a)它是一致的,因为你总是得到一个指向对象的指针,b)如果记录集为空,你没有返回 std::vector 的开销,只需返回一个 NULL 指针。