Retornar um vetor sabendo que ele sempre conterá um único registro para ser consistente com o restante da interface?
-
12-11-2019 - |
Pergunta
Estou escrevendo um pequeno aplicativo de catálogo de endereços e tenho um dilema de design em relação à interface da fonte/backend de dados.
Eu tenho a seguinte classe base abstrata para classes de fonte de dados:
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() {};
};
Abaixo está minha estrutura de registro e tmy record set é um typedef para um vetor STL desses objetos.
class Contact
{
public:
std::string firstName;
std::string lastName;
std::string phoneNumber;
std::string address;
std::string email;
};
typedef std::vector<Contact> ContactRecordSet;
Minha pergunta envolve o tipo de valor de retorno usado para o método DataSource::getContact() e o método DataSource::getAllContacts() e o método de pesquisa a ser adicionado em breve que obterá registros com base em uma consulta.
DataSource::getContact() retornará zero ou 1 registro, pois estou procurando por um ID exclusivo.DataSource::getAllContacts() retornará zero ou mais contatos.O próximo método de pesquisa retornará zero ou mais contatos.
Como tenho agora, o método getContact() está retornando um auto_ptr para um contato porque parecia um desperdício retornar um ContactRecordSet se eu tivesse certeza de que eles nunca seriam mais de um e isso me permite retornar NULL se não houver nenhum registro que tem esse id.
Seria melhor que getContact() retornasse um ContactRecordSet também, simplesmente para que a interface permanecesse consistente?
Parte de mim se irrita com a ideia de retornar uma estrutura de dados como essa para um único objeto, mas por outro lado é mais consistente e a semântica para verificar se um valor foi encontrado para aquele id parece mais alinhada com a abstração geral de o design (verifique o comprimento do conjunto de registros retornado vs.verifique se há um auto_ptr NULO).
O que vocês acham?
(Observação: estou ciente de que provavelmente estou exagerando na engenharia de um aplicativo simples de catálogo de endereços, mas quero que seja fácil trocar diferentes back-ends (arquivo simples, SQL, etc.), desde que implementem o comum interface.O objetivo é praticar um bom design modular e separação de interesses.)
ATUALIZAR
Suponho que poderia olhar da perspectiva oposta e fazer com que vários métodos de registro retornassem auto_ptrs para objetos ContactRecordSet.Dessa forma, a) é consistente porque você sempre obtém um ponteiro para um objeto eb) você não tem a sobrecarga de retornar um std::vector se o conjunto de registros estiver vazio, simplesmente retorne um ponteiro NULL.
Solução
Eu sempre sigo o princípio de design de retorne a coisa menos complexa que define seu objeto. Os vetores destinam-se a conter listas de coisas, não de itens únicos e, embora possam tornar a semântica simétrica, sem dúvida não serão intuitivos para outro desenvolvedor.
Outras dicas
O que há de consistente em retornar um tipo plural para uma função não plural?
Acho que você precisa trabalhar com uma definição diferente de "consistência".