2014-01-06 3 views
0

Каков наилучший дизайн для загрузки объекта из файла? Есть много возможностей, некоторые из которых показаны ниже.Загрузить объект из файла дизайна

class object 
{ 
public: 
    object(const std::string& filename); 
}; 

class object 
{ 
public: 
    object(); 
    void load_from_file(const std::string& filename); 
}; 

class object 
{ 
public: 
    static object load_from_file(const std::string& filename); 

    object(object&& an_object); 
}; 

class object 
{ 
public: 
    std::unique_ptr<object> load_from_file(const std::string& filename); 
}; 

class object_loader 
{ 
public: 
    std::unique_ptr<object> load_object_from_file(const std::string& filename); 
}; 

и список продолжается ...

Edit:

дизайн я пошел с этим был:

class object 
{ 
public: 
    object(); 
}; 

class object_loader 
{ 
public: 
    void load_from_stream(object& an_object, std::istream& input_stream); 
}; 
+3

Честно говоря, вы не должны передавать имя файла вообще. Вы должны передать ссылку 'istream'. Класс не должен знать * где * байты исходят; ему просто нужен способ прочитать байты и понять их. – cHao

+0

Хорошая идея. Тем не менее, какой дизайн является лучшим (просто представьте, что const std :: string & filename заменяется на std :: istream & input_stream)? – Cole

+0

@cHao: Мое мнение по этому вопросу колеблется дико с течением времени. Я не согласен с вами в принципе, но иногда приятно, что вся эта файловая глупость абстрагируется от сайта вызова, а в некоторых приложениях это имеет смысл. –

ответ

2

Я предпочел бы 'класс object_loader', который отделяет IO из контейнера, что позволяет в будущем реализовать различные загрузчики (из txt, двоичного, xml ... файла) без изменения исходного контейнера данных. Лучшее тестирование возможно. Также возможно удалить IO из приложения, если IO не разрешено (например, встроенные устройства и т. Д.).

+0

Я бы поднял ответ, но у меня пока нет достаточной репутации, поэтому спасибо! – Cole

+0

Не волнуйся, я могу его возвысить: D –

2

Каков наилучший дизайн для загрузки объекта из файла?

Лучший дизайн, как правило, вдоль этих линий: код

class object { public: object(); /* ... */ }; // object is default constructible 

std::istream& operator >> (std::istream& in, object& o); 

клиента:

// from file: 
std::ifstream fin(path); 
object o; 
fin >> o; 
// from serialized string: 
std::string contents = "....."; 
std::istrigstream ssin(contents); 
ssin >> o; 

Edit:

транзакционной реализация:

std::istream& operator >> (std::istream& in, object& o) 
{ 
    int i; std::string word; // example data required by object instance 
    if (in >> i >> word) 
    { // read was successful for all data 
     o.set_index(i); 
     o.set_word(word); 
    } 
    return in; 
} 

// client code: 
if(ssin >> o) 
{ // read was successful 
    // use o here 
} else { 
    // o is still as default-constructed 
} 

Этот подход будет работать так же, если поток генерирует исключения при ошибках.

+0

Ничего, я об этом не думал. Что делать, если это не имеет смысла для того, чтобы объект был сконфигурирован по умолчанию? Может ли объект (std :: istream & input_stream) быть лучшим выбором? – Cole

+0

хороший шаблон, но вы не сможете загрузить объект из разных типов файлов (если в будущем требуется поддержка для загрузки из txt, xml, ...) – dousin

+0

@Cole, это имеет смысл, если вы можете гарантировать что объект в потоке корректно сериализуется (иначе вы заканчиваете 'o' в недопустимом состоянии). – utnapistim

Смежные вопросы