Должен ли я использовать частные классы в частных проектах?

Мне предстоит написать достаточно большую программу для исследовательского проекта, который, вероятно, будет использоваться только мной или, возможно, также небольшим количеством людей, которые могут взять на себя его в будущем. Дело в том, что это не коммерческое приложение, и его не будет в открытом доступе. И мой вопрос - в таком случае действительно ли есть какие-либо веские аргументы в пользу определения всех моих классов частными, а не публичными? Весь код предназначен для планировщика последовательности заданий. Итак, например, у меня есть базовый класс работы, который выглядит так:

class Job {

private:    // should it be?
    int Jobid;

    int stack_row ; // horizontal positon in a stack
    int row_height ;    // position in a column of containers

    float ArrivalTime;
    float FinishTime;
    float GantryTime;

    float WaitingTime; // Job Start - Job Arrival
    float ReachableTime; // later time of Vehicle or YC arrival to job location

    float DueDate;
    float Tardiness; // max{0, Ci-di} Ci, Completion time = Finish time; di, DueDate
    float SlackTime;
    int type; // 1, Loading; 2, Unloading

} ;

Затем есть класс для последовательности заданий, данных моделирования, задействованных машин и ряда других вещей. Дело в том, что я получаю много классов и еще больше компонентов для них. Все они будут использоваться либо только мной, либо небольшим количеством других людей. Я мог бы определить все классы private с функциями set_whatever(), get_whatever() для всех private компонентов, которые необходимо установить или прочитать, но есть ли в этом смысл? А - нужно время. B - это не очень разборчивый код, когда я пишу

job_schedule.job_list[i].set_finish_time( job_schedule.job_list[i].get_ArrivaTime() +   job_schedule.job_list[i].get_ProcessingTime() ) ;

вместо

job_schedule.job_list[i] = job_schedule.job_list[i].Finish_Time + job_schedule.job_list[i].Processing_Time ;

Итак, мой вопрос: есть ли действительно веская причина, по которой я бы в этом случае придерживался частных занятий? Или, может быть, есть более элегантный способ сделать

job_schedule.job_list[i].set_finish_time( job_schedule.job_list[i].get_ArrivaTime() + job_schedule.job_list[i].get_ProcessingTime() ) ;

оставаясь приватным?


person Puchatek    schedule 13.09.2011    source источник
comment
Итак, я понимаю, что это разумная идея придерживаться определения всех сеттеров и геттеров, потому что в долгосрочной перспективе они более гибкие и с меньшей вероятностью вызовут у вас ошибки. Если у кого-то есть что добавить, пожалуйста.   -  person Puchatek    schedule 13.09.2011
comment
Геттеры и сеттеры улучшают обслуживание (несколько), но на самом деле подходят только для Bundle of Data (т.е. классов, которые действуют как простые контейнеры нескольких связанных свойств без взаимодействия между ними). Как только у вас появляется корреляция между свойствами, они становятся упадком.   -  person Matthieu M.    schedule 13.09.2011
comment
В том-то и дело, что у меня есть связанные свойства, которые действительно коррелируют, то есть время окончания задания является функцией времени начала и времени обработки. Вот почему я бы предпочел найти лучшее решение, чем длинная строка, которая представляет собой просто функцию set() с двумя функциями get() в аргументах для вычисления финиш = начало + обработка.   -  person Puchatek    schedule 13.09.2011
comment
В этом случае у вас есть два решения. Вы можете либо сохранить свой один класс, либо предоставить геттеры для всех свойств, но только сеттеры, которые объединяют свойства (т.е. set(Time start, Duration process)). Другое решение состоит в том, чтобы разделить класс на несколько значимых классов: class JobSchedule { public: Time getStart() const; Duration getProcessing() const; void set(Time start, Duration processing); /**/ };, а затем составить свой Job класс с этими значимыми блоками. Блоки — это настоящие классы (с инвариантными и сильными корреляциями между свойствами), а Job — это просто набор.   -  person Matthieu M.    schedule 13.09.2011


Ответы (4)


private это больше, чем просто управление зависимостями.

Сокрытие информации — это хорошо, так как упрощает обслуживание, но какой смысл иметь класс, если вы просто обрабатываете его как кортеж данных?

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

Помните, что исходный код должен быть читаем в первую очередь.

person Matthieu M.    schedule 13.09.2011
comment
Действительно, я использую здесь классы только для группировки связанных данных. И я думаю, что определение set и get для всех этих компонентов уродливо. Но помимо того, что я просто рассматриваю все эти классы как общедоступные, у меня нет хорошего представления о том, как решить проблему в противном случае (но я также пытаюсь получить хороший ответ о том, почему или почему бы не держать их частными/общедоступными в моем случае ). И почему создание класса для связывания логически связанных компонентов (т. е. характеристик работы) является преступлением? - person Puchatek; 13.09.2011
comment
Да, геттеры/сеттеры - пустая трата времени в 99% случаев. - person mihai; 13.09.2011
comment
@Puchatek: это не преступление, в этом случае у вас фактически есть пакет данных (подобный кортежу), и вы можете использовать struct или сеттеры / геттеры в зависимости от вашей привычки. Просто в типичном ООП это обычно не считается class, даже если язык более или менее заставляет вас втиснуть его в один. - person Matthieu M.; 13.09.2011

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

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

person cyco130    schedule 13.09.2011
comment
Его немного сложнее набирать, но типичный фрагмент кода набирается только один раз и читается много раз. Я не понимаю. Как геттеры и сеттеры улучшают читабельность? - person R. Martinho Fernandes; 13.09.2011
comment
Если вы просто используете свой класс просто как кортеж данных, как предлагает Матье, и вы уверены и уверены, что это никогда не изменится, тогда вы правы. В этом случае я предпочитаю объявлять его как структуру, а не класс, в качестве напоминания всем, кто может читать исходный код, включая меня. - person cyco130; 13.09.2011
comment
@ cyco130 - они немного зависят друг от друга, как я только что описал в комментарии к вопросу. Вы скажете, что это что-то меняет? - person Puchatek; 13.09.2011
comment
Если это просто связанные данные и ничего больше, я бы посоветовал использовать публичных членов. Но вам придется что-то сделать с этими данными, не так ли? В этот момент вам понадобятся методы, и это будет полноценный класс. В любой момент, если вам нужно что-то изменить при изменении данных, вы будете сожалеть о том, что не реализовали хотя бы сеттеры. Но, как я уже сказал, если вы на 100% уверены, что вам нужны только некоторые связанные данные, вы, конечно, можете использовать структуру или класс с открытыми членами. В этом нет ничего плохого как такового. - person cyco130; 13.09.2011

В C++ нет таких вещей, как закрытые или открытые классы. У вас есть частные, защищенные или общедоступные члены или классы.

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

person Ed Heal    schedule 13.09.2011

Создайте интерфейс для классов, но сохраняйте конфиденциальность данных.

Почему не job_schedule.set_finish_time(i, now()); или подобное?

person graham.reeds    schedule 13.09.2011