Вернуть вектор, зная, что он всегда будет содержать одну запись, чтобы соответствовать остальной части интерфейса?

Я пишу небольшое приложение для адресной книги, и у меня возникла дилемма дизайна в отношении интерфейса для источника данных/бэкенда.

У меня есть следующий абстрактный базовый класс для классов источников данных:

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 представляет собой typedef для вектора STL этих объектов.

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 запись, так как я ищу по уникальному идентификатору. DataSource::getAllContacts() вернет ноль или более контактов. Предстоящий метод поиска вернет ноль или более контактов.

Как у меня сейчас, метод getContact() возвращает auto_ptr в контакт, потому что казалось расточительным возвращать ContactRecordSet, если я точно знаю, что их никогда не будет больше одного, и это позволяет мне вернуть NULL, если нет записи у которого есть этот идентификатор.

Было бы лучше, чтобы getContact() также возвращал ContactRecordSet просто для того, чтобы интерфейс оставался согласованным?

Часть меня раздражает идея возврата такой структуры данных для одного объекта, но, с другой стороны, это более последовательно, и семантика для проверки того, было ли найдено значение для этого идентификатора, кажется, больше соответствует общей абстракции дизайн (проверьте длину возвращаемого набора записей и проверьте наличие NULL auto_ptr).

Что вы все думаете?

(Примечание. Я знаю, что я, вероятно, слишком много работаю над простым приложением адресной книги, но я хочу, чтобы было легко менять местами разные серверные части (плоский файл, SQL и т. д.) при условии, что они реализуют общий интерфейс. Цель состоит в том, чтобы практиковать хороший модульный дизайн и разделение задач.)

ОБНОВЛЕНИЕ

Я полагаю, что мог бы посмотреть с противоположной точки зрения и заставить несколько методов записи возвращать auto_ptrs в объекты ContactRecordSet. Таким образом, а) это соответствует тому, что вы всегда получаете указатель на объект, и б) у вас нет накладных расходов на возврат std::vector, если набор записей пуст, просто верните указатель NULL.


person Community    schedule 12.02.2011    source источник
comment
Это может быть за пределами вашей компетенции, но как насчет того, чтобы getContact() возвращал boost::Optional‹Contact›?   -  person Managu    schedule 12.02.2011


Ответы (2)


Я всегда следую принципу проектирования возвращать наименее сложную вещь, которая определяет ваш объект. Векторы предназначены для хранения списков вещей, а не отдельных элементов, и хотя это может сделать семантику симметричной, она, несомненно, будет неинтуитивна для другой. разработчик.

person Andrew White    schedule 12.02.2011

Что последовательного в возврате типа множественного числа для функции, не являющейся множественным числом?

Я думаю, вам нужно работать с другим определением «согласованности».

person Edward Strange    schedule 12.02.2011